Spring Boot - Can't get load time weaving with aspectj to work
Solution 1
Okay, I took a quick look at your GitHub project. The POM is pretty weird, e.g. it does not contain any dependency on spring-instrument. Furthermore, you depend on aspectjweaver 1.8.2, but on aspectjrt 1.5.4. You should really use the same version for both.
Anyway, I experimented with different Java agents on the command line, and it seems that it is not enough to just use AspectJ weaver (result: exception) or just Spring Instrument (result: aspects do not work, just as you described). You need to use both:
java -javaagent:path/to/aspectjweaver-1.8.2.jar -javaagent:path/to/spring-instrument-4.1.0.RELEASE.jar ...
This works for me with your code and yields the following on the console when using Curl according to your description:
[AppClassLoader@58644d46] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.1.6.RELEASE)
2014-09-08 13:09:54.489 INFO 1464 --- [ main] App : Starting App on Xander-PC with PID 1464 (C:\Users\Alexander\Documents\java-src\SO_AJ_SpringBootPrivilegedAspect\target\classes started by Alexander in C:\Users\Alexander\Documents\java-src\SO_AJ_SpringBootPrivilegedAspect)
2014-09-08 13:09:54.513 INFO 1464 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6771beb3: startup date [Mon Sep 08 13:09:54 CEST 2014]; root of context hierarchy
(...)
2014-09-08 13:09:56.257 INFO 1464 --- [ main] o.s.c.w.DefaultContextLoadTimeWeaver : Found Spring's JVM agent for instrumentation
2014-09-08 13:09:56.259 INFO 1464 --- [ main] o.s.c.w.DefaultContextLoadTimeWeaver : Found Spring's JVM agent for instrumentation
Aspect of called
(...)
2014-09-08 13:09:56.779 INFO 1464 --- [ main] App : Started App in 2.531 seconds (JVM running for 3.067)
2014-09-08 13:09:59.115 INFO 1464 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2014-09-08 13:09:59.115 INFO 1464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2014-09-08 13:09:59.122 INFO 1464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 7 ms
Aspect of called
Advising getter
Solution 2
Try declaring an InstrumentationLoadTimeWeaver bean instead of explicitly using -javaagent:/path/to/org.springframework.instrument-{version}.jar. As per the documentation
To use it, you must start the virtual machine with the Spring agent, by supplying the following JVM options:
-javaagent:/path/to/org.springframework.instrument-{version}.jar
Note that this requires modification of the VM launch script which may prevent you from using this in application server environments (depending on your operation policies). Additionally, the JDK agent will instrument the entire VM which can prove expensive.
I am hoping doing the way below would be better I guess.
@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
return loadTimeWeaver;
}
The same can be done in xml configuration.
Found a new library that just solves to dynamically setup spring InstrumentationLoadTimeWeaver to enable support for aspects without having to start the JVM with an explicit java agent
<dependency>
<groupId>de.invesdwin</groupId>
<artifactId>invesdwin-instrument</artifactId>
<version>1.0.2</version>
</dependency>
Spring boot config
@SpringBootApplication
/**
* Make @Configurable work via @EnableLoadTimeWeaving.
* If it does not work, alternatively you can try:
* @ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml")
*/
@EnableLoadTimeWeaving
public class MySpringBootApplication {
public static void main(final String[] args) {
DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes
}
}
sat
Updated on June 05, 2022Comments
-
sat almost 2 years
Could anyone please tell me why the aspect won't fire when using spring boot? I am trying to setup load time weaving with aspectj so that I can have private methods advised.
Here is the link to the barebones project - https://github.com/satb/spring_aop_test_project.git
Run the "App" class with "-javaagent:path/to/spring-instrument-4.1.0.RELEASE.jar" (or some other version of the lib on your computer) and run the curl command
curl -i http://localhost:8080/test-app/motd
The MyAspect class has an advice that should execute when the private method of MyService is called. But in this case, nothing happens.
When the application starts though, I see a message like this:
[AppClassLoader@58644d46] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified.
I tried following the suggestion from here to get it to work but that didn't help - Using @Autowired with AspectJ and Springboot
-
sat over 9 years@kregaex - Thanks. Looks like I missed adding aspectjweaver as a javaagent. Didn't realize it was needed. Although I read about it on SO when someone else had the same problem, it didn't work for me when I added it on my earlier test. Therefore, I removed it thinking that wasn't the problem. But maybe the problem then was something else. And sorry for the same question another time. I should have added this barebones project link to the other question itself.
-
subes over 8 yearsAn easier solution is to dynamically load the agent without the need of jvm arguments: github.com/subes/invesdwin-instrument
-
Juzer Ali about 8 yearsThis does not work with spring boot jar github.com/spring-projects/spring-boot/issues/739
-
Vikram Palakurthi about 8 yearsI implemented it using spring boot jar and have it working in production application, the implementation shouldn't really make any different with spring boot or normal spring implementation.
-
Juzer Ali about 8 yearsdid you deploy your spring boot application using embedded tomcat server?
-
Vikram Palakurthi about 8 yearsYup the application runs in embedded tomcat server.
-
Juzer Ali about 8 yearsThen I wonder what this bug is all about?
-
codeomnitrix almost 6 years@VikramPalakurthi how can you achieve the Custom LoadTimeweaver with xml?
-
LppEdd about 5 yearsWhat I'm trying to understand is, why do I need to load both Java Agents? The documentation doesn't mention that
-
kriegaex about 5 yearsI am not a Spring user, I just wanted to help. I am an AspectJ expert, so I can also help a bit with Spring AOP or AspectJ via LTW within Spring. The documentation actually says that either one agent should suffice. Maybe there is a way to just use
spring-instrument
and make it load the AspectJ weaver automatically if done right. But what "done right" exactly means, I have no idea. There are others more qualified than I to answer that. But it does work with both agents on the command line.