Support javaagent instrumentation with loader

Update spring-boot-loader to allow `-javaagent` instrumentation when
running from executable jars.

Prior to this commit the `Launcher` skipped the application classloader
and instead used the system classloader as a parent. This was to ensure
that locally packaged classes were always loaded by the classloader
that had access to nested jars.  Unfortunately when using the
`-javaagent` option, it is the application classloader that is modified.

The `Launcher` class now uses the application classloader as parent
and `LaunchedURLClassLoader` has been updated to always search local
URLs before delegating to the parent. This is very similar to the way
that most application servers handle the loading of war files.

Issue: #56232870
This commit is contained in:
Phillip Webb 2013-09-02 13:38:23 -07:00
parent 8bc06b4ee8
commit cd2c18965e
2 changed files with 28 additions and 1 deletions

View File

@ -40,6 +40,33 @@ public class LaunchedURLClassLoader extends URLClassLoader {
super(urls, parent);
}
/**
* Attempt to load classes from the URLs before delegating to the parent loader.
*/
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> loadedClass = findLoadedClass(name);
if (loadedClass == null) {
loadedClass = doLoadClass(name);
}
if (resolve) {
resolveClass(loadedClass);
}
return loadedClass;
}
}
private Class<?> doLoadClass(String name) throws ClassNotFoundException {
try {
return findClass(name);
}
catch (ClassNotFoundException e) {
}
return super.loadClass(name, false);
}
@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
int lastDot = name.lastIndexOf('.');

View File

@ -143,7 +143,7 @@ public abstract class Launcher {
* @throws Exception
*/
protected ClassLoader createClassLoader(URL[] urls) throws Exception {
return new LaunchedURLClassLoader(urls, getClass().getClassLoader().getParent());
return new LaunchedURLClassLoader(urls, getClass().getClassLoader());
}
/**