Prevent duplicate resource enumeration form loader

Fix LaunchedURLClassLoader to only enumerate resources from the
rootLoader and the URLs.

Commit cd2c189 (Support javaagent instrumentation with loader) added
a parent classloader and used filtering in the loadClass() method
to ensure classes were loaded from the appropriate location. The change
in parent means that locally packaged resources are found twice, once
from the parent, and once from the self archive URL.

LaunchedURLClassLoader now overrides getResource and getResources to
filter out the parent classloader and instead only add resources from
the root classloader and the URLs.

Issue: #56232870
This commit is contained in:
Phillip Webb 2013-10-09 11:09:03 -07:00
parent 64d9f4f18d
commit 35ff983b40

View File

@ -21,6 +21,7 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import org.springframework.boot.loader.jar.RandomAccessJarFile;
@ -53,6 +54,43 @@ public class LaunchedURLClassLoader extends URLClassLoader {
return null;
}
@Override
public URL getResource(String name) {
URL url = null;
if (this.rootClassLoader != null) {
url = this.rootClassLoader.getResource(name);
}
return (url == null ? findResource(name) : url);
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (this.rootClassLoader == null) {
return findResources(name);
}
final Enumeration<URL> rootResources = this.rootClassLoader.getResources(name);
final Enumeration<URL> localResources = findResources(name);
return new Enumeration<URL>() {
@Override
public boolean hasMoreElements() {
return rootResources.hasMoreElements()
|| localResources.hasMoreElements();
}
@Override
public URL nextElement() {
if (rootResources.hasMoreElements()) {
return rootResources.nextElement();
}
return localResources.nextElement();
}
};
}
/**
* Attempt to load classes from the URLs before delegating to the parent loader.
*/