Issue
I've tried to follow the advice found here: https://www.baeldung.com/spring-inject-bean-into-unmanaged-objects
Only to find that it's compiling but not actually doing what it should. The autowired bean is not being set in the non-managed object.
@SpringBootApplication
@EnableSpringConfigured
public class SpringApp {
...
public class ApiClient {
private static String result = "not set";
//this would be called from another applicaiton written in a different language potentially.
public String apiInterface(String message) {
//This is where we're going to have to create Spring, where the languages 'join'.
SpringApplicationBuilder builder = new SpringApplicationBuilder(SpringApp.class);
builder.run();
System.out.println("Running legacy code...");
LegacyCode oldCode = new LegacyCode();
result = oldCode.doLegacyStuff("hello world");
return result;
}
}
...
@Configurable(preConstruction = true)
public class LegacyCode {
@Autowired
MessageSender sender; //let's pretend we Spring-fied this bit of code but not the Legacy code that uses it.
public String doLegacyStuff(String message) {
sender.send(message);
sender.close();
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
return "interupted";
}
return "ok";
}
}
That's the gist of the code. The full code is over at github here:https://github.com/AlexMakesSoftware/SpringConsoleApp3
The output I get is:
Exception in thread "main" java.lang.NullPointerException
at demo.LegacyCode.doLegacyStuff(LegacyCode.java:13)
at demo.ApiClient.apiInterface(ApiClient.java:17)
at demo.DummyApplication.main(DummyApplication.java:7)
Which can only mean that the @Autowired MessageSender isn't getting injected.
Any ideas what I'm doing wrong?
EDIT: I should point out that this is a simple example of a more complicated project to slowly integrate Spring into a legacy codebase. I cannot simply 'make it all Spring', nor can I shift the location of Spring's initialisation because this legacy code gets called from another application (albeit a simpler one) written in another language but running in the JVM. Yes, it's horrible, I know.
Solution
I did not clone your project, just started to take a quick look at your POM in the browser. What immediately jumped at me was this:
Your Maven POM is wrong. You only preconfigure the AspectJ Maven Plugin in the pluginManagement
section without ever actually declaring the plugin in the regular plugins
section. I.e., the plugin is not going to be used during your build.
If after fixing that you are still having follow-up problems, I can take a second look.
Update: What I said before is true, but I also noticed some more oversights in your POM and test code:
- You use a non-existent AspectJ Maven Plugin version.
- For compile-time weaving, you need the AspectJ runtime
aspectjrt
on the classpath. - You need
spring-tx
on the dependency list, otherwise a class referred to byspring-aspects
will not be found. - Your test expects a result different from the actual "ok".
Update 2: You can simply accept this pull request.
Answered By - kriegaex