I tried to test the performance of AOP on Spring framework 4.1.6 and
AOP methods were clean, jdk dynamic proxy and aspectJ.
I made one to five simple advices to them and checked elapsed time for each.
result:
jdk dynamic proxy:
aspect1: 2.499 sec.
aspect2: 2.574
aspect3: 2.466
aspect4: 2.436
aspect5: 2.563
aspectJ (ctw):
aspect1: 2.648
aspect2: 2.562
aspect3: 2.635
aspect4: 2.520
aspect5: 2.574
clean (no aspect):
aspect1: 2.699
aspect2: 2.513
aspect3: 2.527
aspect4: 2.458
aspect5: 2.402
Before testing them, I expected AspectJ (ctw) will be faster than Jdk dynamic proxy because AspectJ modified bytecode. But it was wrong even there was no performance difference among them.
So, I checked the target class(.class) modified to recognise that AspectJ Compiler used and found bytecode modified.
Here, I have question:
Is there any performance difference among them? (idk dynamic proxy, aspectj, no aop)
My code:
public class HelloAOP {
public static void main(String [] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/application-context.xml");
Order order = (Order) ctx.getBean("orderImpl");
SimpleDateFormat format = new SimpleDateFormat("mm:ss.SSS");
StopWatch watch = new StopWatch();
watch.start();
order.placeOrder();
watch.stop();
System.out.println("Elapsed: " + format.format(watch.getTotalTimeMillis()));
}
}
target:
#Service
public class OrderImpl implements Order {
public void placeOrder() {
System.out.println("::Target Object");
for(long i = 0; i < 5000000000L; i++);
}
}
aspect:
#Aspect
#Component
public class Aspect1 {
#Before("execution(* com.cafe.beans.impl.OrderImpl.placeOrder())")
public void aspect() {
System.out.println("Aspect 1 *");
}
}
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.6</version>
</dependency>
<build>
<finalName>testAop</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>3.3</source>
<target>3.3</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<complianceLevel>1.8</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You should not be surprised not to see any difference because you are just measuring one single method call. 99.9% of the time measured is the loop inside your method. Ergo you are not measuring the right thing. You should do it the other way around, maybe similar to what I did here:
The method should do nothing or next to nothing and print nothing.
You should measure the overall time of repeatedly calling an aspect-advised method because you want to find out about the overhead of applying an aspect, not about method body runtime (the method body remains unchanged by your aspect).
Now you can compare Spring AOP to AspectJ performance and should see that AspectJ is superior. A few caveats:
I hope you know that you need to change the Spring configuration so as to switch from Spring AOP to AspectJ and vice versa. E.g. if you use the AspectJ Maven Plugin all the time for your builds, you will use compile-time AspectJ weaving, no matter if you configure Spring to use Spring AOP or AspectJ via load-time weaving as described in the Spring manual, section 10.8 Using AspectJ with Spring applications.
You should measure different types of pointcuts and advice, e.g. #Before/#After vs. #Around, (not) using parameter binding via this(), target() or args() etc.
Please also note that your sample code uses a pointcut on a class rather than an interface. JDK dynamic proxies do not work directly on classes, though, only on interfaces. In order to apply Spring AOP on classes, you need CGLIB as a dependency in Spring, otherwise it simply will not work. Edit: Okay, your class implements the Order interface, so it might still work with JDK dynamic proxies.
Related
First up, a disclaimer, I'm not entirely happy with the architecture of what I'm about to ask about!
We have a Spring based project that produces a library as a jar. That library includes all the usual controller/service/jpa (repositories) layers you might expect but no boot application to start it all up.
The idea being various projects within our organisation can import the jar and get instant addition of a common (HTTP) API.
Unit tests work ok.
*IT.java tests are another matter.
Run in isolation by the IDE from the test/java/ hierarchy they run ok and pass.
However when running via maven as part of the build they fail.
[ERROR] ControllerIT » IllegalState Unable to find a #SpringBootConfiguration...
We have a Boot configuration in the test hierarchy which the ITs must be using when run via the IDE, but when running the maven build it seems it can't be found to start up the application (understandably as it is in the test package tree).
The boot file we do have is intended to be no more than a test harness to run the lib, to run the ITs.
We have h2 in the Maven test scope, but it isn't wanted in the final library (that is up to the host application to provide a datasource/connection etc).
Requirement:
Start up the API library in an application for testing
Run the tests as part of Maven build
H2 should not end up in final jar
Symptoms when running mvn install
[ERROR] ControllerIT » IllegalState Unable to find a #SpringBootConfiguration...
Presumably need some config somewhere in pom? Already using package.Boot in the Springboot maven plugin config.
Maybe just need to figure out the magic config to point it at the src/test/... Boot.class rather than src/main/...Boot.class
Question(s):
Does spring have a 'correct' way to achieve what we want (I'd go with MicroServices, but not an option because ... reasons)?
How should we go about implementing ITs against a H2 driven SpringBoot application when we don't want to include the bootable class (or H2 lib) in product jar?
Should we be creating a separate Maven module just for the ITs (with a dependency on the library module)?
Abbreviated Maven pom:
<properties>
<version.spring-boot>2.1.13.RELEASE</version.spring-boot>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring-boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.28.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.28.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0</version>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- other dependencies excluded for brevity -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${version.spring-boot}</version>
<configuration>
<!-- file lives in test hierarchy -->
<mainClass>org.my.packages.test.Boot</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<skip>true</skip><!-- Skipping unit tests while trying to sort ITs -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<failIfNoTests>true</failIfNoTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</execution>
</plugin>
</plugins>
</build>
The Spring Boot config:
#SpringBootApplication()
public class Boot extends SpringBootServletInitializer
{
public static void main(String[] args)
{
SpringApplication.run(Boot.class, args);
}
}
IT configuration:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ControllerIT
{
#Autowired
private TestRestTemplate restTemplate;
...
}
Number 2 lead me to looking into params of #SpringBootTest.
I ended up with ...
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = ITConfig.class)
Where ITConfig is:
#SpringBootApplication()
public class ITConfig extends SpringBootServletInitializer
{
public static void main(String[] args)
{
SpringApplication.run(org.lhasalimited.libraries.ITConfig.class, args);
}
}
That appears to be working. Thanks for the hint.
Let me propose one way of solving this issue, there are might be others:
#SpringBootTest annotation is intended to mimic the startup of the full fledged spring boot application.
It scans the packages up to the point where it finds #SpringBootConfiguration annotataion (this annotation is placed on #SpringBootApplication already) and this way it understands that the packages down to the package in which the main class is found should be scanned (to find all the beans).
Besides that, it does many other things that spring boot application does during the start: loading configurations (application.properties/yaml) obeying the conventions of spring boot application, loading auto-configurations (stuff inside spring.factories) and so forth.
Bottom line you'll have a full-fledged spring boot application (usually microservice) loaded inside the test.
So far so good, but you say that you don't really have a spring boot application. So I see three ways:
Introduce an artificial class with #SpringBootConfiguration in the src/test/java/whatever-package-close-to-root folder (note, its in 'test', not in src/main)
Use #SpringBootTest with a parameter of "Configuration". This will mean that SpringBootTest won't use all this scanning up-and-then-down process and instead you'll instruct it to use the concrete context configuration.
Do not use #SpringBootTest annotation at all, and prefer a "usual" #ContextConfiguration - yes, you won't have the power of spring boot but as I've said above you probably won't need it. In addition these tests will be way faster, especially if you'll provide many "#Configuration" classes and will load only "relevant" parts of the library during the tests.
For example, if you test the DAO, there is no point in loading web related stuff.
I have an existing Maven project based on JAX-RS using RESTEasy. It works great! It creates a WAR that I deploy to Tomcat running on Ubuntu. It's clean and follows the latest standards. The POM is simple:
...
<packaging>war</packaging>
...
<dependencies>
...
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.1.0.Final</version>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
...
I don't need any web.xml because I'm using the latest Java EE annotations:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/")
public class MyRESTApplication extends Application {
final FooResource fooResource = new FooResourceService();
...
#Override
public Set<Object> getSingletons() {
return ImmutableSet.of(fooResource);
}
}
This is all simple and it's working so great! Now I just want a way to easily change FooResource implementations based on the profile --- in other words, wire my singletons. That's where Spring comes in, right? And I've been told that Spring Boot makes Spring even more awesome, and you can use it with anything, and it gives you an actuator that allows you to gain real-time inside on the health of your system.
Unfortunately all the Spring Boot books and tutorials seem to think I'm starting with one of their quick-start applications. But I already have a great, simple application. I just want to:
Get my application wiring, based on profiles, from an external configuration file (not annotations) via Spring.
Get whatever other goodness comes from Spring Boot, because apparently it is awesome and will completely transform my application.
How do I add Spring (or Spring Boot) to this simple little JAX-RS application?
we solved it that way, that we created a singleton spring bean, let's call it ServiceStartupClass, where we register all JAX-RS services.
Here some code snippet how we start our services:
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
#Component
#ApplicationPath("/")
public class ServiceStartupClass extends ResourceConfig {
#PostConstruct
public void startup() {
register(FooResource.class);
...
}
}
If you need any further help, let me know
Before marking this question as a duplicate, please read through, as
I've gone through a number of posts on SO and other places but have
still failed to find a solution to my problem.
I'm trying to implement a project in Spring + AspectJ and as the title says, I can see the aspectj maven plugin applying the advice but it isn't actually called.
I'm trying to apply an advice based on an annotation.
Following is the annotation class:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface LogThis {
String name();
int id();
int eventID();
}
This annotation has been applied to a method which is being called from a js script on the front end through an ajax call. The method being called is as follows:
#RequestMapping(value = "/handle", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.NO_CONTENT)
#LogThis(name = "name", ID = 12345, eventID = 12345)
public void create(#RequestBody TodoDTO todo, HttpServletRequest req) {
//perform some action
}
The advice is being applied to the LogThis annotation and the advice is as follows:
#Pointcut("#annotation(LogThis)")
public void genericPointcut() {
}
#Pointcut("execution(* *(..))")
public void atExecution() {
}
#Async
#Before("genericPointcut() && atExecution()")
public void logBefore(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException {
// Perform logging
}
The annotation class and the aspect are in the same package while the class which is being advised is in a different package but everything is in the same project.
I've configured my maven pom.xml file as follows (only relevant portions shown):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<Xlint>ignore</Xlint>
<complianceLevel>${java.source-target.version}</complianceLevel>
<encoding>${project.build.sourceEncoding}</encoding>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
The properties are:
<properties>
<sonar.language>java</sonar.language>
<java.source-target.version>1.7</java.source-target.version>
<aspectj.version>1.8.7</aspectj.version>
</properties>
The aspectj dependencies are:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
Spring version being used is 4.1.3.RELEASE.
The spring config entry for my aspect is as follows:
<aop:aspectj-autoproxy />
<bean id="logAspect" class="somep2.LoggingAspect" />
On running mvn clean install the build succeeds and the following log entry is present w.r.t aspectj:
[INFO] --- aspectj-maven-plugin:1.8:compile (default) # myproj ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[INFO] Join point 'method-execution(void somep.SomeC.create(param1, param2))' in Type 'somep.SomeC' (SomeC.java:63) advised by before advice from 'somep2.LoggingAspect' (LoggingAspect.java:36)
[INFO]
[INFO] --- aspectj-maven-plugin:1.8:test-compile (default) # myproj ---
[WARNING] No sources found skipping aspectJ compile
According to the logs, the join point was found and advised but the logBefore() method is never called when the create() method is called. I am certain of this because I'm writing to a file using a FileWriter but nothing is being written.
Deployment details:
This project is built as part of another project which creates an ear file which is then deployed on JBoss 6.3
I've tried numerous approaches but nothing has worked. Please let me know what I'm missing.
Any help is appreciated.
I finally got it to work. Turns out I was complicating things too much. There was no need for the aspectj compiler. All that I had to do was tell spring that my aspect was a component as well so that it could inject my advice.
So here's the complete list of changes:
Removed the aspectj-maven-plugin from pom.xml. It is not required.
Removed the aspectj-tools and spring-aop dependencies and added the aspectj-weaver dependency to pom.xml
Removed the bean entry for my aspect from the spring config.
Annotated my aspect class with #Component and made sure that it was being scanned as part of the Spring component scan.
Hope this helps someone else as well.
PS. I still do not completely understand why this worked so if someone has an explanation, please comment.
I am creating a new project that uses aspectj transactions. It also uses legacy jars that contain services that are using the proxy method where an interface is required.
I am using java config and when I set
#EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
Then I get the following exception thrown with accessing the proxy style services from the legacy libs:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
If I change to:
#EnableTransactionManagement(mode=AdviceMode.PROXY)
Then I don't get the problem but I can't then use the aspectj style transactions in my new project.
I've tried adding two #EnableTransactionManagement annotations with each adviceMode, but that is not allowed.
Here is the annotated class
#EnableWebMvc
#Configuration
#ComponentScan("com.mydomain")
#EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
public class ApplicationConfig extends WebMvcConfigurerAdapter {
...
I've also added the aspectj maven plugin to the legacy project in the hope that it would handle the weaving at compile time and thus aspectj transactions would work. But this has not solved the problem.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<showWeaveInfo>true</showWeaveInfo>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Is it possible to have spring deal with both advice modes? How would I do this?
Or is there another way around this problem.
The problem was with the aspectj config on the legacy project.
When I ran mvn compile it became apparent. I had to add the dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
That got it working when compiled using maven, but I it would still not work in eclipse. I had to right click on the legacy project in eclipse:
Configure>Convert to Aspectj Project
Then I could deploy from eclipse and I had aspectj transactional support in the legacy jars.
I try to hijack/intercept a method of a class in EclipseLink. I had tried Spring AOP and AspectJ and I failed. I want to do something when class org.eclipse.persistence.internal.localization.i18n.TraceLocalizationResource throw exception while calling method getString(..); My implementation as below:
#AfterThrowing(pointcut = "execution(* org.eclipse.persistence.internal.localization.i18n.TraceLocalizationResource.getString(..))",throwing="error")
public void logAfterThrowing(JoinPoint joinPoint,Throwable error) {
....
}
And calssTraceLocalizationResource was called (I debug into it). But the hijack method wasn't called.
MY questions:
Was I doing it in the wrong way ?
The target class we want to hijack or intercept must be self-define type?
What if I want to hijack a class in JDK like java.lang.String ?
Basically the syntax looks okay, but I have not tried to replicate a
full aspect from your code snippet here. Furthermore, I only use
native AspectJ syntax and am not quite familiar with
annotation-based syntax, so if there is a problem there I might not
have seen it.
No, but if you want to weave a library (JAR or unpacked into the file system) used by your main application, you must make sure that it is in the in-path for the weaver. Please consult AspectJ documentation for the syntax. Edit: I posted some helpful links in another answer earlier today.
By default, packages org.aspectj, java and javax are excluded from weaving. For the latter two, there are command line switches to enable weaving. But LTW will be tricky at best and a pain in the a** (next to impossible) at worst because you have a hen-and-egg problem there: The AspectJ weaver runtime classes need the JDK, and JDK bootstrapping happens before any Java agent like the weaver is attached. So your best bet is compile-time weaving for JDK classes and then using the woven rt.jar later in your application. Even with compile-time weaving you might run into issues if your advice use JDK woven classes themselves. You want to make sure to avoid infinite recursions there. But it is possible.
Update: Another hint which sometimes seems too simple to mention for someone who has used AspectJ for a while: Instead of an execution pointcut which makes it necessary to weave the target class, you may just use a call pointcut which intercepts (as the name implies) calls to the target everywhere in your client classes. It might be a little less efficient, but maybe your best and easiest bet unless you really want to take the trouble of weaving the JDK.
It is possible to weave third party libraries but you must configure the aspectj-maven-plugin plugin:
<project>
...
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.agroup</groupId>
<artifactId>to-weave</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.anothergroup</groupId>
<artifactId>gen</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.9</version>
<configuration>
<weaveDependencies>
<weaveDependency>
<groupId>org.agroup</groupId>
<artifactId>to-weave</artifactId>
</weaveDependency>
<weaveDependency>
<groupId>org.anothergroup</groupId>
<artifactId>gen</artifactId>
</weaveDependency>
</weaveDependencies>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
<build>
...
</project>
Source: http://www.mojohaus.org/aspectj-maven-plugin/examples/weaveJars.html