This solution was therefore not suitable for me, but I understand this is consequence of the core design of spring boot, and nothing can be done easily.
I disagree quite strongly with that. There's nothing about the core design of Spring Boot that stops you from deploying multiple applications in the same JVM. As I said above, that's exactly what happens when you deploy multiple war files that use Spring Boot to a servlet container.
If you specifically want to use the exact same class loader with multiple applications then, yes, that will be difficult. However, I don't think it makes sense to do so. An application is intended to be an isolated unit and sharing a ClassLoader breaks that isolation. Irrespective of the use of Spring Boot, breaking that isolation can lead to class path conflicts.
This is a standard modularity problem on the JVM. The tried and tested solution to that problem is to use separate class loaders. Here's a basic example of how that might look for four Boot apps:
public class MultipleApps {
public static void main(String[] args) throws Exception {
launchApp(new File("app1.jar"));
launchApp(new File("app2.jar"));
launchApp(new File("app3.jar"));
launchApp(new File("app4.jar"));
}
private static void launchApp(File fatJar, String... args) throws Exception {
ClassLoader classLoader = new URLClassLoader(new URL[] {fatJar.toURI().toURL()});
Class<?> mainClass = classLoader.loadClass(getMainClassName(fatJar));
Method mainMethod = mainClass.getMethod("main", String[].class);
mainMethod.invoke(null, new Object[] {args});
}
private static String getMainClassName(File fatJar) throws IOException {
try (JarFile jarFile = new JarFile(fatJar)) {
return jarFile.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
}
}
}
Originally posted by @wilkinsona in https://github.com/spring-projects/spring-boot/issues/3300#issuecomment-254170473
Comment From: tongsrv
After some test, report error:
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.tongtech.lithops.process.LithopsProcess.launchApp(LithopsProcess.java:149)
at com.tongtech.lithops.process.LithopsProcess.testLaunch(LithopsProcess.java:63)
at com.tongtech.lithops.process.LithopsProcess$1.run(LithopsProcess.java:37)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:86)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
... 8 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:194)
at com.tongtech.creeper.kernel.Main.main(Main.java:61)
... 16 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 18 common frames omitted
How we should resolve this error?
Comment From: wilkinsona
@tongsrv I can't see the connection between my comment on #3300 that you've copied above and the exception that you're seeing. It appears that you do not have spring-jcl
on the classpath but it's impossible to tell why that would be the case from a stack trace alone.
This sort of problem diagnosis is better-suited to Gitter or Stack Overflow. In either case, you'll have to provide more information about the problem, and ideally a minimal example that reproduces it.