I want to be able to use Spring & AspectJ to weave in an aspect to an existing tomcat webapp at load time. I am using AspectJ because I need to perform constructor pointcut.
I have two test scenarios, one where my aspect is part of a simple servlet application -- the application contains the source for the aspect and I am using MVN and the aspectJ plugin to compile the WAR and the Aspect. This aspect works as expected. The second scenario is where I have separated the aspect into its own project and compiled it into a JAR file using (I've tried both AJC and AJDT) and included the jar file in my war/WEB-INF/lib folder. It seems that the Aspect is being picked up when the war file context is loaded, but not applied to any objects in the war file.
Here is the Aspect code:
@SuppressWarnings("unused")
public aspect ProjectMonitor{
pointcut constr() : call(com.avaya..*.new(..)) ;
Object around() : constr(){
System.out.println("In Constructor for "
+ thisJoinPointStaticPart.getSignature());
Object ret = proceed();
return ret;
}
pointcut publicOperation() : execution(public * *.*(..));
Object around() : publicOperation() {
long start = System.nanoTime();
Object ret = proceed();
long end = System.nanoTime();
System.out.println(thisJoinPointStaticPart.getSignature() + " took "
+ (end - start) + " nanoseconds");
return ret;
}
pointcut callConst() : call(public *..*SCESession.new(..));
public Object callConst(ProceedingJoinPoint jp) throws Throwable {
System.out.println("In Project Monitor!!!");
return jp.proceed();
}
}
I have included a aop.xml file in the web app/META-INF folder:
<aspectj>
<aspects>
<aspect name="com.ddvc.ivr.ProjectMonitor" />
</aspects>
</aspectj>
And my Spring Context file looks as such:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:load-time-weaver aspectj-weaving="on" />
<context:spring-configured />
<context:component-scan base-package="com.avaya.sce.runtimecommon"/>
<context:annotation-config />
<aop:aspectj-autoproxy />
<!-- Aspect Mapping -->
<bean id="monitor" class="com.ddvc.ivr.ProjectMonitor" factory-method="aspectOf"/>
</beans>
Pretty straightforward, right? I even have a -javaagent set:
export JAVA_OPTS="-Xmx1024M -Xms1024M -server -javaagent:/software/apache-tomcat-6.0.36/lib/spring-instrument-3.2.1.RELEASE.jar"
Why would this work when the source is compiled with the WAR file but when it is included as a JAR file in the class path, it does not work at all.
I see the following in the tomcat log files multiple times when the WAR context file is reloaded:
11:27:51,285 DEBUG GenericTypeResolver:151 - Resolving return type for [public static org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.aspectOf()] with concrete method arguments [{}].
Any/All replies appreciated! Thanks in advance, Griff
Stupid mistakes cost time and money. I was including the aop.xml in the WAR file /META-INF folder instead of the included JAR file. Moving the aop.xml file inside the JAR file fixed the problem, duh!