Load-time weaving, Spring and Maven.

Mattias Ask

As some of you might have read in my earlier post, I'm using load-time weaving in the project that I'm working on. Lately I've run in to some problems with getting the tests to play nice with Maven.

So what was the problem? Well, I've been using @Configurable and @Autowired to inject stuff in my domain object which I create in code. To get this working when running mvn test you have to pass in spring-agent.jar as javaagent. When you do this, everything worked great! To to this with Maven you have to do the following:

 
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.4</version>
    <configuration>
      <forkMode>once</forkMode>
      <argLine>
        -javaagent:${settings.localRepository}/org/springframework/spring-agent/${spring.version}/spring-agent-${spring.version}.jar
      </argLine>
      <useSystemClassloader>true</useSystemClassloader>
    </configuration>
</plugin>
 

Now, that's all cool, and it worked like a charm... for a while. When I added @Configurable to another class to autowire in a new dependency, I could not get that specific class to get weaved properly. Believe me, I tried everything I could think of, but nothing worked... until I found a hint on a thread with a related problem. By passing in a second javaagent, aspectjweaver.jar, the problem was solved! To do this in Maven you just add the second javaagent after the first, like this:

 
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.4</version>
    <configuration>
      <forkMode>once</forkMode>
      <argLine>
        -javaagent:${settings.localRepository}/org/springframework/spring-agent/${spring.version}/spring-agent-${spring.version}.jar -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/1.6.1/aspectjweaver-1.6.1.jar
      </argLine>
      <useSystemClassloader>true</useSystemClassloader>
    </configuration>
</plugin>
 

Note: If you add a line-break between the two javaagents, it doesn't work.

What was the problem I had? I have no idea! Why does this solution work? I have no idea! All I know is that I get a green light from my tests, and that I don't need this solution when running live in Tomcat or whatever, since the classloader there has addTransformer(ClassFileTransformer).

Still, if anyone has any idea of why I, after everything worked with only spring-agent.jar, needed to add aspectjweaver I am all ears! Don't get me wrong! I can live with not knowing, but I would get peace of mind from knowing...

Mattias Ask
Consultant at Jayway

Tags: , , , , ,

2 comments ↓

#1 Jorge Duarte on 08.07.10 at 21:57

The same procedure is required with Eclipse Helios.
Thx for sharing this information!

#2 Dejan on 06.29.11 at 17:21

Thank you for this post. It solved my problem with aspectjweaver.jar. I used the weaving to inject properties from template bean to my bean created in local code. For this I needed aspectjweaver.jar and spring 2.0 config . I see now it is not any more provided in spring 3.1.

Leave a Comment