|
17 | 17 | package org.springframework.boot.devtools.restart.classloader;
|
18 | 18 |
|
19 | 19 | import java.io.IOException;
|
| 20 | +import java.lang.reflect.Method; |
20 | 21 | import java.net.MalformedURLException;
|
21 | 22 | import java.net.URL;
|
22 | 23 | import java.net.URLClassLoader;
|
|
30 | 31 | import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
|
31 | 32 | import org.springframework.core.SmartClassLoader;
|
32 | 33 | import org.springframework.util.Assert;
|
| 34 | +import org.springframework.util.ReflectionUtils; |
33 | 35 |
|
34 | 36 | /**
|
35 | 37 | * Disposable {@link ClassLoader} used to support application restarting. Provides parent
|
|
41 | 43 | */
|
42 | 44 | public class RestartClassLoader extends URLClassLoader implements SmartClassLoader {
|
43 | 45 |
|
| 46 | + private final ClassLoadingLockSupplier classLoadingLockSupplier; |
| 47 | + |
44 | 48 | private final Log logger;
|
45 | 49 |
|
46 | 50 | private final ClassLoaderFileRepository updatedFiles;
|
@@ -85,6 +89,11 @@ public RestartClassLoader(ClassLoader parent, URL[] urls,
|
85 | 89 | if (logger.isDebugEnabled()) {
|
86 | 90 | logger.debug("Created RestartClassLoader " + toString());
|
87 | 91 | }
|
| 92 | + Method classLoadingLockMethod = ReflectionUtils.findMethod(ClassLoader.class, |
| 93 | + "getClassLoadingLock", String.class); |
| 94 | + this.classLoadingLockSupplier = classLoadingLockMethod != null |
| 95 | + ? new StandardClassLoadingLockSupplier() |
| 96 | + : new Java6ClassLoadingLockSupplier(); |
88 | 97 | }
|
89 | 98 |
|
90 | 99 | @Override
|
@@ -142,7 +151,7 @@ public Class<?> loadClass(String name, boolean resolve)
|
142 | 151 | if (file != null && file.getKind() == Kind.DELETED) {
|
143 | 152 | throw new ClassNotFoundException(name);
|
144 | 153 | }
|
145 |
| - synchronized (getClassLoadingLock(name)) { |
| 154 | + synchronized (this.classLoadingLockSupplier.getClassLoadingLock(this, name)) { |
146 | 155 | Class<?> loadedClass = findLoadedClass(name);
|
147 | 156 | if (loadedClass == null) {
|
148 | 157 | try {
|
@@ -232,4 +241,32 @@ public E nextElement() {
|
232 | 241 |
|
233 | 242 | }
|
234 | 243 |
|
| 244 | + private interface ClassLoadingLockSupplier { |
| 245 | + |
| 246 | + Object getClassLoadingLock(RestartClassLoader classLoader, String className); |
| 247 | + |
| 248 | + } |
| 249 | + |
| 250 | + private static final class Java6ClassLoadingLockSupplier |
| 251 | + implements ClassLoadingLockSupplier { |
| 252 | + |
| 253 | + @Override |
| 254 | + public Object getClassLoadingLock(RestartClassLoader classLoader, |
| 255 | + String className) { |
| 256 | + return classLoader; |
| 257 | + } |
| 258 | + |
| 259 | + } |
| 260 | + |
| 261 | + private static final class StandardClassLoadingLockSupplier |
| 262 | + implements ClassLoadingLockSupplier { |
| 263 | + |
| 264 | + @Override |
| 265 | + public Object getClassLoadingLock(RestartClassLoader classLoader, |
| 266 | + String className) { |
| 267 | + return classLoader.getClassLoadingLock(className); |
| 268 | + } |
| 269 | + |
| 270 | + } |
| 271 | + |
235 | 272 | }
|
0 commit comments