Maven: проект compile aspectj, содержащий исходный код Java 1.6
Основной вопрос
То, что я хочу сделать, довольно легко. Или так вы думаете. Тем не менее, ничего не работает должным образом.
Требование: Используя maven, скомпилируйте проект Java 1.6 с помощью компилятора AspectJ.
Примечание. Наш код не может быть скомпилирован с помощью javac. То есть компиляция не выполняется, если аспекты не вплетены (потому что у нас есть аспекты, которые смягчают исключения).
Обновление 21.02.2011: Есть два одинаково жизнеспособных решения для этого (оба случая используют аспект j-maven-плагин в сочетании с плагином maven-compiler-plugin):
- добавлять
<failOnError>false</failOnError>
к плагину компилятора (спасибо Pascal Thivent) - добавлять
<phase>process-sources</phase>
в плагин компилятора aspectj (спасибо Andrew Swan)
Более подробная информация об этих решениях находится в разделе ответов. Я считаю, что решение № 2 - лучший подход.
Смежные вопросы
Вопросы (основанные на неудачных попытках ниже):
- Как заставить maven запускать аспект aspectj: compile напрямую, без запуска compile: compile?
- Как вы игнорируете сбой компиляции: компиляция?
- Как указать собственный compilerId, который указывает на ваш собственный ajc-компилятор (то есть make compile: compile использует компилятор aspectj, отличный от plexus)?*
Попытка 1 (ошибка): укажите аспект J в качестве компилятора для подключаемого модуля maven-compiler:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerId>aspectj</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-aspectj</artifactId>
<version>1.8</version>
</dependency>
</dependencies>
</plugin>
Это терпит неудачу с ошибкой:
org.codehaus.plexus.compiler.CompilerException: The source version was not recognized: 1.6
Независимо от того, какую версию компилятора plexus я использую (1.8, 1.6, 1.3 и т. Д.), Это не сработает. Я на самом деле прочитал исходный код и обнаружил, что этот компилятор не любит исходный код выше Java 1.5.
Попытка 2 (неудача): Используйте аспект aspectJ-maven-plugin, прикрепленный к целям компиляции и тест-компиляции:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
Это не работает при запуске:
mvn clean test-compile
mvn clean compile
потому что он пытается выполнить compile: compile перед запуском aspectj:compile. Как отмечалось выше, наш код не компилируется с javac - аспекты обязательны. Поэтому mvn нужно вообще пропустить цель compile: compile и запустить только aspectj:compile.
Попытка 3 (работает, но неприемлемо):
Используйте ту же конфигурацию выше, но вместо этого запустите:
mvn clean aspectj:compile
Это работает в том смысле, что он успешно собирается, но недопустимо в том смысле, что мы должны иметь возможность напрямую запускать цель компиляции и цель тест-компиляции (автоматическая сборка m2eclipse зависит от этих целей). Более того, для его выполнения потребуется, чтобы мы указали все цели, которые нам нужны (например, нам нужны распределенные ресурсы и тесты, которые нужно запустить, а ресурсы развернуты и т. Д.)
4 ответа
Версия 1.3 плагина AspectJ намеренно изменила фазу по умолчанию для своей цели компиляции с "process-sources" на "compile". Чтобы восстановить предыдущее поведение запуска ajc перед javac, вам просто нужно добавить тег "phase" к соответствующему тегу "execute", например:
<execution>
<phase>process-sources</phase> <!-- or any phase before compile -->
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
Как насчет того, чтобы сказать maven-compiler-plugin, чтобы он пропускал все файлы *.java и позволял aspectj-maven-plugin делать свою работу?
...
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>utf-8</encoding>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal> <!-- weave main classes -->
<goal>test-compile</goal> <!-- weave test classes -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Я использовал эту конфигурацию в проекте для компиляции AspectJ и Java 6 с использованием Maven:
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Ссылка: aspectj-maven-plugin
Как указать пользовательский compilerId, который указывает на ваш собственный ajc-компилятор (то есть make compile:compile использует компилятор aspectj, отличный от plexus)?
Я не знаю, как указать другое compilerId
чем "официальные". Не уверен, что это возможно.
Насколько я понимаю, http://jira.codehaus.org/browse/MCOMPILER-107 решит вашу проблему (AspectJ 1.6+ поддерживает Java 1. 6, верно?). К сожалению, это все еще открыто.
Как вы игнорируете сбой компиляции: компиляция?
compiler:compile
цель плагина Maven Compiler имеет failOnError
необязательный параметр, позволяющий указать, будет ли сборка продолжаться даже при наличии ошибок компиляции.
<project>
...
<build>
...
<plugins>
...
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.2</version>
<configuration>
<failOnError>false</failOnError>
...
</configuration>
</plugin>
</plugins>
</build>
</project>
Это может быть уродливым решением этой проблемы.
Как заставить maven запускать аспект aspectj: compile напрямую, без запуска compile:compile?
Проблема в том, что compiler:compile
связан с compile
фаза и что вы не можете удалить привязку жизненного цикла по умолчанию. Так что, возможно, есть и другой вариант, но я могу думать только о том, чтобы отключить все, используя <packaging>pom<packaging>
и заново связать все цели вручную (по крайней мере, для следующих этапов: process-resources
, compile
, process-test-resources
, test-compile
, test
, package
). Схематично примерно так:
ресурсы процесса ресурсы: ресурсы compile aspectj:compile ресурсы процесса-теста-ресурсов:testResources Компилятор тест-компиляции:testCompile тест верный: тест пакет ejb:ejb или ejb3:ejb3 или jar:jar или par: par или rar: rar или war: war установить установить: установить Развернуть Развернуть: развернуть
Это может быть еще один уродливый обходной путь. Отказ от ответственности: не проверено, но должно работать.