欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Tomcat 7中配置AspectJ的Load Time weaving

程序员文章站 2022-07-14 15:50:20
...
最近项目中有个同事启用了AspectJ的Load Time Weaving,通过在Maven中打包部署在Weblogic完全没问题,但是在我的Tomcat 7中无法启动应用的情况,会出现类似“Can't Add Transfomer”以及采用-javaagent:spring-instructment.jar来避免该错误的提示,导致每次出现问题时,只能通过maven打包部署或者事先在代码加入日志来定位问题,极度不爽。

在使用Google大神在*上找了一堆文章查看后发现两种解决方案:
1)通过配置在启动tomcat的脚本中配置-javaagent:spring-instrument.jar来解决。spring-instrument.jar在Spring各版本中名称不一样。在项目使用的最新的Spring4.0.2中名称为:spring-instrument-4.0.2.RELEASE.jar。在早期的spring版本中可能是spring-ageng.jar。发现通过设置该属性在tomcat7中完全不起作用。

2)通过将spring-instrument-tomcat-4.0.2.RELEASE.jar的jar包放置在Tomcat安装目录的lib下,同时将context.xml文件,文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
		<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>

放置在Web项目的root目录(webapp或者WebContent目录,也就是与WEB-INF目录平行)下。在使用Eclipse自带的Server插件可以成功启动项目。
如果放置在TOMCAT安装目录的conf目录的context.xml文件(该文件的配置信息将对Tomcat中所有的web app起作用)中,发现启动项目仍然会出现上述错误。

由于在开发项目的过程中一直sysdeo的Tomcat插件,想通过该插件来启动web项目,发现还是抛出了上述错误。为什么要使用这个插件?因为这个插件比起自身的Eclipse的插件有很多好处,启动快速,不需要发布文件(因为直接加载编译好的class文件),修改文件不重启。经发现tomcat7一直采用自身的WebappClassLoader来加载class文件而不是上述配置的TomcatInstrumentableClassLoader来加载,初步怀疑可能是sysdeo的tomcat插件的DevLoader类实现无法识别上述的配置的类TomcatInstrumentableClassLoader,而采用Tomcat默认的WebappClassLoader类。

查看了DevLoader类的实现发现该类继承了WebappLoader,结合了《深入剖析Tomcat 》第8章 Loader 这篇文章,发现WebappLoader类中实例化了WebappClassLoader。
现在目标就很明确了,只要让WebappLoader类中采用TomcatInstrumentableClassLoader而不是Tomcat默认的WebappClassLoader。需要将spring-instrument-tomcat-4.0.2.RELEASE.jar包放置在Tomcat安装目录的lib下,否则加载不到TomcatInstrumentableClassLoader类。
下载tomcat7对应版本的源代码,找到WebappLoader类将
private String loaderClass =
        "org.apache.catalina.loader.WebappClassLoader";
修改为
private String loaderClass =
        "org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader";
,重新编译该类,将该类的class文件替换到Tomcat安装目录下的catalina.jar即可。编译WebappClassLoader需要依赖:
catalina.jar
tomcat-coyote.jar
tomcat-util.jar
tomcat-juli.jar
其中最后一个jar包在bin目录下,而不是在lib目录下。
附件为:apache-tomcat-7.0.52的catalina.jar(WebappLoader.class文件loaderClass属性已更新为org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader)

最后,祝各位喜欢折腾的朋友好运。