-
-
Notifications
You must be signed in to change notification settings - Fork 545
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
How to use Application ClassLoader to load all plugins #497
Comments
The part with the same ClassLoader for both application and plugins is the ultimate solution (I don't recommend a such solution). |
@karthic891 Any news on this topic? Can I help you with anything else related to this topic? If your response is no, I want to close this issue. |
Hi @decebals |
I played a little bit with this idea and my conclusion is that with the current state of the pf4j, it's not easy to achieve this goal. |
However, if you want to try, the idea is to set the
where public class UrlClassLoader extends URLClassLoader {
static {
registerAsParallelCapable();
}
/*
* Required when this classloader is used as the system classloader.
*/
public UrlClassLoader(ClassLoader parent) {
super(new URL[0], parent);
}
@Override
public void addURL(URL url) {
super.addURL(url);
}
public void addFile(File file) throws IOException {
addURL(file.getCanonicalFile().toURI().toURL());
}
/*
* Required for Java Agents when this classloader is used as the system classloader.
*/
@SuppressWarnings("unused")
private void appendToClassPathForInstrumentation(String jarPath) throws IOException {
addURL(Paths.get(jarPath).toRealPath().toUri().toURL());
}
} The After this, you need to set this custom class loader in
That's about all I had to say on this subject. If you get something notable, create a PR and we will discuss it. |
I came across this issue from a different context: using Hibernate with JPA annotations in my plugins fails since I wonder whether using the |
@milgner With your use case, we are between two worlds, the Hibernate guys don't know about PF4J and I don't know (too much) about Hibernate 😄. |
Well, I certainly wouldn't want to suggest making Hibernate-specific changes to PF4J. The heart of the matter is In Hibernate, I hope that it could be solved by getting it to use the class loading service which knows about all plugins and their classes but when I read about the |
I think so too
As I mentioned somehow in #497 (comment), for me this approach with one ClassLoader for application and plugins seems a step backwards. It comes as a solution to a problem but your application loses the power provided by PF4J. Maybe in this situation you don't need PF4J and a custom solution based on a dynamic class loader and ServiceLoader is good enough. Maybe in the future someone will fully implement the solution based on On the other hand, I think that other developers also use the PF4J with Hibernate, and I was curious to see how they do it. |
@milgner |
I solved it, but only for the specific use case of Hibernate. After collecting all the plugin classloaders and passing them in to Hibernate as base classloaders, all entity classes from my plugins can be loaded. See hibernate/hibernate-reactive#1526 (comment) for a code snippet. The original issue remains unaffected by this, though. Sorry for jumping on this but when I originally found this issue, it seemed somewhat applicable to my use case. |
@karthic891 Can we close it? Do you need more help? |
@decebals Yes, we can close this. Thank you. |
Hi @decebals ,
I'm building a pf4j plugin with javassist and msgpack libraries. I'm building a fat jar out of the plugin. This fat jar contains javassist and msgpack library classes. Looks like there's some issue with class loading, probably during annotation processing (some classes are annotated with @message annotation which gets processed at runtime during serialization/deserialiation of our pojos)
I get the following error:
When I move the javassist, msgpack and our pojo libraries out of the fat jar, place them in the classpath of the app (-cp) and when I call the app, I don't get the above error. When I run in this way, the library classes mentioned above are loaded by the Application ClassLoader (not the plugin/dependency class loader). I verified this through the TRACE logs.
I'd like to try loading all the plugins with the Application ClassLoader so that I can build a fat jar for each plugin and not have separate dependencies in the classpath belonging to each of the plugins. I see that you have mentioned:
This doesn't seem to be clear enough on how to pass host application's ClassLoader. Could you please provide a sample on how to define a DefaultPluginManager that loads plugins from a filesystem path and uses application's ClassLoader?
Here's the sample I use that didn't work (it doesn't use Application's class loader, hence fails in my case):
Appreciate your library and the documentation. Thank you.
The text was updated successfully, but these errors were encountered: