Java AspectJ-为什么;XYZ中定义的通知尚未应用";?

Java AspectJ-为什么;XYZ中定义的通知尚未应用";?,java,aop,aspectj,Java,Aop,Aspectj,我刚开始使用AspectJ(1.6.11)。我通过commons电子邮件库发送电子邮件,我想知道发送邮件需要多长时间。这是我的电子邮件发送代码: import org.apache.commons.mail.Email; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail; public class EmailTest { public static void

我刚开始使用AspectJ(1.6.11)。我通过commons电子邮件库发送电子邮件,我想知道发送邮件需要多长时间。这是我的电子邮件发送代码:

import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;

public class EmailTest
{
    public static void main(String[] args) throws EmailException
    {
        Email e = new SimpleEmail();
        e.setHostName("localhost");
        e.setFrom("foo@localhost");
        e.addTo("batto@localhost");
        e.setSubject("Test " + System.currentTimeMillis());
        e.setMsg("Message");
        e.send();
    }
}
这就是我的观点:

public aspect EmailAspect
{
    private long start;

    pointcut conn() : call(* javax.mail.Transport.send(..));

    void around() : conn() {
        start = System.currentTimeMillis();
        Throwable t = null;
        try {
            proceed();
        }
        catch(Throwable _t) {
            t = _t;
        }
        long spent = System.currentTimeMillis() - start;
        System.out.println("Send time: " + spent);
        if (t != null) {
            throw new RuntimeException(t);
        }
    }
}
但是,当我编译它时:

java -jar ../lib/aspectjtools-1.6.11.jar -cp "$CLASSPATH" -source 6 Email*{java,aj}
我得到以下警告:

/home/batto/work/ajtest/test/EmailAspect.aj:8 [warning] advice defined in EmailAspect has not been applied [Xlint:adviceDidNotMatch]


1 warning
当然,aspect不起作用。我尝试了before()/after()建议,在call()中使用了不同的模式,但最终都得到了相同的警告

我在Eclipse中调试了该程序(使用commons电子邮件源),我知道Transport.send()会被执行

有什么问题

多谢各位

更新

所以我刚刚发现我需要javax.mail.Transport的源代码来实现我使用的编织方法(源编织)。因此,我使用了二进制编织,它起了作用。然而,我改变了主意,现在我想测量java.net.Socket.connect(..)的时间(org.apache.commons.mail.Email.send(..)调用javax.mail.Transport.send(..)调用java.net.Socket.connect(..),我通过在Eclipse中调试对其进行了验证)。但我不想在编译的代码中包含整个JDK。所以我尝试了加载时间编织。这是我修改过的方面:

public aspect EmailAspect {
    // Some day I'll learn what's the difference between call() and execution()
    pointcut conn() :
        call(* java.net.Socket.connect(..)) ||
        execution(* java.net.Socket.connect(..));

    before() : conn() {
        System.out.println("It works");
    }
}
我编译并运行程序的步骤如下:

$ mkdir META-INF
$ cat >META-INF/aop.xml
<aspectj>
  <aspects>
    <aspect name="EmailAspect"/>
    <!-- I think this is not neccessary -->
    <include within="java..*"/>
    <include within="javax..*"/>
  </aspects>
  <weaver>
    <include within="java..*"/>
    <include within="javax..*"/>
  </weaver>
</aspectj>
$ # add jars from ../lib to CLASSPATH
$ javac -source 6 EmailTest.java
$ java -jar ../lib/aspectjtools-1.6.11.jar -cp ".:$CLASSPATH" -source 6 EmailAspect.aj
$ java -cp ".:$CLASSPATH" -javaagent:../lib/aspectjweaver-1.6.11.jar EmailTest
$mkdir META-INF
$cat>META-INF/aop.xml
$#将JAR从../lib添加到类路径
$javac-源代码6 EmailTest.java
$java-jar../lib/aspectjtools-1.6.11.jar-cp.“:$CLASSPATH”-源代码6 EmailAspect.aj
$java-cp.“:$CLASSPATH”-javaagent:../lib/aspectjweaver-1.6.11.jar EmailTest

但是它不起作用:(.

快速查看apache文档似乎表明电子邮件和SimpleMail都不是传输实例。将
切入点更改为:

pointcut conn() : call(* SimpleEmail.send(..));

因此,我刚刚解决了加载时编织的问题。我将aop.xml更改为:

<aspectj>
  <aspects>
    <aspect name="EmailAspect"/>
  </aspects>
  <weaver options="-verbose -Xset:weaveJavaxPackages=true -Xset:weaveJavaPackages=true">
  </weaver>
</aspectj>

(还有AspectJ运行时报告说我需要提供-Xset:weaveJavaxPackages=true选项,我太笨了:()。

我的JDK是OpenJDK 6b18-1.8.7-5(debian软件包)是的,但是Email.send()调用Transport.send(..)。不管怎样,我还是成功了(我更新了问题)使用二进制编织。现在问题变为非工作加载时编织。我还向切入点添加了具有相同模式的execution()“predicate”(我还不知道有什么区别,但现在无关紧要)。@batto没有办法通过编译时编织(CTW)来实现这一点?