Aligns the classloader creation strategy of the aggregated module with the regular modules
- application classpath URLs are added to the launched aggregated module as well
This commit is contained in:
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.boot.loader.archive.Archive;
|
||||
import org.springframework.boot.loader.util.AsciiBytes;
|
||||
import org.springframework.cloud.stream.module.utils.ClassloaderUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -80,20 +81,7 @@ public class ModuleJarLauncher extends ExecutableArchiveLauncher {
|
||||
|
||||
@Override
|
||||
protected ClassLoader createClassLoader(URL[] urls) throws Exception {
|
||||
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||
if (systemClassLoader instanceof URLClassLoader) {
|
||||
// add the URLs of the application classloader to the created classloader
|
||||
// to compensate for LaunchedURLClassLoader not delegating to parent to retrieve resources
|
||||
@SuppressWarnings("resource")
|
||||
URLClassLoader systemUrlClassLoader = (URLClassLoader) systemClassLoader;
|
||||
URL[] mergedUrls = new URL[urls.length + systemUrlClassLoader.getURLs().length];
|
||||
System.arraycopy(urls, 0, mergedUrls, 0, urls.length);
|
||||
System.arraycopy(systemUrlClassLoader.getURLs(), 0, mergedUrls, urls.length,
|
||||
systemUrlClassLoader.getURLs().length);
|
||||
// add the extension classloader as parent to the created context, if accessible
|
||||
return new LaunchedURLClassLoader(mergedUrls, systemUrlClassLoader.getParent());
|
||||
}
|
||||
return new LaunchedURLClassLoader(urls, systemClassLoader);
|
||||
return ClassloaderUtils.createModuleClassloader(urls);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.util.regex.Pattern;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.loader.LaunchedURLClassLoader;
|
||||
import org.springframework.boot.loader.ModuleJarLauncher;
|
||||
import org.springframework.boot.loader.archive.Archive;
|
||||
import org.springframework.boot.loader.archive.JarFileArchive;
|
||||
@@ -146,8 +145,8 @@ public class ModuleLauncher {
|
||||
mainClassNames.add(jarFileArchive.getMainClass());
|
||||
arguments.add(toArgArray(moduleLaunchRequest.getArguments()));
|
||||
}
|
||||
final ClassLoader classLoader = new LaunchedURLClassLoader(jarURLs.toArray(new URL[jarURLs.size()]),
|
||||
ClassloaderUtils.getExtensionClassloader());
|
||||
final ClassLoader classLoader = ClassloaderUtils
|
||||
.createModuleClassloader(jarURLs.toArray(new URL[jarURLs.size()]));
|
||||
final List<Class<?>> mainClasses = new ArrayList<>();
|
||||
for (String mainClass : mainClassNames) {
|
||||
mainClasses.add(ClassUtils.forName(mainClass, classLoader));
|
||||
|
||||
@@ -16,24 +16,39 @@
|
||||
|
||||
package org.springframework.cloud.stream.module.utils;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.springframework.boot.loader.LaunchedURLClassLoader;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class ClassloaderUtils {
|
||||
|
||||
/**
|
||||
* Retrieves the extension classloader of the current JVM, if accessible. In general the extension classloader is
|
||||
* found in a hierarchy as the parent of the application classloader. If such a hierarchy does not exist, it will
|
||||
* return the application classloader itself.
|
||||
* Creates a ClassLoader for the launched modules by merging the URLs supplied as argument with the URLs that
|
||||
* make up the additional classpath of the launched JVM (retrieved from the application classloader), and
|
||||
* setting the extension classloader of the JVM as parent, if accessible.
|
||||
*
|
||||
* @return the classloader
|
||||
* @param urls a list of library URLs
|
||||
* @return the resulting classloader
|
||||
*/
|
||||
public static ClassLoader getExtensionClassloader() {
|
||||
public static ClassLoader createModuleClassloader(URL[] urls) {
|
||||
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||
// try to retrieve the extension classloader
|
||||
ClassLoader extensionClassLoader = systemClassLoader != null ? systemClassLoader.getParent() : null;
|
||||
// set the classloader for the module as the extension classloader if available
|
||||
// fall back to the system classloader (which can also be null) if not available
|
||||
return extensionClassLoader != null ? extensionClassLoader : systemClassLoader;
|
||||
if (systemClassLoader instanceof URLClassLoader) {
|
||||
// add the URLs of the application classloader to the created classloader
|
||||
// to compensate for LaunchedURLClassLoader not delegating to parent to retrieve resources
|
||||
@SuppressWarnings("resource")
|
||||
URLClassLoader systemUrlClassLoader = (URLClassLoader) systemClassLoader;
|
||||
URL[] mergedUrls = new URL[urls.length + systemUrlClassLoader.getURLs().length];
|
||||
System.arraycopy(urls, 0, mergedUrls, 0, urls.length);
|
||||
System.arraycopy(systemUrlClassLoader.getURLs(), 0, mergedUrls, urls.length,
|
||||
systemUrlClassLoader.getURLs().length);
|
||||
// add the extension classloader as parent to the created context, if accessible
|
||||
return new LaunchedURLClassLoader(mergedUrls, systemUrlClassLoader.getParent());
|
||||
}
|
||||
return new LaunchedURLClassLoader(urls, systemClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user