I'm using aspectj to target methods using a third-party annotation. However, I can't guarantee that this annotation will be available on the classpath. Is there a way to target an annotation from an optional dependency?
As an example, I might want to target JUnit 5's @ParameterizedTest
annotation. My .aj file would look something like this:
public aspect Example {
pointcut beforeTest(): @annotation(ParamterizedTest);
before(): beforeTest() {
System.out.println("This is a Parameterized Test!");
}
}
However, if my project is using JUnit 4, or doesn't include the junit-jupiter-params library, then Maven will fail to weave since it can't find the class:
2019-02-04 16:37:37.649 [ERROR] Failed to execute goal org.codehaus.mojo:aspectj-maven-plugin:1.11:test-compile (default) on project ExampleProject: AJC compiler errors:
2019-02-04 16:37:37.650 [ERROR] error at (no source information available)
2019-02-04 16:37:37.656 [ERROR] /jenkins/workspace/exampleProject/src/test/java/com/example/ExampleTest.java:0::0 can't determine annotations of missing type org.junit.jupiter.params.ParameterizedTest
2019-02-04 16:37:37.657 [ERROR] when weaving type com.example.ExampleTest
2019-02-04 16:37:37.657 [ERROR] when weaving classes
2019-02-04 16:37:37.657 [ERROR] when weaving
2019-02-04 16:37:37.658 [ERROR] when batch building BuildConfig[null] #Files=21 AopXmls=#0
2019-02-04 16:37:37.658 [ERROR] [Xlint:cantFindType]
I've tried adding the library to the aspectj-maven-plugin
's <dependencies>
section like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<aspectLibraries>
<aspectLibrary>
<groupId>com.example</groupId>
<artifactId>example-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.1.1</version>
</dependency>
</dependencies>
</plugin>
... but that makes no difference.
Is there a way to make this work without requiring the addition of the dependency? Pretty much I want the pointcut to work if there is a method annotated with the third-party annotation, if present, and to be ignored otherwise.
(For the purposes of the junit example, which I built out to confirm it works the same as my real problem, my aspect library does declare the dependency on junit-jupiter-params.)