AspectJ - 为什么“没有应用在 XYZ 中定义的建议"? [英] AspectJ - why "advice defined in XYZ has not been applied"?
问题描述
我刚开始玩 AspectJ (1.6.11).我正在通过 commons-email libary 发送电子邮件,我想知道发送消息需要多长时间.所以这是我的电子邮件发送代码:
I just started playing with AspectJ (1.6.11). I'm sending emails via commons-email libary and I'd like to know how long it takes to send a message. So this is my email sending code:
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() 中使用了不同的模式,但最终都得到了相同的警告.
And of course aspect doesn't work. I tried before()/after() advices, different patterns in call(), but it all ended up with same warning.
我在 Eclipse 中调试了程序(使用 commons-email 源)并且我知道 Transport.send() 被执行了.
I debugged the the program in Eclipse (with commons-email sources) and I know that Transport.send() gets executed.
有什么问题?
谢谢.
更新
所以我刚刚发现我需要 javax.mail.Transport 的源代码用于我使用的编织方法(源编织).所以我使用了二进制编织并且它起作用了.但是我改变了主意,现在我想测量 java.net.Socket.connect(..) (org.apache.commons.mail.Email.send(..) 调用 javax.mail.Transport.send(..) 的时间..) 调用 java.net.Socket.connect(..),我通过在 Eclipse 中调试来验证它).但我不想在我的编译代码中包含整个 JDK.所以我尝试了加载时编织.这是我修改的方面:
So I've just figured out that I need source code of javax.mail.Transport for the method of weaving I used (source weaving). So I used binary weaving and it worked. However I changed my mind and now I want to measure time of java.net.Socket.connect(..) (org.apache.commons.mail.Email.send(..) calls javax.mail.Transport.send(..) which calls java.net.Socket.connect(..), I verified it by debugging in Eclipse). But I don't want to include whole JDK in my compiled code. So I tried load-time weaving. This is my modified aspect:
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");
}
}
这是我编译&的步骤运行程序:
And this steps I did to compile & run program:
$ 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
但它不起作用:(.
推荐答案
所以我刚刚解决了加载时编织的问题.我将 aop.xml 改为:
So I've just sovled the problem with load-time weaving. I changed aop.xml to:
<aspectj>
<aspects>
<aspect name="EmailAspect"/>
</aspects>
<weaver options="-verbose -Xset:weaveJavaxPackages=true -Xset:weaveJavaPackages=true">
</weaver>
</aspectj>
我在这里找到答案https://bugs.eclipse.org/bugs/show_bug.cgi?id=149261#c11(还有 AspectJ 运行时报告说我需要一直提供 -Xset:weaveJavaxPackages=true 选项,我太笨了:().
I found answer here https://bugs.eclipse.org/bugs/show_bug.cgi?id=149261#c11 (and also AspectJ runtime was reporting that I need to supply -Xset:weaveJavaxPackages=true option all the time, I was just too dumb :().
这篇关于AspectJ - 为什么“没有应用在 XYZ 中定义的建议"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!