开发者

Maven: compile aspectj project containing Java 1.6 source

Primary Question

What I want to do is fairly easy. Or so you would think. However, nothing is working properly.

Requirement: Using maven, compile Java 1.6 project using AspectJ compiler.

Note: Our code cannot compile with javac. That is, it fails compilation if aspects are not woven in (because we have aspects that soften exceptions).


Update 2/21/2011: There are two equally viable solutions to this (both cases use the aspectj-maven-plugin in conjuction with the maven-compiler-plugin):

  1. Add <failOnError>false</failOnError> to the compiler plugin (thanks Pascal Thivent)
  2. Add <phase>process-sources</phase> to the aspectj compiler plugin (thanks Andrew Swan)

More info on these solutions is in the answer section. I believe solution #2 is the better approach.


Related Questions

Questions (based on failed attempts below):

  1. How do you get maven to run the aspectj:compile goal directly, without ever running compile:compile?
  2. How do you ignore the failure of compile:compile?
  3. How do you specify a custom compilerId that points to your own ajc compiler (that is make compile:compile use an aspectj compiler other than the plexus one)?*
Thanks for any and all suggestions. These are the things I've tried that have led to my problem/questions:


Attempt 1 (fail): Specify aspectJ as the compiler for the 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>

This fails with the error:

org.codehaus.plexus.compiler.CompilerException: The source version was not recognized: 1.6

No matter what version of the plexus compiler I use (1.8, 1.6, 1.3, etc), this doesn't work. I actually read through the source code and found that this compiler does not like source code above Java 1.5.

Attempt 2 (fail): Use the aspectJ-maven-plugin attached to the compile and test-compile goals:

<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>compil开发者_Python百科e</goal>      
   <goal>test-compile</goal> 
  </goals>
 </execution>
</executions>
</plugin>

This fails when running either:

mvn clean test-compile

mvn clean compile

because it attempts to execute compile:compile before running aspectj:compile. As noted above, our code doesn't compile with javac--the aspects are required. So mvn would need to skip the compile:compile goal altogether and run only aspectj:compile.

Attempt 3 (works but unnacceptable):

Use the same configuration above but instead run:

mvn clean aspectj:compile

This works, in that it builds successfully but it's unacceptable in that we need to be able to run the compile goal and the test-compile goal directly (m2eclipse auto-build depends on those goals). Moreover, running it this way would require that we spell out every goal we want along the way (for instance, we need resources distributed and tests to be run and test resources deployed, etc)


Version 1.3 of the AspectJ plugin deliberately changed the default phase of its compile goal from process-sources to compile, see MASPECTJ-13. This causes follow-up problems like yours or MASPECTJ-92. To restore the previous behaviour of running ajc before javac, you just need to add a "phase" tag to the relevant "execution" tag, like this:

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


How about telling maven-compiler-plugin to skip all *.java files and let aspectj-maven-plugin do the job ?

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


I used this configuration in a project to compile AspectJ and Java 6 using 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>

Ref: aspectj-maven-plugin


How do you specify a custom compilerId that points to your own ajc compiler (that is make compile:compile use an aspectj compiler other than the plexus one)?

I don't know how to specify another compilerId than the "official" ones. Not sure it's possible.

My understanding is that http://jira.codehaus.org/browse/MCOMPILER-107 would solve your problem (AspectJ 1.6+ does support Java 1. 6 right?). Sadly, it's still open.

How do you ignore the failure of compile:compile?

The compiler:compile goal of the Maven Compiler plugin has a failOnError optional parameter allowing to Indicate whether the build will continue even if there are compilation errors.

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <failOnError>false</failOnError>
          ...
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

This could be a ugly workaround to the above problem.

How do you get maven to run the aspectj:compile goal directly, without ever running compile:compile?

The problem is that compiler:compile is bound to the compile phase and that you can't remove a default lifecyle binding. So there is maybe another option but the only one I can think of would be to turn everything off by using a <packaging>pom<packaging> and to rebind all the goals manually (at least for these phases: process-resources, compile, process-test-resources, test-compile, test, package). Schematically, something like this:

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

That could be another ugly workaround. Disclaimer: not tested but should work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