@ -36,8 +36,19 @@ import org.springframework.boot.loader.jar.JarFile;
* /
public class LaunchedURLClassLoader extends URLClassLoader {
static {
try {
ClassLoader . registerAsParallelCapable ( ) ;
}
catch ( NoSuchMethodError ex ) {
// Not available on earlier JDKs
}
}
private final ClassLoader rootClassLoader ;
private final LockProvider lockProvider ;
/ * *
* Create a new { @link LaunchedURLClassLoader } instance .
* @param urls the URLs from which to load classes and resources
@ -46,6 +57,17 @@ public class LaunchedURLClassLoader extends URLClassLoader {
public LaunchedURLClassLoader ( URL [ ] urls , ClassLoader parent ) {
super ( urls , parent ) ;
this . rootClassLoader = findRootClassLoader ( parent ) ;
this . lockProvider = createLockProvider ( ) ;
}
private LockProvider createLockProvider ( ) {
try {
ClassLoader . class . getMethod ( "getClassLoadingLock" , String . class ) ;
return new Java7LockProvider ( ) ;
}
catch ( NoSuchMethodException ex ) {
return new LockProvider ( ) ;
}
}
private ClassLoader findRootClassLoader ( ClassLoader classLoader ) {
@ -126,7 +148,7 @@ public class LaunchedURLClassLoader extends URLClassLoader {
@Override
protected Class < ? > loadClass ( String name , boolean resolve )
throws ClassNotFoundException {
synchronized ( this ) {
synchronized ( this .lockProvider . getLock ( this , name ) ) {
Class < ? > loadedClass = findLoadedClass ( name ) ;
if ( loadedClass = = null ) {
Handler . setUseFastConnectionExceptions ( true ) ;
@ -222,4 +244,27 @@ public class LaunchedURLClassLoader extends URLClassLoader {
}
}
/ * *
* Strategy used to provide the synchronize lock object to use when loading classes .
* /
private static class LockProvider {
public Object getLock ( LaunchedURLClassLoader classLoader , String className ) {
return classLoader ;
}
}
/ * *
* Java 7 specific { @link LockProvider } .
* /
private static class Java7LockProvider extends LockProvider {
@Override
public Object getLock ( LaunchedURLClassLoader classLoader , String className ) {
return classLoader . getClassLoadingLock ( className ) ;
}
}
}