Loading Spring beans from external JAR file

I am working on a Spring Boot application. I want to provide a (rather rudimentary) plugin system. I originally hoped this was enough to just add the JAR to the classpath like this:

URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;

Method method = sysclass.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(sysloader, new File("./plugin/plugin.jar").toURI().toURL());

SpringApplication.run(Application.class, args);

      

There is a class in plugin.jar annotated with @Controller

and RequestMapping. The context loads fine and the controller constructor is called as well. However, looking at the logs, I see that RequestMapping was not received.

Also, if I try to execute the @Autowire

JpaRepository in the plugin controller, it fails to respond that it cannot find the repository interface class (which I assume is some kind of problem that I was messing with with the ClassLoader).

It's just that the auto-install of the repository in my main application works fine, so it shouldn't be a problem with its configuration.

Is there something I am doing wrong? Can I tweak Springs ApplicationContext or its ClassLoader to work properly?

To summarize, I want to load some controllers (and possibly other Spring components) at runtime from an external JAR in a different folder.

+3


source to share


2 answers


At this point, I have just declared profile declarations in my pom application for my various plugins, and I will just compile it using the plugin profiles I want. It's not very dynamic, but at least I can completely decouple plugin development from application development and Spring takes all the plugin components.



This isn't exactly what I wanted, but I thought I'd describe how I "solved" it anyway. If anyone knows a way to make this work with external JARs, I'd be happy to accept this answer!

0


source


I solved this by importing the dependency that my controller is in and then calling the controller and main startup method packages with the same name (but in different projects). This is a hack, but it works.



0


source







All Articles