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(); } } and this is my aspect:
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); } } } However when I compile it with:
java -jar ../lib/aspectjtools-1.6.11.jar -cp "$CLASSPATH" -source 6 Email*{java,aj} I get following warning:
/home/batto/work/ajtest/test/EmailAspect.aj:8 [warning] advice defined in EmailAspect has not been applied [Xlint:adviceDidNotMatch] 1 warning And of course aspect doesn't work. I tried before()/after() advices, different patterns in call(), but it all ended up with same warning.
I debugged the the program in Eclipse (with commons-email sources) and I know that Transport.send() gets executed.
What is the problem?
Thank you.
UPDATE
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 But it doesn't work :(.