import org.sonar.api.ServerComponent;
import org.sonar.api.utils.log.Loggers;
import org.sonar.classloader.ClassloaderBuilder;
-import org.sonar.classloader.ClassloaderBuilder.LoadingOrder;
import java.io.Closeable;
import java.io.File;
import org.sonar.classloader.Mask;
import static java.util.Arrays.asList;
+import static org.sonar.classloader.ClassloaderBuilder.LoadingOrder.PARENT_FIRST;
import static org.sonar.classloader.ClassloaderBuilder.LoadingOrder.SELF_FIRST;
/**
private static final String[] DEFAULT_SHARED_RESOURCES = {"org/sonar/plugins", "com/sonar/plugins", "com/sonarsource/plugins"};
+ // underscores are used to not conflict with plugin keys (if someday a plugin key is "api")
+ private static final String API_CLASSLOADER_KEY = "_api_";
+
private final PluginExploder exploder;
public PluginLoader(PluginExploder exploder) {
*/
private void buildClassloaders(Collection<ClassloaderDef> defs) {
ClassloaderBuilder builder = new ClassloaderBuilder();
+ builder.newClassloader(API_CLASSLOADER_KEY, baseClassloader());
for (ClassloaderDef def : defs) {
builder
- .newClassloader(def.getBasePluginKey(), getClass().getClassLoader())
+ .newClassloader(def.getBasePluginKey())
+ .setParent(def.getBasePluginKey(), API_CLASSLOADER_KEY, new Mask())
// resources to be exported to other plugin classloaders (siblings)
.setExportMask(def.getBasePluginKey(), def.getMask())
- .setLoadingOrder(def.getBasePluginKey(), def.isSelfFirstStrategy() ? SELF_FIRST : LoadingOrder.PARENT_FIRST);
+ .setLoadingOrder(def.getBasePluginKey(), def.isSelfFirstStrategy() ? SELF_FIRST : PARENT_FIRST);
for (File file : def.getFiles()) {
builder.addURL(def.getBasePluginKey(), fileToUrl(file));
}
public void unload(Collection<Plugin> plugins) {
for (Plugin plugin : plugins) {
ClassLoader classLoader = plugin.getClass().getClassLoader();
- if (classLoader instanceof Closeable && classLoader != getClass().getClassLoader()) {
+ if (classLoader instanceof Closeable && classLoader != baseClassloader()) {
try {
((Closeable) classLoader).close();
} catch (Exception e) {
}
}
+ private ClassLoader baseClassloader() {
+ return getClass().getClassLoader();
+ }
+
/**
* Get the root key of a tree of plugins. For example if plugin C depends on B, which depends on A, then
* B and C must be attached to the classloader of A. The method returns A in the three cases.