Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven + AspectJ - all steps to configure it

I have a problem with applying aspects to my maven project. Probably I am missing something, so I've made a list of steps. Could you please check if it is correct?

Let say in projectA is an aspect class and in projectB classes, which should be changed by aspects.

  • Create maven project ProjectA with AspectJ class
  • add Aspectj plugin and dependency
  • Add ProjectA as a dependency to projectB pom.xml
  • Add to projectB pom.xml plugin
<plugin>     <groupId>org.codehaus.mojo</groupId>     <artifactId>aspectj-maven-plugin</artifactId>     <version>1.4</version>     <executions>         <execution>             <goals>                 <goal>compile</goal>                 <goal>test-compile</goal>             </goals>         </execution>     </executions>     <configuration>         <source>${maven.compiler.source}</source>         <target>${maven.compiler.target}</target>         <aspectLibraries>             <aspectLibrary>                 <groupId>ProjectA</groupId>                 <artifactId>ProjectA</artifactId>             </aspectLibrary>         </aspectLibraries>     </configuration> </plugin> 
  • Add aspectj dependency

After all these steps my problem is, that during compilation I get:

[WARNING] advice defined in AspectE has not been applied [Xlint:adviceDidNotMatch] 

And then when I run my program:

Exception in thread "FeatureExcutionThread" java.lang.NoClassDefFoundError: AspectE 
like image 763
alicjasalamon Avatar asked Sep 14 '12 11:09

alicjasalamon


People also ask

What is AspectJ Maven plugin used for?

Maven AspectJ Plug-inIt offers the ability to weave aspects on the classes generated and dependency libraries. This also includes the ability to add dependencies on libraries with aspects.

What is AspectJ compiler?

Compile-Time Weaving When we have both the source code of the aspect and the code that we are using aspects in, the AspectJ compiler will compile from source and produce a woven class files as output. Afterward, upon execution of your code, the weaving process output class is loaded into JVM as a normal Java class.

What is the use of Aspectjrt jar?

aspectjweaver. jar is an AspectJ library needed for LTW (load-time weaving), as opposed to compile-time weaving.


2 Answers

I traced some of your older questions to try to find out what you actually are trying to do. I have come up with the following structure and code and for me it works well.

 $ tree . . ├── pom.xml ├── ProjectA |   ├── pom.xml |   └── src |       └── main |           └── aspect |               └── com |                   └── stackoverflow |                       └── aspects |                           ├── AspectL.java |                           └── Trace.aj └── ProjectB     ├── pom.xml     └── src         └── main             └── java                 └── com                     └── stackoverflow                         └── App.java 

pom.xml

<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>org.stackoverflow</groupId>     <artifactId>Q12423965</artifactId>     <packaging>pom</packaging>     <version>1.0-SNAPSHOT</version>      <name>${project.artifactId}-${project.version}</name>      <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <maven.compiler.source>1.6</maven.compiler.source>         <maven.compiler.target>1.6</maven.compiler.target>     </properties>      <modules>         <module>ProjectA</module>         <module>ProjectB</module>     </modules>      <dependencyManagement>         <dependencies>             <dependency>                 <groupId>org.stackoverflow</groupId>                 <artifactId>Q12423965-ProjectA</artifactId>                 <version>${project.version}</version>             </dependency>         </dependencies>     </dependencyManagement>      <build>         <pluginManagement>             <plugins>                 <plugin>                     <groupId>org.codehaus.mojo</groupId>                     <artifactId>aspectj-maven-plugin</artifactId>                     <version>1.4</version>                     <executions>                         <execution>                             <goals>                                 <goal>compile</goal>                                 <goal>test-compile</goal>                             </goals>                         </execution>                     </executions>                     <configuration>                         <source>${maven.compiler.source}</source>                         <target>${maven.compiler.target}</target>                     </configuration>                 </plugin>                 <plugin>                     <groupId>org.apache.maven.plugins</groupId>                     <artifactId>maven-compiler-plugin</artifactId>                     <version>2.5.1</version>                     <configuration>                         <source>${maven.compiler.source}</source>                         <target>${maven.compiler.target}</target>                     </configuration>                 </plugin>             </plugins>         </pluginManagement>     </build> </project> 

ProjectA/pom.xml

<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>      <parent>         <groupId>org.stackoverflow</groupId>         <artifactId>Q12423965</artifactId>         <version>1.0-SNAPSHOT</version>     </parent>      <artifactId>Q12423965-ProjectA</artifactId>      <name>${project.artifactId}-${project.version}</name>      <dependencies>         <dependency>             <groupId>org.aspectj</groupId>             <artifactId>aspectjrt</artifactId>             <version>1.6.11</version>         </dependency>     </dependencies>      <build>         <plugins>             <plugin>                 <groupId>org.codehaus.mojo</groupId>                 <artifactId>aspectj-maven-plugin</artifactId>             </plugin>         </plugins>     </build> </project> 

