Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassNotFoundException for plugin class, loading a spring boot executable jar #10

Open
fabioformosa opened this issue Jun 4, 2020 · 15 comments
Labels
enhancement New feature or request

Comments

@fabioformosa
Copy link

I'm testing the deployment runtime-mode.
Main App finds plugin jar that I put in plugins folder, but it fails when it tries to switch plugin state from RESOLVED to STARTED because:

java.lang.ClassNotFoundException: com.example.MyPlugin

I put the spring boot fat jar, built by spring-boot-maven-plugin that creates the following structure into the jar:

  • BOOT-INF
    -> classes -> com.example.MyPlugin and all others
    -> libs -> all jar dependencies
  • META-INF
  • org/springframework/boot/loader/...

Managing plugins with the shape of spring boot application, is SBP library aware to search classes under BOOT-INF folder?

@hank-cp
Copy link
Owner

hank-cp commented Jun 5, 2020

I have commit demonstration code of building plugin jar. Please checkout 9107e87 for more details. Also, you could read the doc describe further more.

Regarding to

Managing plugins with the shape of spring boot application, is SBP library aware to search classes under BOOT-INF folder?

the quick answer is no. I recommand search plugins jar via file system, rather than searching classpath. It's design to load/unload plugins dynamically at runtime time. If you use classpath, sbp has not difference as other ordinary monolithic Spring Boot application.

@fabioformosa
Copy link
Author

fabioformosa commented Jun 5, 2020

I recommand search plugins jar via file system, rather than searching classpath

I'm added the plugin jar via file system, but my jar is a spring boot executable jar, not a standard jar. Look at this link to browser the structure of a spring boot executable jar: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-executable-jar-format.html#executable-jar-jar-file-structure

You've done a wonderful work with this library, but since it addresses pluggability of spring boot apps, I'm expecting that it's possible to provide via filesystem a spring boot executable jar because it's a standard way to build for spring.

So, according your opinion, loading a plugin jar with that structure, is it possibile to specify to sbp plugin loader the path (inside jar): /BOOT-INF/classes and /BOOT-INF/libs?
I've tried with classes-directories properties but it doesn't work in deployment mode.

EDIT: I've just tried to load a standard jar (not spring boot executable jar ) assembling manually it with "libs" and it run OK. I think it could be more convenient to load a spring boot executable jar, because it contains all libs by default.

@fabioformosa fabioformosa changed the title ClassNotFoundException for plugin class in Deployment Mode ClassNotFoundException for plugin class, loading a spring boot executable jar Jun 5, 2020
@hank-cp
Copy link
Owner

hank-cp commented Jun 8, 2020

got your point.

I think this could be done by add a custom PluginLoader. Right now SbpAutoConfiguration.pluginManager use two PluginLoader as here and here. You could implement an ExecutableJarPluginLoader to locate the dependent jars in BOOT-INFO/libs, and then add it to SbpAutoConfiguration.pluginManager by overridding it.

@fabioformosa
Copy link
Author

Thank you for the answer. Now, it's clear to me how to define a new PluginLoader in the PluginManager bean.
I think that the ExecutableJarPluginLoader should use an extended version of your SpringBootPluginClassLoader. Could you help me to understand which method to override in SpringBootPluginClassLoader to locate (inside the jar) classes and libs into the folders BOOT-INFO/classes and BOOT-INFO/libs ?

@hank-cp
Copy link
Owner

hank-cp commented Jun 11, 2020

I have just added a configuration spring.sbp.custom-plugin-loaders to allow you customize your own PluginLoader (example)

You could use the SNAPSHOT version to experience it.

@fabioformosa
Copy link
Author

Good, so it's easier to add a custom plugin loader. Very nice!
But I don't understand yet how to develop this custom plugin loader to load classes from a jar with the structure of a spring-executable-jar.
It should be like the native JarPluginLoader but with an extendend SpringBootPluginClassLoader , I suppose.
Which method should I override in SpringBootPluginClassLoader to locate (inside the jar) classes and libs into the folders BOOT-INFO/classes and BOOT-INFO/libs ?

@hank-cp
Copy link
Owner

hank-cp commented Jun 12, 2020

I don't suggest you to extend SpringBootPluginClassLoader. There are complex class loading strategies behind it.

What you have to do now is to load jars inside a jar. Looks like there are no out-of-box solution till today(can't believe that >_<!). Here is antoher example.

Then you could implement a custom FatJarPluginLoader, who holds the PluginClassLoader, and tell this PluginClassLoader to load the jars by pluginClassLoader.addFile(myJarFile); just as other PluginLoader did.

@fabioformosa
Copy link
Author

What you have to do now is to load jars inside a jar

Not only jars, also the classes are in another folder (BOOT-INF/classes) inside the plugin.jar

@fabioformosa
Copy link
Author

With spring.sbp.custom-plugin-loaders does the CustomPluginLoader replace the default ones or add itself to the list of default loaders?

@hank-cp
Copy link
Owner

hank-cp commented Jun 19, 2020

adding, after the builtin pluginLoader DefaultPluginLoader/JarPluginLoader

@fabioformosa
Copy link
Author

Ok, I would need to remove/replace JarPluginLoader because it's apply to all jars. I would like to have an extended JarPluginLoader that supports standard jar and spring boot jar.

@hank-cp hank-cp added the enhancement New feature or request label Jun 23, 2020
@hank-cp
Copy link
Owner

hank-cp commented Jun 23, 2020

Have make custom-plugin-loader exclusive as #13 mentioned.

@wuyuan2009123
Copy link

i also get same error

@hank-cp
Copy link
Owner

hank-cp commented Dec 4, 2023

@wuyuan2009123 For a fatJar plugin, you need to unzip the jar and load classes/libs seperator. Or you can build your jar in flatten format.

This issue is still open because it is still waiting a workable FatJar example...

Repository owner deleted a comment from Gracemansam Apr 23, 2024
Repository owner deleted a comment from Gracemansam Apr 23, 2024
@luanact247
Copy link

@fabioformosa finally, how to fix this issue? I get this issue too. Could you show me how to resolve it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants