mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-06 00:25:58 +00:00
fully implemented faster classloader lookup
This commit is contained in:
1 parent
cd78f636cd
commit
ee4e9c6149
3 files changed
+192
-57
No files matched your search
@@ -26,16 +26,25 @@ package hudson;
|
||||
import hudson.Plugin.DummyImpl;
|
||||
import hudson.PluginWrapper.Dependency;
|
||||
import hudson.model.Hudson;
|
||||
import hudson.util.CyclicGraphDetector;
|
||||
import hudson.util.CyclicGraphDetector.CycleDetectedException;
|
||||
import hudson.util.IOException2;
|
||||
import hudson.util.IOUtils;
|
||||
import hudson.util.MaskingClassLoader;
|
||||
import hudson.util.VersionNumber;
|
||||
import jenkins.ClassLoaderReflectionToolkit;
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.taskdefs.Expand;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
@@ -50,15 +59,8 @@ import java.util.jar.Manifest;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.taskdefs.Expand;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
|
||||
public class ClassicPluginStrategy implements PluginStrategy {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ClassicPluginStrategy.class.getName());
|
||||
private final ClassLoaderReflectionToolkit clt = new ClassLoaderReflectionToolkit();
|
||||
|
||||
/**
|
||||
* Filter for jar files.
|
||||
@@ -167,7 +169,8 @@ public class ClassicPluginStrategy implements PluginStrategy {
|
||||
for (DetachedPlugin detached : DETACHED_LIST)
|
||||
detached.fix(atts,optionalDependencies);
|
||||
|
||||
ClassLoader dependencyLoader = new DependencyClassLoader(getBaseClassLoader(atts), archive, Util.join(dependencies,optionalDependencies));
|
||||
ClassLoader dependencyLoader = new DependencyClassLoader(getClass().getClassLoader(), archive, Util.join(dependencies,optionalDependencies));
|
||||
dependencyLoader = getBaseClassLoader(atts, dependencyLoader);
|
||||
|
||||
return new PluginWrapper(pluginManager, archive, manifest, baseResourceURL,
|
||||
createClassLoader(paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies);
|
||||
@@ -249,8 +252,7 @@ public class ClassicPluginStrategy implements PluginStrategy {
|
||||
* <p>
|
||||
* This mechanism allows plugins to have their own versions for libraries that core bundles.
|
||||
*/
|
||||
private ClassLoader getBaseClassLoader(Attributes atts) {
|
||||
ClassLoader base = getClass().getClassLoader();
|
||||
private ClassLoader getBaseClassLoader(Attributes atts, ClassLoader base) {
|
||||
String masked = atts.getValue("Mask-Classes");
|
||||
if(masked!=null)
|
||||
base = new MaskingClassLoader(base, masked.trim().split("[ \t\r\n]+"));
|
||||
@@ -413,22 +415,78 @@ public class ClassicPluginStrategy implements PluginStrategy {
|
||||
|
||||
private List<Dependency> dependencies;
|
||||
|
||||
/**
|
||||
* Topologically sorted list of transient dependencies.
|
||||
*/
|
||||
private volatile List<PluginWrapper> transientDependencies;
|
||||
|
||||
public DependencyClassLoader(ClassLoader parent, File archive, List<Dependency> dependencies) {
|
||||
super(parent);
|
||||
this._for = archive;
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
private List<PluginWrapper> getTransitiveDependencies() {
|
||||
if (transientDependencies==null) {
|
||||
CyclicGraphDetector<PluginWrapper> cgd = new CyclicGraphDetector<PluginWrapper>() {
|
||||
@Override
|
||||
protected List<PluginWrapper> getEdges(PluginWrapper pw) {
|
||||
List<PluginWrapper> dep = new ArrayList<PluginWrapper>();
|
||||
for (Dependency d : pw.getDependencies()) {
|
||||
PluginWrapper p = pluginManager.getPlugin(d.shortName);
|
||||
if (p!=null)
|
||||
dep.add(p);
|
||||
}
|
||||
return dep;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
for (Dependency d : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(d.shortName);
|
||||
if (p!=null)
|
||||
cgd.run(Collections.singleton(p));
|
||||
}
|
||||
} catch (CycleDetectedException e) {
|
||||
throw new AssertionError(e); // such error should have been reported earlier
|
||||
}
|
||||
|
||||
transientDependencies = cgd.getSorted();
|
||||
}
|
||||
return transientDependencies;
|
||||
}
|
||||
|
||||
// public List<PluginWrapper> getDependencyPluginWrappers() {
|
||||
// List<PluginWrapper> r = new ArrayList<PluginWrapper>();
|
||||
// for (Dependency d : dependencies) {
|
||||
// PluginWrapper w = pluginManager.getPlugin(d.shortName);
|
||||
// if (w!=null) r.add(w);
|
||||
// }
|
||||
// return r;
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
for (Dependency dep : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(dep.shortName);
|
||||
if(p!=null)
|
||||
if (PluginManager.FAST_LOOKUP) {
|
||||
for (PluginWrapper pw : getTransitiveDependencies()) {
|
||||
try {
|
||||
return p.classLoader.loadClass(name);
|
||||
} catch (ClassNotFoundException _) {
|
||||
// try next
|
||||
Class c = clt.findLoadedClass(pw.classLoader,name);
|
||||
if (c!=null) return c;
|
||||
return clt.findClass(pw.classLoader,name);
|
||||
} catch (InvocationTargetException e) {
|
||||
//not found. try next
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Dependency dep : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(dep.shortName);
|
||||
if(p!=null)
|
||||
try {
|
||||
return p.classLoader.loadClass(name);
|
||||
} catch (ClassNotFoundException _) {
|
||||
// try next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ClassNotFoundException(name);
|
||||
@@ -437,12 +495,25 @@ public class ClassicPluginStrategy implements PluginStrategy {
|
||||
@Override
|
||||
protected Enumeration<URL> findResources(String name) throws IOException {
|
||||
HashSet<URL> result = new HashSet<URL>();
|
||||
for (Dependency dep : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(dep.shortName);
|
||||
if (p!=null) {
|
||||
Enumeration<URL> urls = p.classLoader.getResources(name);
|
||||
while (urls != null && urls.hasMoreElements())
|
||||
result.add(urls.nextElement());
|
||||
|
||||
if (PluginManager.FAST_LOOKUP) {
|
||||
try {
|
||||
for (PluginWrapper pw : getTransitiveDependencies()) {
|
||||
Enumeration<URL> urls = clt.findResources(pw.classLoader, name);
|
||||
while (urls != null && urls.hasMoreElements())
|
||||
result.add(urls.nextElement());
|
||||
}
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
} else {
|
||||
for (Dependency dep : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(dep.shortName);
|
||||
if (p!=null) {
|
||||
Enumeration<URL> urls = p.classLoader.getResources(name);
|
||||
while (urls != null && urls.hasMoreElements())
|
||||
result.add(urls.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,12 +522,23 @@ public class ClassicPluginStrategy implements PluginStrategy {
|
||||
|
||||
@Override
|
||||
protected URL findResource(String name) {
|
||||
for (Dependency dep : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(dep.shortName);
|
||||
if(p!=null) {
|
||||
URL url = p.classLoader.getResource(name);
|
||||
if (url!=null)
|
||||
return url;
|
||||
if (PluginManager.FAST_LOOKUP) {
|
||||
try {
|
||||
for (PluginWrapper pw : getTransitiveDependencies()) {
|
||||
URL url = clt.findResource(pw.classLoader,name);
|
||||
if (url!=null) return url;
|
||||
}
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
} else {
|
||||
for (Dependency dep : dependencies) {
|
||||
PluginWrapper p = pluginManager.getPlugin(dep.shortName);
|
||||
if(p!=null) {
|
||||
URL url = p.classLoader.getResource(name);
|
||||
if (url!=null)
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,4 +565,5 @@ public class ClassicPluginStrategy implements PluginStrategy {
|
||||
}
|
||||
|
||||
public static boolean useAntClassLoader = Boolean.getBoolean(ClassicPluginStrategy.class.getName()+".useAntClassLoader");
|
||||
private static final Logger LOGGER = Logger.getLogger(ClassicPluginStrategy.class.getName());
|
||||
}
|
||||
Reference in new issue
Block a user