From: Simon Brandhof Date: Tue, 12 May 2015 11:40:32 +0000 (+0200) Subject: SONAR-6517 fix self-first classloaders in plugins X-Git-Tag: 5.2-RC1~1984 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=68565f9d89feec02c4332506e580adc429e2b248;p=sonarqube.git SONAR-6517 fix self-first classloaders in plugins --- diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java index 8722703d7f7..ecede3063a6 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java @@ -27,7 +27,6 @@ import org.sonar.api.Plugin; 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; @@ -39,6 +38,7 @@ import java.util.Map; 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; /** @@ -59,6 +59,9 @@ public class PluginLoader implements BatchComponent, ServerComponent { 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) { @@ -108,12 +111,14 @@ public class PluginLoader implements BatchComponent, ServerComponent { */ private void buildClassloaders(Collection 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)); } @@ -164,7 +169,7 @@ public class PluginLoader implements BatchComponent, ServerComponent { public void unload(Collection 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) { @@ -174,6 +179,10 @@ public class PluginLoader implements BatchComponent, ServerComponent { } } + 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.