java - example - Maven+AspectJ: todos los pasos para configurarlo
spring security oauth2 (5)
Tengo un problema para aplicar aspectos a mi proyecto de maven. Probablemente me falta algo, así que hice una lista de pasos. ¿Podría verificar si es correcto?
Digamos que en el projectA
es una clase de aspecto y en clases projectB
, que deben cambiarse por aspectos.
- Crear proyecto maven
ProjectA
con claseAspectJ
- agregar el complemento
Aspectj
y la dependencia - Agregar
ProjectA
como una dependencia deprojectB
pom.xml
- Agregar al plugin
projectB
pom.xml
"
<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>
- Añadir dependencia aspectj
Después de todos estos pasos mi problema es que durante la compilación obtengo:
[WARNING] advice defined in AspectE has not been applied [Xlint:adviceDidNotMatch]
Y luego cuando ejecuto mi programa:
Exception in thread "FeatureExcutionThread" java.lang.NoClassDefFoundError: AspectE
Eche un vistazo a un ejemplo de la vida real:
- Este es un módulo donde definimos aspectos y los pom.xml : pom.xml .
- Así es como los usamos, en otro proyecto: pom.xml (preste atención a las líneas resaltadas).
El problema en su caso es que no incluye ProjectA
como una dependencia en tiempo de ejecución de ProjectB
.
Esto funcionó para mí, tuve que agregar la búsqueda de dependencias externas (ver weaveDependencies) para poder tejerlas, debe incluir esto en el archivo pom de ProjectA:
<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>
Espero eso ayude...
Recuerdo que también tuve este problema, pero lo resolví cambiando a aspectos basados en la anotación Java. Podrías intentarlo.
Seguí algunas de sus preguntas anteriores para tratar de descubrir qué es lo que realmente está tratando de hacer. He creado la siguiente estructura y código y para mí funciona bien.
$ tree . . ├── pom.xml ├── ProjectA | ├── pom.xml | └── src | └── main | └── aspect | └── com | └── | └── aspects | ├── AspectL.java | └── Trace.aj └── ProjectB ├── pom.xml └── src └── main └── java └── com └── └── 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.</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.</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.</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>
He creado dos aspectos diferentes. Uno que usa anotaciones @AspectJ y otro que se define como un aspecto AspectJ clásico.
AspectL.java
package com..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..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());
}
}
Esos dos archivos son parte del módulo ProjectA y son parte de un jar.
Ahora queremos utilizar estos aspectos y tejerlos en el código de 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.</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.</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.</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..App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
App.java
package com.;
/**
* @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");
}
}
Construyo todo desde arriba pom:
mvn clean install
Y luego ve al directorio de ProjectB y ejecuta la aplicación:
mvn exec:java
El resultado es:
aspect before
Enters on method: void com..App.hello(String).
With argument of type class java.lang.String and value world.
Exits method: void com..App.hello(String).
aspect after
Entonces, para concluir, ambos aspectos están funcionando y la configuración de maven también funciona.
Tuve el mismo problema que tú. La única solución que encontré fue crear un contenedor para cada clase de aspecto dentro del proyecto aspectJ para permitir que los proyectos externos tuvieran acceso a él.