I build small library (Java and Maven) - using AspectJ. Library must be independent. Library deliver Aspects and Annotations. Function of library is - "call advice when executed a method with specific annotation". All is ok when I use everything in one module, but problem appers when i separate library and project with classes which advice must be applied. I create simple schema.
Library B - my library (aspects and annotations)
Project A - project with buisness methods which adivce must be applied
Is any posibility to do this?

- 63,017
- 15
- 111
- 202

- 113
- 1
- 7
2 Answers
According to the AspectJ Maven documentation, chapter "using aspect libraries", you need to
- add the aspect library as a regular
<dependency>
, - also add the same dependency (without
<version>
because it is already assigned in step 1) in the plugin<configuration><aspectLibraries>
section as an<aspectLibrary>
.
Here is a concrete example:
Aspect library POM, marker annotation and sample aspect:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.scrum-master.stackoverflow</groupId>
<artifactId>aspectj-lib</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>AspectJ Library</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.source-target.version>1.8</java.source-target.version>
<aspectj.version>1.8.7</aspectj.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<!-- IMPORTANT -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</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> -->
<!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn> -->
</configuration>
<executions>
<execution>
<!-- IMPORTANT -->
<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>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
-->
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
</dependencies>
<organization>
<name>Scrum-Master.de - Agile Project Management</name>
<url>http://scrum-master.de</url>
</organization>
</project>
package de.scrum_master.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Marker {}
package de.scrum_master.aspect;
public aspect MyAspect {
before() : execution(* *(..)) && @annotation(Marker) {
System.out.println(thisJoinPoint);
}
}
Now run mvn clean install
on the aspect library project so as to install the dependency into your local Maven repo.
Java application POM and sample application:
By the way, in the POM I have also added two optional plugins:
- One-JAR plugin packages your application with all dependencies (e.g. aspect library and AspectJ runtime) into one artifact, here
target/java-app-0.0.1-SNAPSHOT.one-jar.jar
. You can just run your application viajava -jar target/java-app-0.0.1-SNAPSHOT.one-jar.jar
. - Exec Maven plugin is useful if you easily want to test your application from the command line via
mvn clean install exec:java
.
These two are only for convenience, you do not need them if you dislike them.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.scrum-master.stackoverflow</groupId>
<artifactId>java-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Java Application</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.source-target.version>1.8</java.source-target.version>
<aspectj.version>1.8.7</aspectj.version>
<main-class>de.scrum_master.app.Application</main-class>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<!-- IMPORTANT -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</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> -->
<!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn> -->
<aspectLibraries>
<aspectLibrary>
<groupId>de.scrum-master.stackoverflow</groupId>
<artifactId>aspectj-lib</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<!-- IMPORTANT -->
<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>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>${main-class}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<onejarVersion>0.96</onejarVersion>
<mainClass>${main-class}</mainClass>
<attachToBuild>true</attachToBuild>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>${main-class}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<configuration>
<mainClass>${main-class}</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>OneJAR googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>de.scrum-master.stackoverflow</groupId>
<artifactId>aspectj-lib</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>de.scrum-master.stackoverflow</groupId>
<artifactId>aspectj-lib</artifactId>
</dependency>
</dependencies>
<organization>
<name>Scrum-Master.de - Agile Project Management</name>
<url>http://scrum-master.de</url>
</organization>
</project>
This little driver application demonstrates that you can now annotate methods with @Marker
, in this case only foo
and zot
, but not bar
:
package de.scrum_master.app;
import de.scrum_master.aspect.Marker;
public class Application {
@Marker
public static void foo() {}
public static void bar() {}
@Marker
public static void zot() {}
public static void main(String[] args) {
foo();
bar();
zot();
}
}
Console log:
java -jar target/java-app-0.0.1-SNAPSHOT.one-jar.jar
execution(void de.scrum_master.app.Application.foo())
execution(void de.scrum_master.app.Application.zot())

- 63,017
- 15
- 111
- 202
-
This approach is not working for me..because I need to first execute maven plugin and then aspectJ compilation changes. How do I achieve that? Maven-compiler-plugin is coming from parent project and aspectJ is part of spring-data artifacts. I dont know how can i order them in my pom file. Please advice. – coretechie Feb 08 '17 at 11:02
-
Thank you kind sir - I have seen a few of your replies in various Maven - AspectJ related questions here on SO and each has helped me out of a rut. Your knowledge of maven configuration is impressive! The only issue I have now is; IntelliJ underling my dependency (the one I have created and utilising AspectJ) in the Maven Projects Tool window with red to suggest error (without any info) but everything compiles and runs just fine... so perhaps a cosmetic issue with IntelliJ? – Psyrus Sep 05 '17 at 22:55
-
Ah OK, disregard, it was due to duplicate AspectJ dependencies - declared both in the pom of my dependency that utilises AspectJ and also in the pom for the Java Application that depends on it. Removed the dependency declarations from the latter and IntelliJ is happy (which makes sense). – Psyrus Sep 05 '17 at 23:09
-
1@Psyrus: Attention! Never rely on a transitive dependency from one of your libraries, always declare your own dependencies as needed. Use dependency management in order to make sure that there is no version conflict. You can use `mvn dependency:analyze` in order to list used undeclared dependencies, but also in order to find the less dangerous (only bloat) unused declared ones. – kriegaex Sep 06 '17 at 00:52
-
Thank you once again! Now **that** makes sense. I was unclear about the "management" variants of certain maven tags. I am not happy with my understanding of maven capabilities, I think I will need to set aside some study time before long... In any event, your advice is much appreciated! – Psyrus Sep 06 '17 at 19:18
-
Oh and just to confirm, yes, you were completely correct, I had skipped the "management" variants, due to a lack of understanding... but not so much any more :) – Psyrus Sep 06 '17 at 20:00
-
how to add aspectLibraries in gradle ? – Adams.H Mar 09 '19 at 05:19
-
Jason, your question is off-topic. – kriegaex Mar 09 '19 at 12:53
-
Thank you very much! Saved a lot of time. – sys463 Aug 15 '19 at 09:59
Here is a short summary of krigaex's answer. Add your library as a normal dependency and as an AspectJ plugin dependency to pom.xml
. If you use com.nickwongdev:aspectj-maven-plugin
- use <weaveDependencies>
& <weaveDependency>
tags instead of <aspectLibraries>
& <aspectLibrary>
:
<project>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-library</artifactId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>com.nickwongdev</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.12.6</version>
<configuration>
<weaveDependencies>
<weaveDependency>
<groupId>com.example</groupId>
<artifactId>my-library</artifactId>
</weaveDependency>
</weaveDependencies>
</configuration>
</plugin>
</plugins>
</build>
</project>

- 18,610
- 7
- 91
- 99