Aspectj pointcut аннотация таргетинга от необязательной зависимости
Я использую aspectj, чтобы предназначаться для методов, используя стороннюю аннотацию. Однако я не могу гарантировать, что эта аннотация будет доступна на пути к классам. Есть ли способ нацелить аннотацию из необязательной зависимости?
В качестве примера я мог бы нацелиться на JUnit 5 @ParameterizedTest
аннотаций. Мой файл.aj будет выглядеть примерно так:
public aspect Example {
pointcut beforeTest(): @annotation(ParamterizedTest);
before(): beforeTest() {
System.out.println("This is a Parameterized Test!");
}
}
Однако, если мой проект использует JUnit 4 или не включает библиотеку junit-jupiter-params, то Maven не сможет соткать, так как не может найти класс:
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]
Я пытался добавить библиотеку в aspectj-maven-plugin
"s <dependencies>
раздел, как это:
<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>
... но это не имеет значения.
Есть ли способ сделать эту работу, не требуя добавления зависимости? В значительной степени я хочу, чтобы pointcut работал, если есть метод, аннотированный сторонней аннотацией, если он есть, и игнорируемый в противном случае.
(Для целей примера junit, который я создал для подтверждения того, что он работает так же, как и моя настоящая проблема, моя библиотека аспектов объявляет зависимость от junit-jupiter-params.)
1 ответ
Ваш аспект использует класс, и хотя ваш пример кода не показывает его, должен быть импорт для него поверх вашего аспекта. Это означает, что это определенно зависимость, а не дополнительная зависимость для вашей библиотеки аспектов. Таким образом, вы должны определить это как таковое в Maven POM вашей библиотеки. Все остальное просто не имеет смысла. Что в этом такого большого? Правильное управление зависимостями - это то, для чего был создан Maven.
Обновление: спасибо за разъясняющий комментарий.
Вы можете использовать синтаксис на основе аннотаций вместо собственного синтаксиса, поскольку он не требует импорта. Pointcut просто не будет совпадать, как тогда будет показано другое предупреждение Xlint.
Если у вас есть возможность компилировать другие проекты с помощью компилятора AspectJ, я также рекомендую вам изучить @DeclareError
а также @DeclareWarning
, Это поможет вам обеспечить соблюдение политики не использовать параметризованные тесты во время компиляции вместо того, чтобы выдавать ошибки или регистрировать что-либо во время выполнения. Компилятор AspectJ просто не скомпилирует тесты, используя эту аннотацию.