I have created two differenct aspects. One that uses @AspectJ annotations and another one that is defined as a classic AspectJ aspect.

AspectL.java

package com.stackoverflow.aspects;  import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut;  /**  * @author maba, 2012-09-18  */ @Aspect public class AspectL {      @Pointcut("execution(* main(..))")     public void defineEntryPoint() {     }      @Before("defineEntryPoint()")     public void aaa(JoinPoint joinPoint) {         System.out.println("aspect before");     }      @After("defineEntryPoint()")     public void bbb(JoinPoint joinPoint) {         System.out.println("aspect after");     } } 

Trace.aj

package com.stackoverflow.aspects;  public aspect Trace {     pointcut publicMethodExecuted(): execution(public !static * *(..));      after(): publicMethodExecuted() {         System.out.printf("Enters on method: %s. \n", thisJoinPoint.getSignature());          Object[] arguments = thisJoinPoint.getArgs();         for (int i =0; i < arguments.length; i++){             Object argument = arguments[i];             if (argument != null){                 System.out.printf("With argument of type %s and value %s. \n", argument.getClass().toString(), argument);             }         }         System.out.printf("Exits method: %s. \n", thisJoinPoint.getSignature());     } } 

Those two files are part of the ProjectA module and are part of a jar.

Now we want to use these aspects and weave them into the code of ProjectB.

ProjectB/pom.xml

<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>      <parent>         <groupId>org.stackoverflow</groupId>         <artifactId>Q12423965</artifactId>         <version>1.0-SNAPSHOT</version>     </parent>      <artifactId>Q12423965-ProjectB</artifactId>      <name>${project.artifactId}-${project.version}</name>      <dependencies>         <dependency>             <groupId>org.aspectj</groupId>             <artifactId>aspectjrt</artifactId>             <version>1.6.11</version>         </dependency>         <dependency>             <groupId>org.stackoverflow</groupId>             <artifactId>Q12423965-ProjectA</artifactId>         </dependency>     </dependencies>      <build>         <plugins>             <plugin>                 <groupId>org.codehaus.mojo</groupId>                 <artifactId>aspectj-maven-plugin</artifactId>                 <configuration>                     <aspectLibraries>                         <aspectLibrary>                             <groupId>org.stackoverflow</groupId>                             <artifactId>Q12423965-ProjectA</artifactId>                         </aspectLibrary>                     </aspectLibraries>                 </configuration>             </plugin>             <plugin>                 <groupId>org.codehaus.mojo</groupId>                 <artifactId>exec-maven-plugin</artifactId>                 <version>1.2.1</version>                 <executions>                     <execution>                         <goals>                             <goal>java</goal>                         </goals>                     </execution>                 </executions>                 <configuration>                     <mainClass>com.stackoverflow.App</mainClass>                 </configuration>             </plugin>         </plugins>     </build> </project> 

App.java

package com.stackoverflow;  /**  * @author maba, 2012-09-17  */ public class App {      public void hello(String name) {     }      public static void main(String[] args) {         App app = new App();         app.hello("world");     } } 

I build everything from top pom:

mvn clean install 

And then go into the ProjectB directory and run the app:

mvn exec:java 

The result is:

aspect before Enters on method: void com.stackoverflow.App.hello(String).  With argument of type class java.lang.String and value world.  Exits method: void com.stackoverflow.App.hello(String).  aspect after 

So to conclude both aspects are working and the maven setup also works.

like image 83
maba Avatar answered Oct 04 '22 09:10

maba


This worked for me, a had to add the lookup for external dependencies (see weaveDependencies) in order to perform weaving to them, you should include this in ProjectA pom file:

<dependencies>   <dependency>     <groupId>com.ProjectB</groupId>     <artifactId>ProjectB</artifactId>   </dependency>   <dependency>     <groupId>org.aspectj</groupId>     <artifactId>aspectjrt</artifactId>     <version>1.6.5</version>   </dependency> </dependencies>  <build>   <plugins>     <plugin>       <groupId>org.codehaus.mojo</groupId>       <artifactId>aspectj-maven-plugin</artifactId>       <version>1.2</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>         <weaveDependencies>            <weaveDependency>             <groupId>com.ProjectB</groupId>             <artifactId>ProjectB</artifactId>           </weaveDependency>         </weaveDependencies>         <showWeaveInfo>true</showWeaveInfo>          <source>${maven.compiler.source}</source>         <target>${maven.compiler.target}</target>       </configuration>     </plugin>   </plugins> </build> 

Hope it helps...

like image 33
Carlos Castellanos Avatar answered Oct 04 '22 08:10

Carlos Castellanos