From 0fd1e37a8f463f13990755d09144d56d13712a85 Mon Sep 17 00:00:00 2001 From: Marius Bogoevici Date: Wed, 2 Sep 2015 22:49:20 -0400 Subject: [PATCH] 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 --- .../boot/loader/ModuleJarLauncher.java | 16 ++------- .../module/launcher/ModuleLauncher.java | 5 ++- .../stream/module/utils/ClassloaderUtils.java | 35 +++++++++++++------ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/spring-cloud-stream-module-launcher/src/main/java/org/springframework/boot/loader/ModuleJarLauncher.java b/spring-cloud-stream-module-launcher/src/main/java/org/springframework/boot/loader/ModuleJarLauncher.java index 5bb462a38..266831918 100644 --- a/spring-cloud-stream-module-launcher/src/main/java/org/springframework/boot/loader/ModuleJarLauncher.java +++ b/spring-cloud-stream-module-launcher/src/main/java/org/springframework/boot/loader/ModuleJarLauncher.java @@ -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); } } diff --git a/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/launcher/ModuleLauncher.java b/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/launcher/ModuleLauncher.java index 0c38f36b5..4361bb784 100644 --- a/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/launcher/ModuleLauncher.java +++ b/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/launcher/ModuleLauncher.java @@ -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> mainClasses = new ArrayList<>(); for (String mainClass : mainClassNames) { mainClasses.add(ClassUtils.forName(mainClass, classLoader)); diff --git a/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/utils/ClassloaderUtils.java b/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/utils/ClassloaderUtils.java index c45098d02..5dc92ec53 100644 --- a/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/utils/ClassloaderUtils.java +++ b/spring-cloud-stream-module-launcher/src/main/java/org/springframework/cloud/stream/module/utils/ClassloaderUtils.java @@ -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); } }