From 4585bc846ae74b6918b1c2b7c14e32b2fcdd7078 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 2 May 2018 08:27:38 +0100 Subject: [PATCH] Restore RestartClassLoader's Java 6 compatibility Closes gh-12826 --- .../classloader/RestartClassLoader.java | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java index 04ba9ad715..774eaec060 100644 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java @@ -17,6 +17,7 @@ package org.springframework.boot.devtools.restart.classloader; import java.io.IOException; +import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -30,6 +31,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind; import org.springframework.core.SmartClassLoader; import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; /** * Disposable {@link ClassLoader} used to support application restarting. Provides parent @@ -41,6 +43,8 @@ import org.springframework.util.Assert; */ public class RestartClassLoader extends URLClassLoader implements SmartClassLoader { + private final ClassLoadingLockSupplier classLoadingLockSupplier; + private final Log logger; private final ClassLoaderFileRepository updatedFiles; @@ -85,6 +89,11 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad if (logger.isDebugEnabled()) { logger.debug("Created RestartClassLoader " + toString()); } + Method classLoadingLockMethod = ReflectionUtils.findMethod(ClassLoader.class, + "getClassLoadingLock", String.class); + this.classLoadingLockSupplier = classLoadingLockMethod != null + ? new StandardClassLoadingLockSupplier() + : new Java6ClassLoadingLockSupplier(); } @Override @@ -142,7 +151,7 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad if (file != null && file.getKind() == Kind.DELETED) { throw new ClassNotFoundException(name); } - synchronized (getClassLoadingLock(name)) { + synchronized (this.classLoadingLockSupplier.getClassLoadingLock(this, name)) { Class loadedClass = findLoadedClass(name); if (loadedClass == null) { try { @@ -232,4 +241,32 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad } + private interface ClassLoadingLockSupplier { + + Object getClassLoadingLock(RestartClassLoader classLoader, String className); + + } + + private static final class Java6ClassLoadingLockSupplier + implements ClassLoadingLockSupplier { + + @Override + public Object getClassLoadingLock(RestartClassLoader classLoader, + String className) { + return classLoader; + } + + } + + private static final class StandardClassLoadingLockSupplier + implements ClassLoadingLockSupplier { + + @Override + public Object getClassLoadingLock(RestartClassLoader classLoader, + String className) { + return classLoader.getClassLoadingLock(className); + } + + } + }