aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-core
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-08-26 15:53:29 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-08-29 15:58:42 +0200
commit9ef78be7a7eab2b693566ebb20fe48fbe1877ed3 (patch)
treea57130dfb06aaf7d82a638fab3d9536d9b4193a2 /sonar-core
parentf9f74e5db5f8ee9b316f8ba61ba156b091a19fd6 (diff)
downloadsonarqube-9ef78be7a7eab2b693566ebb20fe48fbe1877ed3.tar.gz
sonarqube-9ef78be7a7eab2b693566ebb20fe48fbe1877ed3.zip
fix privileged plugin ClassLoader configuration
rename PluginClassloaderDef#serverExtension to PluginClassloaderDef#privileged to avoid confusion with the ServerExtension class and annotations rename PluginClassloaderDef to PluginClassLoaderDef (capital L)
Diffstat (limited to 'sonar-core')
-rw-r--r--sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoaderDef.java (renamed from sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderDef.java)18
-rw-r--r--sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java28
-rw-r--r--sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java28
-rw-r--r--sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java20
-rw-r--r--sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java20
5 files changed, 60 insertions, 54 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderDef.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoaderDef.java
index a78403fa49e..0c6d635b792 100644
--- a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderDef.java
+++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoaderDef.java
@@ -31,9 +31,9 @@ import javax.annotation.Nullable;
import org.sonar.classloader.Mask;
/**
- * Temporary information about the classloader to be created for a plugin (or a group of plugins).
+ * Temporary information about the classLoader to be created for a plugin (or a group of plugins).
*/
-class PluginClassloaderDef {
+class PluginClassLoaderDef {
private final String basePluginKey;
private final Map<String, String> mainClassesByPluginKey = new HashMap<>();
@@ -46,9 +46,9 @@ class PluginClassloaderDef {
*/
private boolean compatibilityMode = false;
- private boolean serverExtension = false;
+ private boolean privileged = false;
- PluginClassloaderDef(String basePluginKey) {
+ PluginClassLoaderDef(String basePluginKey) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(basePluginKey));
this.basePluginKey = basePluginKey;
}
@@ -95,12 +95,12 @@ class PluginClassloaderDef {
this.compatibilityMode = b;
}
- boolean isServerExtension() {
- return serverExtension;
+ boolean isPrivileged() {
+ return privileged;
}
- void setServerExtension(boolean serverExtension) {
- this.serverExtension = serverExtension;
+ void setPrivileged(boolean privileged) {
+ this.privileged = privileged;
}
@Override
@@ -111,7 +111,7 @@ class PluginClassloaderDef {
if (o == null || getClass() != o.getClass()) {
return false;
}
- PluginClassloaderDef that = (PluginClassloaderDef) o;
+ PluginClassLoaderDef that = (PluginClassLoaderDef) o;
return basePluginKey.equals(that.basePluginKey);
}
diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java
index 3750e9e925a..66b11875dfe 100644
--- a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java
+++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java
@@ -62,14 +62,20 @@ public class PluginClassloaderFactory {
/**
* Creates as many classloaders as requested by the input parameter.
*/
- public Map<PluginClassloaderDef, ClassLoader> create(Collection<PluginClassloaderDef> defs) {
+ public Map<PluginClassLoaderDef, ClassLoader> create(Collection<PluginClassLoaderDef> defs) {
+ ClassLoader baseClassLoader = baseClassLoader();
+
ClassloaderBuilder builder = new ClassloaderBuilder();
- builder.newClassloader(API_CLASSLOADER_KEY, baseClassloader());
+ builder.newClassloader(API_CLASSLOADER_KEY, baseClassLoader);
+ builder.setMask(API_CLASSLOADER_KEY, apiMask());
- for (PluginClassloaderDef def : defs) {
- builder.setMask(API_CLASSLOADER_KEY, def.isServerExtension() ? new Mask() : apiMask());
+ for (PluginClassLoaderDef def : defs) {
builder.newClassloader(def.getBasePluginKey());
- builder.setParent(def.getBasePluginKey(), API_CLASSLOADER_KEY, new Mask());
+ if (def.isPrivileged()) {
+ builder.setParent(def.getBasePluginKey(), baseClassLoader, new Mask());
+ } else {
+ builder.setParent(def.getBasePluginKey(), API_CLASSLOADER_KEY, new Mask());
+ }
builder.setLoadingOrder(def.getBasePluginKey(), def.isSelfFirstStrategy() ? SELF_FIRST : PARENT_FIRST);
for (File jar : def.getFiles()) {
builder.addURL(def.getBasePluginKey(), fileToUrl(jar));
@@ -86,10 +92,10 @@ public class PluginClassloaderFactory {
/**
* A plugin can export some resources to other plugins
*/
- private void exportResources(PluginClassloaderDef def, ClassloaderBuilder builder, Collection<PluginClassloaderDef> allPlugins) {
+ private void exportResources(PluginClassLoaderDef def, ClassloaderBuilder builder, Collection<PluginClassLoaderDef> allPlugins) {
// export the resources to all other plugins
builder.setExportMask(def.getBasePluginKey(), def.getExportMask());
- for (PluginClassloaderDef other : allPlugins) {
+ for (PluginClassLoaderDef other : allPlugins) {
if (!other.getBasePluginKey().equals(def.getBasePluginKey())) {
builder.addSibling(def.getBasePluginKey(), other.getBasePluginKey(), new Mask());
}
@@ -99,10 +105,10 @@ public class PluginClassloaderFactory {
/**
* Builds classloaders and verifies that all of them are correctly defined
*/
- private Map<PluginClassloaderDef, ClassLoader> build(Collection<PluginClassloaderDef> defs, ClassloaderBuilder builder) {
- Map<PluginClassloaderDef, ClassLoader> result = new HashMap<>();
+ private Map<PluginClassLoaderDef, ClassLoader> build(Collection<PluginClassLoaderDef> defs, ClassloaderBuilder builder) {
+ Map<PluginClassLoaderDef, ClassLoader> result = new HashMap<>();
Map<String, ClassLoader> classloadersByBasePluginKey = builder.build();
- for (PluginClassloaderDef def : defs) {
+ for (PluginClassLoaderDef def : defs) {
ClassLoader classloader = classloadersByBasePluginKey.get(def.getBasePluginKey());
if (classloader == null) {
throw new IllegalStateException(String.format("Fail to create classloader for plugin [%s]", def.getBasePluginKey()));
@@ -112,7 +118,7 @@ public class PluginClassloaderFactory {
return result;
}
- ClassLoader baseClassloader() {
+ ClassLoader baseClassLoader() {
return getClass().getClassLoader();
}
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 3428358e6fd..ea5850f709e 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
@@ -55,7 +55,7 @@ public class PluginLoader {
* Defines the base keys (defined by {@link #basePluginKey(PluginInfo, Map)}) of the plugins which are allowed to
* run a full server extensions.
*/
- private static final Set<String> SYSTEM_EXTENSION_PLUGINS_BASE_KEYS = ImmutableSet.of("views");
+ private static final Set<String> PRIVILEGED_PLUGINS_BASE_KEYS = ImmutableSet.of("views");
public static final Version COMPATIBILITY_MODE_MAX_VERSION = Version.create("5.2");
@@ -68,8 +68,8 @@ public class PluginLoader {
}
public Map<String, Plugin> load(Map<String, PluginInfo> infoByKeys) {
- Collection<PluginClassloaderDef> defs = defineClassloaders(infoByKeys);
- Map<PluginClassloaderDef, ClassLoader> classloaders = classloaderFactory.create(defs);
+ Collection<PluginClassLoaderDef> defs = defineClassloaders(infoByKeys);
+ Map<PluginClassLoaderDef, ClassLoader> classloaders = classloaderFactory.create(defs);
return instantiatePluginClasses(classloaders);
}
@@ -78,14 +78,14 @@ public class PluginLoader {
* different than number of plugins.
*/
@VisibleForTesting
- Collection<PluginClassloaderDef> defineClassloaders(Map<String, PluginInfo> infoByKeys) {
- Map<String, PluginClassloaderDef> classloadersByBasePlugin = new HashMap<>();
+ Collection<PluginClassLoaderDef> defineClassloaders(Map<String, PluginInfo> infoByKeys) {
+ Map<String, PluginClassLoaderDef> classloadersByBasePlugin = new HashMap<>();
for (PluginInfo info : infoByKeys.values()) {
String baseKey = basePluginKey(info, infoByKeys);
- PluginClassloaderDef def = classloadersByBasePlugin.get(baseKey);
+ PluginClassLoaderDef def = classloadersByBasePlugin.get(baseKey);
if (def == null) {
- def = new PluginClassloaderDef(baseKey);
+ def = new PluginClassLoaderDef(baseKey);
classloadersByBasePlugin.put(baseKey, def);
}
ExplodedPlugin explodedPlugin = jarExploder.explode(info);
@@ -104,7 +104,7 @@ public class PluginLoader {
Version minSqVersion = info.getMinimalSqVersion();
boolean compatibilityMode = minSqVersion != null && minSqVersion.compareToIgnoreQualifier(COMPATIBILITY_MODE_MAX_VERSION) < 0;
def.setCompatibilityMode(compatibilityMode);
- def.setServerExtension(isServerExtension(baseKey));
+ def.setPrivileged(isPrivileged(baseKey));
if (compatibilityMode) {
Loggers.get(getClass()).debug("API compatibility mode is enabled on plugin {} [{}] " +
"(built with API lower than {})",
@@ -115,8 +115,8 @@ public class PluginLoader {
return classloadersByBasePlugin.values();
}
- private static boolean isServerExtension(String basePluginKey) {
- return SYSTEM_EXTENSION_PLUGINS_BASE_KEYS.contains(basePluginKey);
+ private static boolean isPrivileged(String basePluginKey) {
+ return PRIVILEGED_PLUGINS_BASE_KEYS.contains(basePluginKey);
}
/**
@@ -126,11 +126,11 @@ public class PluginLoader {
* @throws IllegalStateException if at least one plugin can't be correctly loaded
*/
@VisibleForTesting
- Map<String, Plugin> instantiatePluginClasses(Map<PluginClassloaderDef, ClassLoader> classloaders) {
+ Map<String, Plugin> instantiatePluginClasses(Map<PluginClassLoaderDef, ClassLoader> classloaders) {
// instantiate plugins
Map<String, Plugin> instancesByPluginKey = new HashMap<>();
- for (Map.Entry<PluginClassloaderDef, ClassLoader> entry : classloaders.entrySet()) {
- PluginClassloaderDef def = entry.getKey();
+ for (Map.Entry<PluginClassLoaderDef, ClassLoader> entry : classloaders.entrySet()) {
+ PluginClassLoaderDef def = entry.getKey();
ClassLoader classLoader = entry.getValue();
// the same classloader can be used by multiple plugins
@@ -154,7 +154,7 @@ public class PluginLoader {
public void unload(Collection<Plugin> plugins) {
for (Plugin plugin : plugins) {
ClassLoader classLoader = plugin.getClass().getClassLoader();
- if (classLoader instanceof Closeable && classLoader != classloaderFactory.baseClassloader()) {
+ if (classLoader instanceof Closeable && classLoader != classloaderFactory.baseClassLoader()) {
try {
((Closeable) classLoader).close();
} catch (Exception e) {
diff --git a/sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java
index 62d41a14a3f..5a4a232167d 100644
--- a/sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java
@@ -44,8 +44,8 @@ public class PluginClassloaderFactoryTest {
@Test
public void create_isolated_classloader() {
- PluginClassloaderDef def = basePluginDef();
- Map<PluginClassloaderDef, ClassLoader> map = factory.create(asList(def));
+ PluginClassLoaderDef def = basePluginDef();
+ Map<PluginClassLoaderDef, ClassLoader> map = factory.create(asList(def));
assertThat(map).containsOnlyKeys(def);
ClassLoader classLoader = map.get(def);
@@ -62,7 +62,7 @@ public class PluginClassloaderFactoryTest {
@Test
public void create_classloader_compatible_with_with_old_api_dependencies() {
- PluginClassloaderDef def = basePluginDef();
+ PluginClassLoaderDef def = basePluginDef();
def.setCompatibilityMode(true);
ClassLoader classLoader = factory.create(asList(def)).get(def);
@@ -76,9 +76,9 @@ public class PluginClassloaderFactoryTest {
@Test
public void classloader_exports_resources_to_other_classloaders() {
- PluginClassloaderDef baseDef = basePluginDef();
- PluginClassloaderDef dependentDef = dependentPluginDef();
- Map<PluginClassloaderDef, ClassLoader> map = factory.create(asList(baseDef, dependentDef));
+ PluginClassLoaderDef baseDef = basePluginDef();
+ PluginClassLoaderDef dependentDef = dependentPluginDef();
+ Map<PluginClassLoaderDef, ClassLoader> map = factory.create(asList(baseDef, dependentDef));
ClassLoader baseClassloader = map.get(baseDef);
ClassLoader dependentClassloader = map.get(dependentDef);
@@ -92,16 +92,16 @@ public class PluginClassloaderFactoryTest {
assertThat(canLoadClass(baseClassloader, BASE_PLUGIN_CLASSNAME)).isTrue();
}
- private static PluginClassloaderDef basePluginDef() {
- PluginClassloaderDef def = new PluginClassloaderDef(BASE_PLUGIN_KEY);
+ private static PluginClassLoaderDef basePluginDef() {
+ PluginClassLoaderDef def = new PluginClassLoaderDef(BASE_PLUGIN_KEY);
def.addMainClass(BASE_PLUGIN_KEY, BASE_PLUGIN_CLASSNAME);
def.getExportMask().addInclusion("org/sonar/plugins/base/api/");
def.addFiles(asList(fakePluginJar("base-plugin/target/base-plugin-0.1-SNAPSHOT.jar")));
return def;
}
- private static PluginClassloaderDef dependentPluginDef() {
- PluginClassloaderDef def = new PluginClassloaderDef(DEPENDENT_PLUGIN_KEY);
+ private static PluginClassLoaderDef dependentPluginDef() {
+ PluginClassLoaderDef def = new PluginClassLoaderDef(DEPENDENT_PLUGIN_KEY);
def.addMainClass(DEPENDENT_PLUGIN_KEY, DEPENDENT_PLUGIN_CLASSNAME);
def.getExportMask().addInclusion("org/sonar/plugins/dependent/api/");
def.addFiles(asList(fakePluginJar("dependent-plugin/target/dependent-plugin-0.1-SNAPSHOT.jar")));
diff --git a/sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java b/sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java
index 3e4a2634740..c79cccc04f0 100644
--- a/sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java
@@ -49,7 +49,7 @@ public class PluginLoaderTest {
@Test
public void instantiate_plugin_entry_point() {
- PluginClassloaderDef def = new PluginClassloaderDef("fake");
+ PluginClassLoaderDef def = new PluginClassLoaderDef("fake");
def.addMainClass("fake", FakePlugin.class.getName());
Map<String, Plugin> instances = loader.instantiatePluginClasses(ImmutableMap.of(def, getClass().getClassLoader()));
@@ -59,7 +59,7 @@ public class PluginLoaderTest {
@Test
public void plugin_entry_point_must_be_no_arg_public() {
- PluginClassloaderDef def = new PluginClassloaderDef("fake");
+ PluginClassLoaderDef def = new PluginClassLoaderDef("fake");
def.addMainClass("fake", IncorrectPlugin.class.getName());
try {
@@ -78,10 +78,10 @@ public class PluginLoaderTest {
.setMainClass("org.foo.FooPlugin")
.setMinimalSqVersion(Version.create("5.2"));
- Collection<PluginClassloaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", info));
+ Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", info));
assertThat(defs).hasSize(1);
- PluginClassloaderDef def = defs.iterator().next();
+ PluginClassLoaderDef def = defs.iterator().next();
assertThat(def.getBasePluginKey()).isEqualTo("foo");
assertThat(def.isSelfFirstStrategy()).isFalse();
assertThat(def.getFiles()).containsOnly(jarFile);
@@ -100,7 +100,7 @@ public class PluginLoaderTest {
.setMainClass("org.foo.FooPlugin")
.setMinimalSqVersion(Version.create("4.5.2"));
- Collection<PluginClassloaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", info));
+ Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", info));
assertThat(defs.iterator().next().isCompatibilityMode()).isTrue();
}
@@ -132,11 +132,11 @@ public class PluginLoaderTest {
.setBasePlugin("foo")
.setUseChildFirstClassLoader(true);
- Collection<PluginClassloaderDef> defs = loader.defineClassloaders(ImmutableMap.of(
+ Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of(
base.getKey(), base, extension1.getKey(), extension1, extension2.getKey(), extension2));
assertThat(defs).hasSize(1);
- PluginClassloaderDef def = defs.iterator().next();
+ PluginClassLoaderDef def = defs.iterator().next();
assertThat(def.getBasePluginKey()).isEqualTo("foo");
assertThat(def.isSelfFirstStrategy()).isFalse();
assertThat(def.getFiles()).containsOnly(baseJarFile, extensionJar1, extensionJar2);
@@ -151,9 +151,9 @@ public class PluginLoaderTest {
public void plugin_is_recognised_as_server_extension_if_key_is_views_and_extends_no_other_plugin_and_runs_in_compatibility_mode() throws IOException {
PluginInfo views = create52PluginInfo("views");
- Collection<PluginClassloaderDef> defs = loader.defineClassloaders(ImmutableMap.of("views", views));
+ Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("views", views));
- assertThat(defs.iterator().next().isServerExtension()).isTrue();
+ assertThat(defs.iterator().next().isPrivileged()).isTrue();
}
@Test
@@ -162,7 +162,7 @@ public class PluginLoaderTest {
PluginInfo views = create52PluginInfo("views")
.setBasePlugin("foo");
- Collection<PluginClassloaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", foo, "views", views));
+ Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", foo, "views", views));
assertThat(defs).extracting("compatibilityMode").containsOnly(false, false);
}