Hi all, I'm having some problems getting load-time weaving to work with Spring in my Tomcat 6 webapp. I only want to use it for transactions (so that self-invocation respects transactional annotations, which it doesn't with AOP proxying). It appears that the weaver is being loaded, but my annotated classes aren't actually being woven. When I step through my code, I don't see any transaction boundaries in SQL logs, as I was seeing with regular AOP proxy configuration. Here's my setup:
In server.xml:
<Context path="/api" allowLinking="true" reloadable="false" docBase="/usr/local/apache-tomcat-6.0.18/webapps/API/ROOT" workDir="/usr/local/apache-tomcat-6.0.18/webapps/API/ROOT/work">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
I've got spring-tomcat-weaver.jar tomcat/lib directory, and the following jars on my Tomcat classpath:
tomcat/webapps/API/ROOT/WEB-INF/lib/aspectjweaver.jar tomcat/webapps/API/ROOT/WEB-INF/lib/spring-aspects.jar
This is in the bean config file where the annotated service classes are defined:
<tx:annotation-driven transaction-manager="txManager" mode="aspectj"/>
In one of the many other bean config files in my context:
<aop:aspectj-autoproxy>
<aop:include name="methodTimer"/>
</aop:aspectj-autoproxy>
<context:load-time-weaver aspectj-weaving="on"/>
<context:annotation-config />
<bean name="methodTimer" class="tv.current.web.aop.MethodTimer" />
I want MethodTimer to use regular AOP proxying, not LTW - LTW should only apply to @Transactional annotations. As described here: http://static.springsource.org/spring/docs/2.5.x/reference/aop.html#aop-aj-configure. If I comment out <aop:aspectj-autoproxy>
element, I don't get any of the weaving info log messages I see otherwise. Speaking of which, here they are; you can see that aspects are getting loaded but nothing is actually being woven:
Aug 28, 2009 6:34:42 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
[TomcatInstrumentableClassLoader@34fe7e0e] info AspectJ Weaver Version 1.6.5 built on Thursday Jun 18, 2009 at 03:42:32 GMT
[TomcatInstrumentableClassLoader@34fe7e0e] info register classloader org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader@34fe7e0e
[TomcatInstrumentableClassLoader@34fe7e0e] info using configuration file:/usr/local/apache-tomcat-6.0.18/webapps/API/ROOT/WEB-INF/lib/spring-aspects.jar!/META-INF/aop.xml
[TomcatInstrumentableClassLoader@34fe7e0e] warning ignoring duplicate definition: jar:file:/usr/local/apache-tomcat-6.0.18/webapps/API/ROOT/WEB-INF/lib/spring-aspects.jar!/META-INF/aop.xml
[TomcatInstrumentableClassLoader@34fe7e0e] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
[TomcatInstrumentableClassLoader@34fe7e0e] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
[TomcatInstrumentableClassLoader@34fe7e0e] info processing reweavable type org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect$ConfigurableDeserializationSupport: org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj
[TomcatInstrumentableClassLoader@34fe7e0e] info successfully verified type org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect exists. Originates from org/springframework/beans/factory/aspectj/D:\projects\spring\spring\aspectj\src\org\springframework\beans\factory\aspectj\AnnotationBeanConfigurerAspect.aj
[TomcatInstrumentableClassLoader@34fe7e0e] info successfully verified type org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect exists. Originates from org/springframework/beans/factory/aspectj/D:\projects\spring\spring\aspectj\src\org\springframework\beans\factory\aspectj\AbstractInterfaceDrivenDependencyInjectionAspect.aj
[TomcatInstrumentableClassLoader@34fe7e0e] weaveinfo Type 'org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect$ConfigurableDeserializationSupport' (AbstractInterfaceDrivenDependencyInjectionAspect.aj) has intertyped method from 'org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect' (D:\projects\spring\spring\aspectj\src\org\springframework\beans\factory\aspectj\AbstractInterfaceDrivenDependencyInjectionAspect.aj:'java.lang.Object org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect$ConfigurableDeserializationSupport.readResolve()')
As you can see from the logs, I don't have my own aop.xml file, I am using the default one in spring-aspects.jar, which is as follows:
<aspectj>
<!--
<weaver options="-showWeaveInfo"/>
-->
<aspects>
<aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"/>
<aspect name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
</aspects>
</aspectj>
I don't need to start Tomcat with -javaagent:/path/to/spring-agent.jar
, correct? Because I specified the right ClassLoader in server.xml and am seeing the loader getting used. Am I mistaken about this? Do I need spring-agent.jar anywhere, either in tomcat/lib or my tomcat classpath? Do I need aspectjweaver.jar in tomcat/lib? What else am I missing? Any help would be greatly appreciated as I have been wrestling with this for almost two days now.
Edit: One more (perhaps very important) detail I omitted - I'm developing in Eclipse and using the Sysdeo Tomcat Plugin to start Tomcat. Will try starting Tomcat from the command line and see if that makes a difference...