1. 程式人生 > >Tomcat 7中配置AspectJ的Load Time weaving

Tomcat 7中配置AspectJ的Load Time weaving

最近專案中有個同事啟用了AspectJ的Load Time Weaving,通過在Maven中打包部署在Weblogic完全沒問題,但是在我的Tomcat 7中無法啟動應用的情況,會出現類似“Can't Add Transfomer”以及採用-javaagent:spring-instructment.jar來避免該錯誤的提示,導致每次出現問題時,只能通過maven打包部署或者事先在程式碼加入日誌來定位問題,極度不爽。

在使用Google大神在StackOverflow上找了一堆文章檢視後發現兩種解決方案:
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,結合了[url=http://sishuok.com/forum/blogPost/list/4120.html]《深入剖析Tomcat 》第8章 Loader [/url]這篇文章,發現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)

最後,祝各位喜歡折騰的朋友好運。