我遇到了与aspectj-maven-plugin和Eclipse Juno的奇怪问题。我在我的pom的构建部分中有以下插件定义:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>1.7</source>
<target>1.7</target>
<Xlint>ignore</Xlint>
<complianceLevel>1.7</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
我在src / test / java / ...文件夹中声明了@Aspect
。
如果我是从命令行构建的(即:mvn clean package),我的类是按照预期正确构建的。
但是,当我在Eclipse中构建时,在我的测试文件夹中声明的方面被编织到我的输出类文件夹.class文件中,而不是test-classes文件夹(通过使用反编译器确认)。
我的配置不正确吗?我的Eclipse项目中是否缺少一个设置来指示在编译时忽略方面?如果我在Eclipse中检查我的Java Build path配置,我会看到src / main / java - &gt;目标/类,而src / test / java-&gt;目标/测试类。
这可能与配置的生命周期映射有关吗? 我有:
Plugin Extension Mapping Source
aspectj:compile configurator extension
aspectj:test-compile configurator extension
我安装了AJDT 1.7.3(org.aspectj)和2.2.3(org.eclipse.ajdt)(我不确定为什么安装了这两个版本)。
更新2
我将Aspectj-maven-plugin配置更新为以下内容并覆盖m2e连接器设置并且它似乎有效,但我希望第三方验证如果这适用于其他人,因为它似乎是编辑器/配置依赖。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sources>
<source>
<basedir>${project.build.sourceDirectory}</basedir>
<includes>
<include>**/*.aj</include>
<include>**/*.java</include>
</includes>
</source>
</sources>
</configuration>
</execution>
<execution>
<id>test compile</id>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sources>
<source>
<basedir>${project.build.testSourceDirectory}</basedir>
<includes>
<include>**/*.aj</include>
<include>**/*.java</include>
</includes>
</source>
</sources>
<weaveDirectories>
<param>${project.build.outputDirectory}</param>
</weaveDirectories>
</configuration>
</execution>
</executions>
<configuration>
<verbose>true</verbose>
<outxml>true</outxml>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<source>${java.version}</source>
<target>${java.version}</target>
<complianceLevel>${java.version}</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
</configuration>
</plugin>
使用以下m2e配置覆盖AJDT / m2e 0.14框架附带的m2e连接器设置: org.eclipse.m2e 生命周期映射 1.0.0 org.codehaus.mojo AspectJ的Maven的插件 [1.7,) 编 org.codehaus.mojo AspectJ的Maven的插件 [1.7,) 测试编译
如果这对其他人有用,下一步是尝试了解m2e连接器如何/为何失败,以及需要修复的位置。
我将测试代码(包括@kriegaex测试项目)上传到我的github示例项目:github.com/benze/aspectj-maven-plugin-defect-example.git。根据自述文件,要启用/禁用覆盖m2e-connector,请启用override-m2e-lifecycle配置文件。
答案 0 :(得分:1)
我刚刚尝试在AspectJ users mailing list上回答您的问题,并在此处找到了相同的问题。至于这一部分,......
我安装了AJDT 1.7.3(org.aspectj)和2.2.3(org.eclipse.ajdt)(我不确定为什么安装了这两个版本)。
前者似乎适用于实际的AspectJ(编译器和运行时)版本,在我的Eclipse Luna中它是1.8.5。后者适用于AJDT插件组件,在我的IDE中它是2.2.4。
<强>更新强>
你关于M2Eclipse生命周期映射的假设(另见你的new mailing list post) - 这是我以前从未听说过的,但只是第一次调查 - 是其中的根本原因问题似乎是真的。
抱歉,这不起作用,请参阅下面的更新2.
阅读this并查看我安装的m2e插件中的默认生命周期映射
<eclipse-dir>/plugins/org.eclipse.m2e.lifecyclemapping.defaults_1.5.0.20140606-0033.jar
-> lifecycle-mapping-metadata.xml
我意识到AspectJ Maven插件没有默认映射。所以我刚创建了一个菜单选项
Window -> Preferences
Maven -> Lifecycle Mappings
具有以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<lifecycleMappingMetadata>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
这解决了我在Eclipse安装中的问题(我可以在我自己的小型演示项目中重现)。
我认为从M2Eclipse中提供AspectJ Maven插件的默认映射(有人应该打开票证,我猜)或者甚至直接在AspectJ Maven插件中通过在插件中提供默认映射工具来提供默认映射(其中根据M2E文件据说是可能的。)
这是我的示例项目:
Maven项目POM:
<?xml version="1.0" encoding="UTF-8"?>
<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.aspectj</groupId>
<artifactId>unit-test-specific-aspect</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<aspectj.version>1.8.6</aspectj.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java.version}</source>
<target>${java.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.version}</source>
<target>${java.version}</target>
<Xlint>ignore</Xlint>
<complianceLevel>${java.version}</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<id>compile</id>
<!-- IMPORTANT -->
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<!-- IMPORTANT -->
<phase>process-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<weaveDirectories>
<param>${project.build.outputDirectory}</param>
</weaveDirectories>
</configuration>
</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.3</version>
<configuration>
<mainClass>de.scrum_master.app.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
驱动程序应用程序:
package de.scrum_master.app;
public class Application {
public static void main(String... args) {
System.out.println("Hello world!");
}
}
单元测试:
package de.scrum_master.app;
import org.junit.Test;
import static org.junit.Assert.*;
public class ApplicationTest {
@Test
public void testMain() throws Exception {
Application.main("foo");
}
@Test
public void testOne() throws Exception {
System.out.println("Test one");
}
@Test
public void testTwo() throws Exception {
System.out.println("Test two");
}
}
测试方面(位于 src / test / java ):
package de.scrum_master.app;
public aspect TestAspect {
before() : execution(* *(..)) {
System.out.println(thisJoinPoint);
}
}
mvn clean package exec:java
的控制台输出:
[INFO] ------------------------------------------------------------------------
[INFO] Building unit-test-specific-aspect 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(...)
[INFO] --- aspectj-maven-plugin:1.7:compile (compile) @ unit-test-specific-aspect ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[INFO]
[INFO] --- aspectj-maven-plugin:1.7:test-compile (test-compile) @ unit-test-specific-aspect ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[INFO] Join point 'method-execution(void de.scrum_master.app.Application.main(java.lang.String[]))' in Type 'de.scrum_master.app.Application' (Application.java:4) advised by before advice from 'de.scrum_master.app.TestAspect' (TestAspect.aj:4)
[INFO] Join point 'method-execution(void de.scrum_master.app.ApplicationTest.testMain())' in Type 'de.scrum_master.app.ApplicationTest' (ApplicationTest.java:9) advised by before advice from 'de.scrum_master.app.TestAspect' (TestAspect.aj:4)
[INFO] Join point 'method-execution(void de.scrum_master.app.ApplicationTest.testOne())' in Type 'de.scrum_master.app.ApplicationTest' (ApplicationTest.java:14) advised by before advice from 'de.scrum_master.app.TestAspect' (TestAspect.aj:4)
[INFO] Join point 'method-execution(void de.scrum_master.app.ApplicationTest.testTwo())' in Type 'de.scrum_master.app.ApplicationTest' (ApplicationTest.java:19) advised by before advice from 'de.scrum_master.app.TestAspect' (TestAspect.aj:4)
(...)
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running de.scrum_master.app.ApplicationTest
execution(void de.scrum_master.app.ApplicationTest.testOne())
Test one
execution(void de.scrum_master.app.ApplicationTest.testTwo())
Test two
execution(void de.scrum_master.app.ApplicationTest.testMain())
execution(void de.scrum_master.app.Application.main(String[]))
Hello world!
(...)
[INFO] --- exec-maven-plugin:1.3:java (default-cli) @ unit-test-specific-aspect ---
[WARNING] Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6.
Hello world!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
(...)
所以它在Maven中起作用,就像之前一样。但是如何通过正常运行配置从Eclipse运行代码呢?
Hello world!
没有方面,很酷!那么Eclipse中的单元测试呢?
execution(void de.scrum_master.app.ApplicationTest.testOne())
Test one
execution(void de.scrum_master.app.ApplicationTest.testTwo())
Test two
execution(void de.scrum_master.app.ApplicationTest.testMain())
execution(void de.scrum_master.app.Application.main(String[]))
Hello world!
Tadaa,方面被编织成Application.main
。 Eclipse和Maven都可以按照我们的要求运行。
更新2:
我很抱歉,它只是起作用,因为我在Maven构建之后没有完成完整的Eclipse重建。显然,生命周期映射还不够,甚至可能不是解决方案的正确途径。我想,Eclipse只是不知道AspectJ Maven插件中的<weaveDirectories>
设置,这是一件非常重要的事情。