Maven: скомпилируйте проект aspectj, содержащий источник Java 1.6
Основной вопрос
То, что я хочу сделать, довольно просто. Или так вы думаете. Однако ничего не работает должным образом.
Требования:
Используя maven, скомпилируйте проект Java 1.6 с использованием компилятора AspectJ.
Примечание:
Наш код не может компилироваться с помощью javac. То есть, он не компилируется, если аспекты не сплетены (потому что у нас есть аспекты, которые смягчают исключения).
Обновление 2/21/2011:
Есть два одинаково жизнеспособных решения для этого (оба случая используют плагин aspectj-maven в сочетании с плагином maven-compiler):
- Добавить
<failOnError>false</failOnError>
к плагину компилятора (спасибо Pascal Thivent)
- Добавить
<phase>process-sources</phase>
к плагину компилятора aspectj (спасибо Эндрю Лебедь)
Дополнительная информация об этих решениях содержится в разделе ответов. Я считаю, что решение №2 - лучший подход.
Вопросы, относящиеся
Вопросы (основанные на неудачных попытках ниже):
- Как вы получаете maven для запуска aspectj: компилировать цель напрямую, без выполнения компиляции: компилировать?
- Как игнорировать сбой компиляции: компилировать?
- Как вы указываете пользовательский компилятор, который указывает на ваш собственный компилятор ajc (то есть make compile: компиляция использует компилятор aspectj, отличный от сплетения)? *
Спасибо за любые предложения. Это те вещи, которые я пробовал, которые привели к моей проблеме/вопросам:
Попытка 1 (сбой):
Укажите aspectJ как компилятор для maven-compiler-plugin:
<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
Независимо от того, какую версию компилятора сплетения я использую (1,8, 1,6, 1,3 и т.д.), это не работает. Я действительно прочитал исходный код и обнаружил, что этот компилятор не любит исходный код выше Java 1.5.
Попытка 2 (сбой):
Используйте плагин aspectJ-maven, прикрепленный к целям компиляции и тестирования:
<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
потому что он пытается выполнить компиляцию: скомпилируйте перед запуском aspectj: compile. Как отмечено выше, наш код не компилируется с помощью javac - эти аспекты необходимы. Поэтому mvn нужно будет пропустить компиляцию: компилировать цель целиком и запускать только aspectj: компилировать.
Попытка 3 (работает, но неприемлема):
Используйте ту же конфигурацию выше, но вместо этого запустите:
mvn clean aspectj:compile
Это работает, потому что он строит успешно, но это неприемлемо в том смысле, что нам нужно иметь возможность запускать цель компиляции и цель тестовой компиляции напрямую (автоматическая сборка m2eclipse зависит от этих целей). Более того, запуск этого метода потребует, чтобы мы заявляли о каждой цели, которую мы хотим на этом пути (например, нам нужны распределенные ресурсы и тесты, которые нужно запустить, и тестовые ресурсы развернуты и т.д.)
Ответы
Ответ 1
Версия 1.3 плагина AspectJ намеренно изменила фазу по умолчанию своей цели компиляции из "процессов-источников" для "компиляции". Чтобы восстановить предыдущее поведение запуска ajc перед javac, вам просто нужно добавить тег "фаза" в соответствующий тег "выполнение", например:
<execution>
<phase>process-sources</phase> <!-- or any phase before compile -->
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
Ответ 2
Как насчет того, чтобы сообщать maven-компилятор-плагин пропустить все *.java файлы и позволить аспект-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>
Ответ 3
Я использовал эту конфигурацию в проекте для компиляции 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
Ответ 4
Как вы указываете пользовательский компилятор, который указывает на ваш собственный компилятор ajc (то есть make compile: компиляция использует компилятор aspectj, отличный от сплетения)?
Я не знаю, как указать другой compilerId
, чем "official" . Не уверен, что это возможно.
Я понимаю, что 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: компилировать цель напрямую, без выполнения компиляции: компилировать?
Проблема заключается в том, что compiler:compile
привязан к фазе compile
и что вы не можете удалить привязка lifecyle по умолчанию. Таким образом, возможно, есть и другой вариант, но единственный, о котором я могу думать, - это отключить все, используя <packaging>pom<packaging>
и восстановить все цели вручную (по крайней мере для этих фаз: process-resources
, compile
, process-test-resources
, test-compile
, test
, package
). Схематически, что-то вроде этого:
process-resources resources:resources
compile aspectj:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
install install:install
deploy deploy:deploy
Это может быть еще один уродливый обходной путь. Отказ от ответственности: не проверен, но должен работать.