【问题标题】:Maven: compile aspectj project containing Java 1.6 sourceMaven:编译包含 Java 1.6 源代码的 aspectj 项目
【发布时间】:2011-02-06 07:50:36
【问题描述】:

主要问题

我想做的事情相当简单。或者你会这么想。但是,没有任何工作正常。

要求: 使用maven,使用AspectJ编译器编译Java 1.6项目。

注意: 我们的代码不能用 javac 编译。也就是说,如果没有编织切面(因为我们有软化异常的切面),它会导致编译失败。


2011 年 2 月 21 日更新: 有两种同样可行的解决方案(两种情况都使用 aspectj-maven-pluginmaven-compiler-plugin):

  • 添加 <failOnError>false</failOnError> 到编译器插件(谢谢 Pascal Thivent)
  • 添加<phase>process-sources</phase> 到aspectj编译器插件 (感谢Andrew Swan
  • 关于这些解决方案的更多信息在答案部分。我相信解决方案 #2 是更好的方法。







    相关问题

    问题(基于以下失败的尝试):

    1. 如何让 maven 直接运行 aspectj:compile 目标,而无需运行 compile:compile?
    2. 如何忽略compile:compile的失败?
    3. 如何指定指向您自己的 ajc 编译器的自定义 compilerId(即 make compile:compile 使用除 plexus 之外的 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

    无论我使用什么版本的 plexus 编译器(1.8、1.6、1.3 等),这都不起作用。我其实通读了源码,发现这个编译器不喜欢Java 1.5以上的源码。

    尝试 2(失败): 使用附加到 compile 和 test-compile 目标的 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

    因为它会在运行 aspectj:compile 之前尝试执行 compile:compile。如上所述,我们的代码不能用 javac 编译——这些方面是必需的。所以 mvn 需要完全跳过 compile:compile 目标,只运行 aspectj:compile。

    尝试 3(有效但不可接受):

    使用与上述相同的配置,但改为运行:

    mvn clean aspectj:compile

    这很有效,因为它可以成功构建,但它是不可接受的,因为我们需要能够直接运行 compile 目标和 test-compile 目标(m2eclipse 自动构建取决于这些目标)。此外,以这种方式运行它需要我们在此过程中阐明我们想要的每一个目标(例如,我们需要分发资源、运行测试和部署测试资源等)

    【问题讨论】:

    标签: java maven-2 aop aspectj


    【解决方案1】:

    AspectJ 插件的 1.3 版故意将其编译目标的默认阶段从 process-sources 更改为 compile,请参阅 MASPECTJ-13。这会导致像您或MASPECTJ-92 这样的后续问题。要恢复之前在javac之前运行ajc的行为,只需要在相关的“execution”标签上加一个“phase”标签,像这样:

    <execution>
        <phase>process-sources</phase> <!-- or any phase before compile -->
        <goals>
            <goal>compile</goal>
            <goal>test-compile</goal>
        </goals>
    </execution>
    

    【讨论】:

    • 感谢发帖!尽管我大约在一年前发布了这个问题,并且与最初出现问题的项目相去甚远(我们已经从 Maven 切换到 Ivy!),但我认为您的解决方案可能会奏效。有机会我会搭建一个测试环境试试看!
    • 您的解决方案完美运行。我还查看了您链接的讨论,我倾向于同意您的看法,他们所做的更改似乎比帮助更有问题。起初,我认为绑定到 process-sources 阶段“有点小题大做”,但经过更多思考,这完全有道理——AspectJ 在编译之前编织源代码!我正在更改我接受的答案,因为我认为这是一种更好的方法。
    【解决方案2】:

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

    【讨论】:

    • 我已经有一段时间没有研究这个问题了,但我认为你在这里写的内容是一个很好的选择,可以完全解决它。我必须对其进行测试以确保调用“mvn compile”仍会调用 aspectj 编译器。此外,我必须检查从编译器插件中排除 java 文件是否不会间接地将它们从 aspectJ 编译中排除。我们目前正在研究该项目的另一个领域,但下次我打开中间件代码时,我会测试您的建议。谢谢!我认为它会起作用。
    • 我在我的 maven 模块中尝试过,它成功了。虽然最终因为其他原因放弃了排除这种情况。我的项目使用了国家字符,而 aspectj-maven-plugin 似乎搞乱了编码。所以最后我重构了模块,没有从 java 到 aj 的引用。 Javac 编译 .java,然后 AspectJ 编译缺少的 .aj 文件。到目前为止工作就像一个魅力。
    • 您是否尝试将插件的“编码”选项设置为您想要的值?见mojo.codehaus.org/aspectj-maven-plugin/apidocs/org/codehaus/…
    • @gmale: "mvn compile" 调用编译阶段,它首先调用 "maven-compiler-plugin" 插件的 "compile" 目标,然后是绑定到该插件的任何其他插件的目标阶段(默认情况下包括 aspectj-maven-plugin 的编译和测试编译目标),所以是的,它仍然会调用 AspectJ 编译器,除非您在该插件的“执行”标签上添加了一个“阶段”标签来绑定它进入不同的阶段。
    【解决方案3】:

    我在一个项目中使用了这个配置来使用 Maven 编译 AspectJ 和 Java 6:

    <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

    【讨论】:

    • 这不会在compiler:compile之前调用aspectj:compile
    • 您的合规级别为 1.6。这是我唯一没有尝试过的事情,但正如 Pascal 提到的,我认为这不会解决我的问题,因为 compile:compile 仍然首先发生。我想知道是否有办法忽略 compile:compile 的失败...嗯,我会在上面的问题中添加它。
    • 如果您关闭 IDE(排除自动构建)并执行“mvn clean”然后执行“mvn install”,这是否有效?你的项目是如何打包的?我的 EAR 项目与您的类似,但无法编译。您的 Java 代码是否依赖于 AspectJ 代码,例如调用 ITD 引入的任何方法?
    【解决方案4】:

    您如何指定指向您自己的 ajc 编译器的自定义 compilerId(即 make compile:compile 使用除了 plexus 之外的 aspectj 编译器)?

    我不知道如何指定另一个compilerId 而不是"official"。不确定这是否可能。

    我的理解是http://jira.codehaus.org/browse/MCOMPILER-107 可以解决您的问题(AspectJ 1.6+ 确实支持 Java 1. 6 对吗?)。遗憾的是,它仍然开放。

    如何忽略compile:compile的失败?

    Maven Compiler plugincompiler:compile 目标有一个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 阶段,并且您无法删除 default lifecyle binding。因此,也许还有另一种选择,但我唯一能想到的就是使用&lt;packaging&gt;pom&lt;packaging&gt; 关闭所有功能并手动重新绑定所有目标(至少对于这些阶段:process-resourcescompileprocess-test-resourcestest-compiletestpackage)。示意图如下:

    流程资源资源:资源 编译方面j:编译 流程测试资源资源:testResources 测试编译器:testCompile 测试万无一失:测试 包 ejb:ejb 或 ejb3:ejb3 或 jar:jar 或 par:par 或 rar:rar 或 war:war 安装安装:安装 部署部署:部署

    这可能是另一个丑陋的解决方法。免责声明:未经测试,但应该可以工作。

    【讨论】:

    • 是的。这真的很烦人。我应该可以说“compile:compile”被替换为“aspectJ:compile”。我可以使用 设置那种做到这一点。唯一的问题是当我将“aspectJ”命名为 compilerId 时,它使用不支持 java 1.6 的 plexus 版本而不是 aspectj 插件。我不知道你可以通过 pom 包装完全重新定义阶段!这是非常好的信息,+1!当然,在此之前,我只需使用上面的解决方案#3 并在我的 Eclipse 运行配置中说明我的所有目标。我只是想知道解决这个问题的所谓“约定”是什么
    • 非常感谢您的额外帮助。当我今天有更多时间时,我将投票赞成那个 codehaus 错误。很遗憾,他们的默认方面编译器不支持 3 年前发布的 java 1.6!今天晚些时候,我可能最终会尝试使用 failOnError 解决方法,因为由于 javac 编译器认为未检查的软化异常,编译会迅速而安静地失败。这似乎是所有弊端中较小的一个,并且可能是 codehaus/java1.6 问题的“官方”解决方法。
    • 当然,这只是当代码没有被编织的方面无法编译时才会出现的问题。但是,在使用 AspectJ 时可能经常发生。
    • @gmale 是的,我明白这一点。但这确实是一个非常有效的用例。
    猜你喜欢
    • 2014-03-09
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多