Commit 939b66f4 authored by Vladimir Tsanev's avatar Vladimir Tsanev Committed by Andy Wilkinson

Use fast exceptions in findResource(s)

Some libraries like aspectj are using findResource to see the raw
bytecode of a class. It will even call findResource for every method of
every class of beans that are post processed. This can be significant
performance hit on startup when LaunchedURLClassLoader and there are a
lot of nested jars.

See gh-3640
Fixes gh-4557
parent 0214fe4b
...@@ -76,7 +76,13 @@ public class LaunchedURLClassLoader extends URLClassLoader { ...@@ -76,7 +76,13 @@ public class LaunchedURLClassLoader extends URLClassLoader {
if (name.equals("") && hasURLs()) { if (name.equals("") && hasURLs()) {
return getURLs()[0]; return getURLs()[0];
} }
return super.findResource(name); Handler.setUseFastConnectionExceptions(true);
try {
return super.findResource(name);
}
finally {
Handler.setUseFastConnectionExceptions(false);
}
} }
catch (IllegalArgumentException ex) { catch (IllegalArgumentException ex) {
return null; return null;
...@@ -88,7 +94,13 @@ public class LaunchedURLClassLoader extends URLClassLoader { ...@@ -88,7 +94,13 @@ public class LaunchedURLClassLoader extends URLClassLoader {
if (name.equals("") && hasURLs()) { if (name.equals("") && hasURLs()) {
return Collections.enumeration(Arrays.asList(getURLs())); return Collections.enumeration(Arrays.asList(getURLs()));
} }
return super.findResources(name); Handler.setUseFastConnectionExceptions(true);
try {
return super.findResources(name);
}
finally {
Handler.setUseFastConnectionExceptions(false);
}
} }
private boolean hasURLs() { private boolean hasURLs() {
...@@ -100,33 +112,8 @@ public class LaunchedURLClassLoader extends URLClassLoader { ...@@ -100,33 +112,8 @@ public class LaunchedURLClassLoader extends URLClassLoader {
if (this.rootClassLoader == null) { if (this.rootClassLoader == null) {
return findResources(name); return findResources(name);
} }
return new ResourceEnumeration(this.rootClassLoader.getResources(name),
final Enumeration<URL> rootResources = this.rootClassLoader.getResources(name); findResources(name));
final Enumeration<URL> localResources = findResources(name);
return new Enumeration<URL>() {
@Override
public boolean hasMoreElements() {
try {
Handler.setUseFastConnectionExceptions(true);
return rootResources.hasMoreElements()
|| localResources.hasMoreElements();
}
finally {
Handler.setUseFastConnectionExceptions(false);
}
}
@Override
public URL nextElement() {
if (rootResources.hasMoreElements()) {
return rootResources.nextElement();
}
return localResources.nextElement();
}
};
} }
/** /**
...@@ -162,6 +149,7 @@ public class LaunchedURLClassLoader extends URLClassLoader { ...@@ -162,6 +149,7 @@ public class LaunchedURLClassLoader extends URLClassLoader {
} }
} }
catch (Exception ex) { catch (Exception ex) {
} }
// 2) Try to find locally // 2) Try to find locally
...@@ -171,6 +159,7 @@ public class LaunchedURLClassLoader extends URLClassLoader { ...@@ -171,6 +159,7 @@ public class LaunchedURLClassLoader extends URLClassLoader {
return cls; return cls;
} }
catch (Exception ex) { catch (Exception ex) {
} }
// 3) Use standard loading // 3) Use standard loading
...@@ -265,4 +254,41 @@ public class LaunchedURLClassLoader extends URLClassLoader { ...@@ -265,4 +254,41 @@ public class LaunchedURLClassLoader extends URLClassLoader {
} }
} /**
* {@link Enumeration} implementation used for {@code getResources()}.
*/
private static class ResourceEnumeration implements Enumeration<URL> {
private final Enumeration<URL> rootResources;
private final Enumeration<URL> localResources;
ResourceEnumeration(Enumeration<URL> rootResources,
Enumeration<URL> localResources) {
this.rootResources = rootResources;
this.localResources = localResources;
}
@Override
public boolean hasMoreElements() {
try {
Handler.setUseFastConnectionExceptions(true);
return this.rootResources.hasMoreElements()
|| this.localResources.hasMoreElements();
}
finally {
Handler.setUseFastConnectionExceptions(false);
}
}
@Override
public URL nextElement() {
if (this.rootResources.hasMoreElements()) {
return this.rootResources.nextElement();
}
return this.localResources.nextElement();
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment