Skip to content

Commit

Permalink
[FIXED JENKINS-24309] Caching class loads and misses from UberClassLo…
Browse files Browse the repository at this point in the history
…ader.
  • Loading branch information
jglick committed Aug 18, 2014
1 parent 6d298b0 commit cd33cdd
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
3 changes: 3 additions & 0 deletions changelog.html
Expand Up @@ -64,6 +64,9 @@
<li class=rfe>
Allow BuildStep to work with non-AbstractProject
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-23713">issue 23713</a>)
<li class=bug>
Improved class loading performance when using Groovy.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-24309">issue 24309</a>)
<li class=rfe>
Make the lifetime of queue items cache configurable.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-19691">issue 19691</a>)
Expand Down
34 changes: 32 additions & 2 deletions core/src/main/java/hudson/PluginManager.java
Expand Up @@ -435,6 +435,9 @@ public void dynamicLoad(File arc) throws IOException, InterruptedException, Rest

plugins.add(p);
activePlugins.add(p);
synchronized (((UberClassLoader) uberClassLoader).loaded) {
((UberClassLoader) uberClassLoader).loaded.clear();
}

try {
p.resolvePluginDependencies();
Expand Down Expand Up @@ -1015,6 +1018,8 @@ public final class UberClassLoader extends ClassLoader {
* Keyed by the generated class name.
*/
private ConcurrentMap<String, WeakReference<Class>> generatedClasses = new ConcurrentHashMap<String, WeakReference<Class>>();
/** Cache of loaded, or known to be unloadable, classes. */
private final Map<String,Class<?>> loaded = new HashMap<String,Class<?>>();

public UberClassLoader() {
super(PluginManager.class.getClassLoader());
Expand All @@ -1033,13 +1038,35 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
else generatedClasses.remove(name,wc);
}

if (name.startsWith("SimpleTemplateScript")) { // cf. groovy.text.SimpleTemplateEngine
throw new ClassNotFoundException("ignoring " + name);
}
synchronized (loaded) {
if (loaded.containsKey(name)) {
Class<?> c = loaded.get(name);
if (c != null) {
return c;
} else {
throw new ClassNotFoundException("cached miss for " + name);
}
}
}
if (FAST_LOOKUP) {
for (PluginWrapper p : activePlugins) {
try {
Class<?> c = ClassLoaderReflectionToolkit._findLoadedClass(p.classLoader, name);
if (c!=null) return c;
if (c != null) {
synchronized (loaded) {
loaded.put(name, c);
}
return c;
}
// calling findClass twice appears to cause LinkageError: duplicate class def
return ClassLoaderReflectionToolkit._findClass(p.classLoader, name);
c = ClassLoaderReflectionToolkit._findClass(p.classLoader, name);
synchronized (loaded) {
loaded.put(name, c);
}
return c;
} catch (ClassNotFoundException e) {
//not found. try next
}
Expand All @@ -1053,6 +1080,9 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
}
}
}
synchronized (loaded) {
loaded.put(name, null);
}
// not found in any of the classloader. delegate.
throw new ClassNotFoundException(name);
}
Expand Down

0 comments on commit cd33cdd

Please sign in to comment.