[JENKINS-23784] - Register DependencyClassLoader in the default plugin strategy as parallel-capable (#5699)

This commit is contained in:
Basil Crow authored and GitHub committed 2021-09-05 19:08:17 +01:00
1 parent f2926a9b81
commit 725dd933d6
1 file changed
+22 -9
@@ -84,7 +84,7 @@ public class ClassicPluginStrategy implements PluginStrategy {
*/
private static final FilenameFilter JAR_FILTER = (dir, name) -> name.endsWith(".jar");
private PluginManager pluginManager;
private final PluginManager pluginManager;
/**
* All the plugins eventually delegate this classloader to load core, servlet APIs, and SE runtime.
@@ -244,7 +244,7 @@ public class ClassicPluginStrategy implements PluginStrategy {
coreClassLoader.add(pkg);
}
ClassLoader dependencyLoader = new DependencyClassLoader(coreClassLoader, archive, Util.join(dependencies,optionalDependencies));
ClassLoader dependencyLoader = new DependencyClassLoader(coreClassLoader, archive, Util.join(dependencies,optionalDependencies), pluginManager);
dependencyLoader = getBaseClassLoader(atts, dependencyLoader);
return new PluginWrapper(pluginManager, archive, manifest, baseResourceURL,
@@ -561,7 +561,7 @@ public class ClassicPluginStrategy implements PluginStrategy {
/**
* Used to load classes from dependency plugins.
*/
final class DependencyClassLoader extends ClassLoader {
static final class DependencyClassLoader extends ClassLoader {
/**
* This classloader is created for this plugin. Useful during debugging.
*/
@@ -569,15 +569,22 @@ public class ClassicPluginStrategy implements PluginStrategy {
private List<Dependency> dependencies;
private final PluginManager pluginManager;
/**
* Topologically sorted list of transient dependencies.
* Topologically sorted list of transient dependencies. Lazily initialized via double-checked locking.
*/
private volatile List<PluginWrapper> transientDependencies;
DependencyClassLoader(ClassLoader parent, File archive, List<Dependency> dependencies) {
static {
registerAsParallelCapable();
}
DependencyClassLoader(ClassLoader parent, File archive, List<Dependency> dependencies, PluginManager pluginManager) {
super(parent);
this._for = archive;
this.dependencies = dependencies;
this.dependencies = Collections.unmodifiableList(new ArrayList<>(dependencies));
this.pluginManager = pluginManager;
}
private void updateTransientDependencies() {
@@ -586,7 +593,11 @@ public class ClassicPluginStrategy implements PluginStrategy {
}
private List<PluginWrapper> getTransitiveDependencies() {
if (transientDependencies==null) {
List<PluginWrapper> localTransientDependencies = transientDependencies;
if (localTransientDependencies == null) {
synchronized (this) {
localTransientDependencies = transientDependencies;
if (localTransientDependencies == null) {
CyclicGraphDetector<PluginWrapper> cgd = new CyclicGraphDetector<PluginWrapper>() {
@Override
protected List<PluginWrapper> getEdges(PluginWrapper pw) {
@@ -610,9 +621,11 @@ public class ClassicPluginStrategy implements PluginStrategy {
throw new AssertionError(e); // such error should have been reported earlier
}
transientDependencies = cgd.getSorted();
transientDependencies = localTransientDependencies = cgd.getSorted();
}
}
return transientDependencies;
}
return localTransientDependencies;
}
@Override