Аспект в Яве не соткан правильно

У меня есть следующий метод:

public class MonitorInterface {

    // this is the method you have to call to trigger the monitor
    public static void event(String eventName, HashMap params) { 
        System.out.println("Entering event method");
    }

}

и следующий аспект:

package aspects;

import com.path.for.MonitorInterface;
import java.util.HashMap;
public aspect _asp_connector0 {
    private pointcut eventP():
        execution(public static void event(String, HashMap));

    before(): eventP(){
        System.out.println("Test pointcut weave");
    }
}

который в основном добавляет Sys.out.print к предыдущему методу

Что касается pom.xml, я использую в основном следующие плагины:

 <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
        <useIncrementalCompilation>false</useIncrementalCompilation>
    </configuration>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.7</version>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
        <complianceLevel>1.7</complianceLevel>
        <Xlint>ignore</Xlint>
        <encoding>UTF-8</encoding>
        <verbose>true</verbose>
        <showWeaveInfo>true</showWeaveInfo>
        <sources>
            <source>
            <basedir>src/main/resources</basedir>
            <includes>
                <include>**/_asp_connector0.aj</include>
            </includes>
            <excludes>
                <exclude>**/*.java</exclude>
                    <exclude>**/*.lrv</exclude>
                    <exclude>**/*.txt</exclude>
                </excludes>
            </source>
        </sources>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.3.2</version>
    <configuration>
         <mainClass>path.to.main.Example</mainClass>
    </configuration>
</plugin>
<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.4.4</version>
    <executions>
       <execution>
          <configuration>
            <onejarVersion>0.96</onejarVersion>
            <mainClass>path.to.main.Example</mainClass>
            <attachToBuild>true</attachToBuild>
          </configuration>
          <goals>
              <goal>one-jar</goal>
          </goals>
       </execution>
  </executions>
</plugin>

Однако когда я компилирую (используя mvn clean install) и запускаю сгенерированный файл jar, я никогда не получаю сплетенный код нужным методом.

В качестве альтернативы я попытался запустить их с помощью компилятора ajc вручную следующим образом:

ajc -outjar testMain.jar -target 1.5 -source 1.5 src\main\java\path\to\Example.java src\main\java\path\to\MonitorInterface.java
set CLASSPATH=%CLASSPATH%;.\testMain.jar
ajc -outjar testAsp.jar -target 1.5 -source 1.5 src\main\resources\aspects\_asp_connector0.aj
set CLASSPATH=%CLASSPATH%;.\testAsp.jar
aj path.to.Example

Это приводит к предупреждению

_asp_connector0.aj:12 [warning] advice defined in aspects._asp_connector0 has not been applied [Xlint:adviceDidNotMatch]

но новый println все еще не появляется

Как я могу решить это, или, по крайней мере, отладить это более эффективно?

Примечание: в maven генерируется файл класса для аспекта, код просто не вплетается в реальный метод

1 ответ

Решение

Так как ваш аспект работает в простом Java-проекте AspectJ в Eclipse - по крайней мере для меня - проблема должна быть в вашей конфигурации плетения. Сразу бросается в глаза одно:

<basedir>src/main/resources</basedir>

Почему вы пытаетесь применить свой аспект к своим ресурсам, а не к коду (src/main/java по умолчанию в проектах maven)? Изменяя эту строку и удаляя include /exclude, я получаю следующее от aspectj-maven-plugin:

[INFO] Join point 'method-execution(void program.MonitorInterface.event(java.lang.String, java.util.HashMap))' in Type 'program.MonitorInterface' (MonitorInterface.java:7) advised by before advice from 'aspects._asp_connector0' (_asp_connector0.aj:11)

Так что совет используется и применяется.

Есть ли причина для вас, чтобы указать эти конкретные включает / исключает?

<exclude>**/*.java</exclude>

Одно это сделает практически невозможным советовать какой-либо Java-код, потому что вы исключаете весь Java-код из ткачества во время компиляции. Я бы предложил удалить все включения / исключения и добавлять их по частям, если у вас есть конкретная проблема, которую можно решить с помощью включений / исключений. Для описанного здесь варианта использования они совершенно не нужны и на самом деле проблематичны в их текущей конфигурации.

Другие вопросы по тегам