0

我遇到了 aspectj-maven-plugin 和 Eclipse Juno 的一个奇怪问题。我的 pom 的构建部分中有以下插件 defn:

        <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>

@Aspect我在我的 src/test/java/... 文件夹中 有一个声明。

如果我从命令行构建(即:mvn clean package),我的类将正确/按预期构建。

但是,当我从 Eclipse 中构建时,我的测试文件夹中声明的方面被编织到我的输出类文件夹 .class 文件中,而不是 test-classes 文件夹(通过使用反编译器确认)。

我的配置不正确吗?我的 Eclipse 项目中是否缺少一个设置来指示在编译时忽略这些方面?如果我在 Eclipse 中检查我的 Java Build 路径配置,我会看到 src/main/java -> target/classes 而 src/test/java-> target/test-classes。

这可能与配置的生命周期映射有关吗?我有:

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 连接器设置,它似乎可以工作,但如果这适用于其他人,我希望进行第 3 方验证,因为它似乎依赖于编辑器/配置.

        <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-plugin [1.7,) 编译 org.codehaus.mojo aspectj-maven-plugin [1.7,) 测试编译

如果这对其他人有效,下一步是尝试了解 m2e 连接器如何/为何失败,以及需要修复的位置。

我将我的测试代码(包括@kriegaex 测试项目)上传到我的 github 示例项目:github.com/benze/aspectj-maven-plugin-defect-example.git。根据自述文件,要启用/禁用覆盖 m2e-connector,请启用 override-m2e-lifecycle 配置文件。

4

1 回答 1

1

我刚刚尝试在AspectJ 用户邮件列表上回答您的问题,并且在这里发现了同样的问题。至于这部分,...

我安装了 AJDT 1.7.3 (org.aspectj) 和 2.2.3 (org.eclipse.ajdt)(我不知道为什么它安装了这两个版本)。

前者似乎适用于实际的 AspectJ(编译器和运行时)版本,在我的 Eclipse Luna 中它是 1.8.5。后者适用于 AJDT 插件组件,在我的 IDE 中是 2.2.4。


更新:

您关于 M2Eclipse 生命周期映射的假设(另请参阅您的新邮件列表帖子)——我以前从未听说过,但只是第一次调查——作为问题的根本原因似乎是正确的。

抱歉,这实际上不起作用,请参阅下面的更新 2。

阅读本文并查看了我安装的 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

Eclipse m2e 生命周期映射菜单

内容如下:

<?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 安装中解决了您的问题(我可以在我自己的小演示项目中重现)。

我认为通过在插件中提供默认映射 wight(据说是根据 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 只是不知道<weaveDirectories>AspectJ Maven 插件中的设置,这是一个非常重要的修复。

于 2015-06-20T12:53:15.847 回答