web-dev-qa-db-fra.com

Maven + AspectJ - toutes les étapes pour le configurer

J'ai un problème avec l'application des aspects à mon projet maven. Il me manque probablement quelque chose, j'ai donc fait une liste d'étapes. Pourriez-vous s'il vous plaît vérifier si elle est correcte?

Disons que dans projectA est une classe d'aspect et dans projectB classes, qui devraient être modifiées par aspects.

  • Créer un projet maven ProjectA avec la classe AspectJ
  • ajouter Aspectj plugin et dépendance
  • Ajoutez ProjectA comme dépendance à projectBpom.xml
  • Ajouter à projectBpom.xml brancher
<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>
  • Ajouter une dépendance aspectj

Après toutes ces étapes, mon problème est que pendant la compilation, j'obtiens:

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

Et puis quand je lance mon programme:

Exception in thread "FeatureExcutionThread" Java.lang.NoClassDefFoundError: AspectE
33
alicjasalamon

J'ai retracé certaines de vos questions les plus anciennes pour essayer de découvrir ce que vous essayez réellement de faire. J'ai trouvé la structure et le code suivants et pour moi, cela fonctionne bien.

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

J'ai créé deux aspects différents. Un qui utilise les annotations @AspectJ et un autre qui est défini comme un aspect AspectJ classique.

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());
    }
}

Ces deux fichiers font partie du module ProjectA et font partie d'un bocal.

Maintenant, nous voulons utiliser ces aspects et les intégrer dans le code 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.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");
    }
}

Je construis tout à partir de pom haut:

mvn clean install

Et puis allez dans le répertoire ProjectB et exécutez l'application:

mvn exec:Java

Le résultat est:

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

Donc, pour conclure, les deux aspects fonctionnent et la configuration de maven fonctionne également.

46
maba

Cela a fonctionné pour moi, a dû ajouter la recherche de dépendances externes (voir weaveDependencies) afin de leur effectuer le tissage, vous devez l'inclure dans le fichier pom 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>

J'espère que cela aide...

8
Carlos Castellanos

Je me souviens également d'avoir rencontré ce problème, mais je l'ai résolu en passant à Java aspects basés sur les annotations. Vous pouvez essayer.

0
Rein

J'avais eu le même problème que toi. La seule solution que j'ai trouvée était de créer un wrapper pour chaque classe d'aspect à l'intérieur du projet aspectJ pour permettre aux projets externes d'y accéder

0
Carlos