From e2b3c03fc4d2c4a8a1d0802bd2c290b4dc9d15ca Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 2 Sep 2013 16:19:27 -0700 Subject: [PATCH] Refine LaunchedURLClassLoader load order Refine the loading order of LaunchedURLClassLoader to consider the root loader before locally bundled classes. The prevents classes from locally bundled JARs from replacing system classes. Issue: #56232870 --- .../boot/loader/LaunchedURLClassLoader.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) 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 451654a7b2..ba12d25755 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 @@ -31,6 +31,8 @@ import org.springframework.boot.loader.jar.RandomAccessJarFile; */ public class LaunchedURLClassLoader extends URLClassLoader { + private final ClassLoader rootClassLoader; + /** * Create a new {@link LaunchedURLClassLoader} instance. * @param urls the URLs from which to load classes and resources @@ -38,6 +40,17 @@ public class LaunchedURLClassLoader extends URLClassLoader { */ public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); + this.rootClassLoader = findRootClassLoader(parent); + } + + private ClassLoader findRootClassLoader(ClassLoader classLoader) { + while (classLoader != null) { + if (classLoader.getParent() == null) { + return classLoader; + } + classLoader = classLoader.getParent(); + } + return null; } /** @@ -59,11 +72,24 @@ public class LaunchedURLClassLoader extends URLClassLoader { } private Class doLoadClass(String name) throws ClassNotFoundException { + + // 1) Try the root class loader + try { + if (this.rootClassLoader != null) { + return this.rootClassLoader.loadClass(name); + } + } + catch (Exception ex) { + } + + // 2) Try to find locally try { return findClass(name); } - catch (ClassNotFoundException e) { + catch (Exception ex) { } + + // 3) Use standard loading return super.loadClass(name, false); }