spring LTW agent方式在tomcat 8下无效

在常规的spring ltw中,我们对tomcat使用ltw,一般是以下两种方式。

//1 在启动项中添加javaagent选项
-javaagent:e:/spring-instrument-4.1.1.RELEASE.jar

//2 使用自定义的启动器,在META-INF/context.xml中增加以下内容
<?xml version="1.0" encoding="UTF-8" ?>
<Context>
 <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" /> 
</Context>

这两种方式在tomcat6以及tomcat7均可以正常工作。但对于tomcat8,第1种方式已经不能再工作,仅能使用第二种方式。原因就在于tomcat8的webClassLoader已经提供了InstrumentableClassLoader接口。此接口将导致spring直接将aspectj的AspectJClassBypassingClassFileTransformer 直接添加到tomcat的classLoader中。但由于不是很正确的实现方式,导致aspect在使用tomcat8提供的classLoader时,并不能有效地对自己的advice进行weaver,导致报以下的错误信息: 

java.lang.NoSuchMethodError: XXXAdvice.aspectOf()LXXXAdvice;
 atXXX.index(AbcController.java:30)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
 at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
 at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)

这个错误的产生在于aspectJ的初始化过程和classLoader之间的交互行为,以及tomcat8中不准确的缓存行为。

继续阅读“spring LTW agent方式在tomcat 8下无效”

使用spring aspect ltw和tomcat进行web开发的aspect加载问题

使用spring aspect ltw与tomcat整合开发时,需要ltw一般有两种方法。一种是通过aspectj本身的classload机制,在tomcat启动脚本中,加载相应的java agent数据信息;另一种就是通过修改上下文的classLoader,而使用spring提供的tomcatInstrmentClassLoader来进行aspect的编织工作。
然而,在笔者的开发环境中,却发生了aspect无法被再次编织的问题。经过反复的检查,确认了是由于classLoader加载类的先后顺序以及spring对instrment的注入顺序发生了混乱,而导致aspect类并没有正确的被编织。

    使用spring aspect ltw与tomcat整合开发时,需要ltw一般有两种方法。一种是通过aspectj本身的classload机制,在tomcat启动脚本中,加载相应的java agent数据信息;另一种就是通过修改上下文的classLoader,而使用spring提供的tomcatInstrmentClassLoader来进行aspect的编织工作。
    然而,在笔者的开发环境中,却发生了aspect无法被再次编织的问题。经过反复的检查,确认了是由于classLoader加载类的先后顺序以及spring对instrment的注入顺序发生了混乱,而导致aspect类并没有正确的被编织。

继续阅读“使用spring aspect ltw和tomcat进行web开发的aspect加载问题”