Hello. I am trying to run a jshell with a system classloader containing the classes from a fat-jar produced by the gradle plugin task.
The system classloader is managed by the property java.system.class.loader, but the problem is that it needs a classloader with a constructor having a single parameter of parent classloader.
I believe that it is possible to extract such classloaders from JarLauncher and WarLauncher in org.springframework.boot.loader package.
Then it would be possible to launch the jshell somewhat like this:
jshell --class-path boot.jar -RDjava.system.class.loader=org.springframework.boot.loader.JarLauncherClassLoader
Do you mind me doing this refactoring? Found a related issue – https://github.com/spring-projects/spring-boot/issues/1812
Comment From: wilkinsona
Have you considered implementing your own ClassLoader that delegates to LaunchedURLClassLoader?
Comment From: faucct
Yes, I have considered it, but it would require to compile against the package and use a bunch of protected *Launcher methods. I think that extracting class-loaders seems like an intuitive direction to follow and believe that this would be much easier to integrate.
Comment From: faucct
Here is the code I had to write to extract the class-loader from the protected methods and I think that it is wrong to go that way:
new org.springframework.boot.loader.JarLauncher(
new org.springframework.boot.loader.archive.JarFileArchive(new java.io.File(
"/opt/ranker/lib/ranking-web-1.0-SNAPSHOT.jar"
))
) {
{
if (!isExploded()) {
org.springframework.boot.loader.jar.JarFile.registerUrlProtocolHandler();
}
try {
Thread.currentThread().setContextClassLoader(createClassLoader(getClassPathArchivesIterator()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
Comment From: faucct
So do you mind me refactoring that?
Comment From: wilkinsona
I don't think we're ready for that. Support for jshell hasn't been a goal of the project. That could change of course, but I don't think we should change public API for something that we may not want to support. I'll flag this issue for the team to discuss.
Comment From: faucct
What exactly is public API in the org.springframework.boot.loader package? I could try leaving it intact.
Comment From: wilkinsona
It's not just the public API. It's also the ongoing burden of maintaining support, testing it, and the ways that it would limit what we can change in the future. Thanks for your enthusiasm, but, to avoid wasted effort, please give us some time to discuss this before working on any changes as we may not accept them.
Comment From: faucct
Meanwhile, what is the proper way to compile against the files in the package?
Comment From: wilkinsona
Add a dependency on org.springframework.boot:spring-boot-loader.
Comment From: wilkinsona
We discussed this today and the team are in agreement that this isn't something that we want to support. Thanks anyway for the suggestion.