From 35ff983b4070eaa4b5f50c9085a12c2aeda1e375 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 9 Oct 2013 11:09:03 -0700 Subject: [PATCH] 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 --- .../boot/loader/LaunchedURLClassLoader.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java index ba12d25755..fa2de4e260 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java @@ -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 getResources(String name) throws IOException { + + if (this.rootClassLoader == null) { + return findResources(name); + } + + final Enumeration rootResources = this.rootClassLoader.getResources(name); + final Enumeration localResources = findResources(name); + + return new Enumeration() { + + @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. */