views:

236

answers:

3

I am trying to add aspectj to a maven project using java 6.0. Browsing around I found 2 maven plugins, none of which works the way I would expect.

The first one http://mojo.codehaus.org/aspectj-maven-plugin did not work at first through netbeans because I could not get the code to compile 5.0 or later source (it complained about annotations etc.) After trying from command line which worked and comparing the commands executed it seems that its mavens install goal that is not compatible with the plugin and java 5+ code while the compile goal works fine. Although it may be possible to work around this it is annoying and brings me to the question: is the aspectj-maven-plugin still being developed? Should I still use it?

The second one is apaches's own which seems more active and more likely to work. I can however not find any complete examples and I am unable to run it. I keep getting an exception from maven:

java.lang.IllegalStateException: The plugin descriptor for the plugin Plugin [maven:maven-aspectj-plugin] was not found. Please verify that the plugin JAR /home/kristofer/.m2/repository/maven/maven-aspectj-plugin/4.0/maven-aspectj-plugin-4.0.jar is intact.

The jar file is there, intact and it also doesn't matter which version of the plugin I use, it always throws the same exception. Any ideas on what the problem might be?

In short, which plugin and how should I use it?

Thanks

+1  A: 

You can use the Maven Compiler plugin and change the compiler to use AspectJ.

The configuration looks like this :

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
        <compilerId>aspectj</compilerId>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-aspectj</artifactId>
            <version>1.6</version>
        </dependency>
    </dependencies>
</plugin>

Resources :

On the same topic :

Colin Hebert
I tried it but my aspects are not added to the classes. What is the default aspect folder? Can I specify it? I currently use src/main/aspect. Do .aj files get picked up?
Kristofer
If you want stuff oget copied out to the root source folder on build, put in src/main/resources
bwawok
Still they are not weaved in, I tried both src/main/java and src/main/resources
Kristofer
+3  A: 

Here is a setup that works for me (using the under documented aspectj-maven-plugin).

The project structure is as follow:

$ tree .
.
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── stackoverflow
    │               └── Q3651690
    │                   ├── App.java
    │                   └── DontWriteToTheConsole.aj
    └── test
        └── java
            └── com
                └── stackoverflow
                    └── Q3651690
                        └── AppTest.java

With the following little demo aspect:

public aspect DontWriteToTheConsole {

    pointcut sysOutOrErrAccess() : get(* System.out) || get(* System.err);

    declare error
      : sysOutOrErrAccess()
      : "Don't write to the console";

}

And the pom.xml is configured like this:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.stackoverflow.Q3651690</groupId>
  <artifactId>Q3651690</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Q3651690</name>
  <properties>
    <maven.compiler.source>1.6</maven.compiler.source>
    <maven.compiler.target>1.6</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.6.7</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.3</version>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal><!-- to weave all your main classes -->
              <goal>test-compile</goal><!-- to weave all your test classes -->
            </goals>
          </execution>
        </executions>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

The key parts are:

  • to configure the maven-compiler-plugin for 1.6 source level (this is done using the properties)
  • to configure the aspectj-maven-plugin for 1.6 source level (and I reused the properties used to configure the maven-compiler-plugin here)

The second step seems redundant but, well, that's how things are.

This way, I was able to weave code using annotations, etc:

$ mvn clean install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Q3651690
[INFO]    task-segment: [clean, install]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] [resources:resources {execution: default-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/pascal/Projects/stackoverflow/Q3651690/src/main/resources
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to /home/pascal/Projects/stackoverflow/Q3651690/target/classes
[INFO] [aspectj:compile {execution: default}]
[ERROR] Don't write to the console
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Compiler errors:
error at System.out.println( "Hello World!" );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/pascal/Projects/stackoverflow/Q3651690/src/main/java/com/stackoverflow/Q3651690/App.java:11:0::0 Don't write to the console
    see also: /home/pascal/Projects/stackoverflow/Q3651690/src/main/java/com/stackoverflow/Q3651690/DontWriteToTheConsole.aj:8::0
...
Pascal Thivent
We are also using the aspectj-maven-plugin to compile our aspects with Maven
festerwim
A: 

we're using the aspectj-maven-plugin for building several large production grade J2EE systems. Lately, the development on that plugin doesn't seem to be overly active. The last relase has been last winter, and there are some serious problems with "AspectLib" and "WeaveDependencies", which got reported several times (even with attached bugfixes), without any responses from upstream.

But anyway, the basic functionality is working, and this plugin supports lots of configuration needed in real world projects.

Pascal Thivent showed in his (very good) response above how to configure the plugin with a special dependency section. You can use this trick also to configure the actual AspectJ version used for compilation, as the version used by default by this plugin is somewhat dated....

<project xmlns=....

<properties>
    <aspectjVer>1.6.9</aspectjVer>
    ....
    ....
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
....

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.3</version>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectjVer}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectjVer}</version>
                </dependency>
            </dependencies>
            <configuration>
       ....
</build>
<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectjVer}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId><!-- only needed if you use Spring-AOP -->
        <version>${aspectjVer}</version>
    </dependency>
    ....
    ....

Note the fact that the plugin has an classpath environment which is independent from your project's classpath. Thus we have to add the AspectJ-Runtime explicitly to the project dependencies.

Ichthyo
It would definately be interesting with an example of that!
Kristofer