AspectJ (аннотации) во время компиляции с помощью Ant и NetBeans

Я хочу использовать AspectJ времени компиляции с Ant в NetBeans. Я хочу запустить его в Google App Engine, но в данный момент это не обязательно. AspectJ основан на аннотациях.
Я предпочитаю переплетение во время компиляции (модификация, инструментирование? классов). Я не хотел бы использовать собственный загрузчик классов. Как этого добиться?

Что у меня уже есть:

Я попробовал учебник по аннотациям AspectJ с NetBeans. Я изменил build.xml для обработки аспектов (используя задачу iajc Ant), как описано здесь. Проблема в том, что для этого требуется добавить -javaagent:lib/aspectjweaver.jar (это невозможно в GAE).
Запуск моей сборки приводит к следующему результату:

info compiling C:\NetBeansProjects\TryAspectJ\src\net\andrewewhite\examples\HelloWorld.java
weaveinfo Join point 'method-call(void java.io.PrintStream.println(java.lang.String))' in Type 'net.andrewewhite.examples.HelloWorld' (HelloWorld.java:9) advised by before advice from 'net.andrewewhite.aspects.BasicAspect' (BasicAspect.class:17(from BasicAspect.java))
weaveinfo Join point 'method-call(void java.io.PrintStream.println(java.lang.String))' in Type 'net.andrewewhite.examples.HelloWorld' (HelloWorld.java:9) advised by after advice from 'net.andrewewhite.aspects.BasicAspect' (BasicAspect.class:23(from BasicAspect.java))
info woven class net.andrewewhite.examples.HelloWorld (from C:\NetBeansProjects\TryAspectJ\src\net\andrewewhite\examples\HelloWorld.java)
info Compiler took 2547ms

Когда я запускаю свой проект с параметром -javaagent, он работает нормально. (В NetBeans: щелкните проект>Свойства>Выполнить>Параметры виртуальной машины: -javaagent:./dist/lib/aspectjweaver.jar). Вывод кода из учебника:

run:
About to make call to print Hello World
Hello World!
Just made call to print Hello World
BUILD SUCCESSFUL (total time: 0 seconds)

Без агента (параметры VM очищены) код работает так, как если бы он был без AspectJ:

run:
Hello World!
BUILD SUCCESSFUL (total time: 0 seconds)

Источники:

\TryAspectJ\src\META-INF\aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <aspect name="net.andrewewhite.aspects.BasicAspect" />
    </aspects>
</aspectj>

\TryAspectJ\src\net\andrewewhite\aspects\BasicAspect.java

package net.andrewewhite.aspects;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BasicAspect {

    @Before("   call(void java.io.PrintStream.println(java.lang.String)) " +
            "&& !within(net.andrewewhite.aspects..*)")
    public void beforePrintlnCall() {
        System.out.println("About to make call to print Hello World");
    }

    @After("    call(void java.io.PrintStream.println(java.lang.String)) " +
           "&&  !within(net.andrewewhite.aspects..*)")
    public void afterPrintlnCall() {
        System.out.println("Just made call to print Hello World");
    }
}

\TryAspectJ\src\net\andrewewhite\examples\HelloWorld.java

package net.andrewewhite.examples;

public class HelloWorld {
    public static void main(String[] argv) {
        System.out.println("Hello World!"); 
    }   
}

\TryAspectJ\build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="TryAspectJ" default="default" basedir=".">
    <description>Builds, tests, and runs the project TryAspectJ.</description>
    <import file="nbproject/build-impl.xml"/>        
<taskdef classpath="lib/aspectj/aspectjtools.jar" resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"/>         

    <target name="aspectj">
        <echo level="info">--- aspectj (start) ---</echo>
        <iajc destDir="${build.classes.dir}" source="1.6" target="1.6" showweaveinfo="true" verbose="true" >
            <inpath>
                <pathelement location="lib/aspectj/aspectjrt.jar"/>
                <pathelement location="${build.classes.dir}" /> 
            </inpath>
            <sourceroots>
                <pathelement location="${src.dir}"/>
            </sourceroots>
            <classpath>
                <pathelement location="${javac.classpath}"/>
                <pathelement location="${j2ee.platform.classpath}"/>
            </classpath>
        </iajc> 
         <echo level="info">--- aspectj finished ---</echo>
    </target>

<target name="-post-compile" depends="aspectj"></target>
</project>

Что мне нужно добавить или изменить?


person zacheusz    schedule 13.07.2011    source источник


Ответы (2)


Решение найдено. Это правильный фрагмент build.xml:

<taskdef classpath="lib/aspectjtools.jar" resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"/>
<target name="aspectj">
    <echo level="info">--- aspectj (start) ---</echo>
    <!-- begin fix classpath for this bug https://issues.apache.org/bugzilla/show_bug.cgi?id=40291 -->
    <condition property="targetos" value="windows" else="unix">
        <os family="windows"/>
    </condition>
    <!-- converting classpath -->
    <pathconvert targetos="${targetos}" property="javac.convertedClasspath" >
        <path path="${javac.classpath}" />                   
    </pathconvert>
    <!-- end fix classpath -->
    <iajc source="1.6" target="1.6" showweaveinfo="true" verbose="true" destdir="${build.classes.dir}"  >
        <inpath>
            <pathelement location="${build.classes.dir}"/>    
        </inpath>
        <classpath>
            <pathelement location="${javac.convertedClasspath}" />
        </classpath>
    </iajc>
    <echo level="info">--- aspectj (finished) ---</echo>
</target>
<target name="-post-compile" depends="aspectj"></target>

Вызов java -classpath ./lib/aspectjrt.jar -jar TryAspectJ.jar работает нормально. Странно то, что из NetBeans (правый клик по проекту->Выполнить) результаты такие, как если бы они были без AspectJ. Я думаю, что NetBeans запускает проекты из каталога build/classes, а не из jar. Но это не проблема.

person zacheusz    schedule 13.07.2011

Вам нужно добавить элемент пути аспекта в качестве подэлемента к элементу iajc.

<aspectpath>
    <pathelement location="..." />
</aspectpath>

Файл aop.xml необходим только для сплетения AspectJ во время загрузки.

person Espen    schedule 13.07.2011
comment
Спасибо за ваш ответ. Я добавил ‹aspectpath›‹pathelement location=${dist.jar} /›‹/aspectpath›. При вызове из ‹target name=-post-compile depend=aspectj›‹/target› я получаю предупреждение об ошибке конфигурации сборки: пропуск отсутствующей, пустой или поврежденной записи аспектного пути: C:\NetBeansProjects\TryAspectJ\dist\TryAspectJ.jar. При вызове из ‹target name=-post-jar depend=aspectj›‹/target› предупреждение исчезает, но результат такой же, как если бы он был без ‹aspectpath›. Вот подробный журнал компиляции: zacheusz.eu/java/various/aspectj02.log - person zacheusz; 13.07.2011