如何在命令行上使用-javaagent来设置Spring和Tomcat的加载时织法 [英] how to setup load-time weaving with Spring and Tomcat WITHOUT using the -javaagent on the command line
问题描述
我正在使用Spring 3.2.9,Tomcat 6.0.44
I am using Spring 3.2.9, Tomcat 6.0.44
我正在尝试将应用程序的Spring工具提供程序(例如spring-instrumentation.jar)配置为在Tomcat上部署时进行加载时编织.
I am trying to configure my application's Spring instrumentation provider (e.g. spring-instrumentation.jar) for load-time weaving, when it is deployed on Tomcat.
我有一个要求不要使用: 在命令行上"-javaagent:/path/path/spring-instrument.jar"进行配置.
I have a requirement to NOT use: "-javaagent:/path/path/spring-instrument.jar" on the command line to do the configuration.
我已阅读到可以通过修改< Context>配置Spring工具.应用程序的Tomcat配置的元素(在Tomcat的server.xml或Web应用程序的context.xml中).添加适当的< Context> server.xml的元素导致我的应用程序被正确配置为与Spring的工具提供程序一起运行.将其添加到context.xml(请参见下文)不会导致工作设置正常.
I've read that I can configure the Spring instrumentation by modifying the <Context> element of my application's Tomcat configuration (in either Tomcat's server.xml or my web app's context.xml). Adding the appropriate <Context> element to the server.xml results in my application being correctly configured to run with Spring's instrumentation provider. Adding it to the context.xml (see below) does NOT result in a working setup.
我有一个META-INF/aop.xml文件,看起来像这样:
I have a META-INF/aop.xml file, looks like this:
<aspectj>
<weaver options="-verbose -showWeaveInfo -debug">
<include within="com.mv.xx.services..*"/>
<exclude within="com.mv.xx.aop..*"/>
</weaver>
<aspects>
<aspect name="com.mv.xx.aop.MyAspect"/>
</aspects>
</aspectj>
我还通过将其添加到我的Spring上下文配置中来指定要使用加载时编织:
I also specify that I want to use load-time weaving by adding this to my Spring context config:
<context:load-time-weaver />
然后将这个jar添加到我的应用程序的类路径中: spring-instrument-tomcat.jar
And I add this jar to my application's classpath: spring-instrument-tomcat.jar
我尝试过的内容:
启动Tomcat时,如果我使用-javaagent参数像这样在命令行上标识spring-instrument.jar的位置:
When starting Tomcat, If I identify the location of the spring-instrument.jar on the command line using the -javaagent parameter like this:
-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar
一切正常.
接下来,我从命令行中删除了"-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar". 在Tomcat的server.xml文件(位于$ CATALINE_HOME/conf中)中,我添加了一个< Context> < Host>元素的元素元素,像这样:
Next I removed "-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar" from the command line. In Tomcat's server.xml file (located in $CATALINE_HOME/conf), I added a a <Context> element to the <Host> element, like this:
<Context path="/myApp" docBase="myApp">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
使用此配置,所有行为均正常运行.但是我有一个要求不要修改Tomcat的server.xml,因为我无法控制server.xml(DevOps可以,并且不愿对其进行修改).
With this configuration everything behaves properly. However I have a requirement to not modify Tomcat's server.xml, since I don't have control over the server.xml (DevOps does, and is reluctant to modify it).
接下来,我删除了< Context> Tomcat的server.xml中的元素. 根据
Next I removed the <Context> element from Tomcat's server.xml. According to the Spring docs, I can add a /META-INF/context.xml to my webapp, and put the <Context> element that used to be in Tomcat's server.xml into the context.xml, like so:
<Context>
<Context path="/myApp" docBase="myApp">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
</Context>
但是,当我重新启动Tomcat时,我在日志中收到一条错误消息,内容为:
However when I restart Tomcat, I get an error message in the logs saying:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.apache.catalina.loader.WebappClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
深入研究之后,我读到一些建议,建议修改Spring配置中的<context:load-time-weaver/>
元素,如下所示:
After digging around, I read something that suggested that I modify the <context:load-time-weaver/>
element in my Spring config, like this:
<context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
然后将包含InstrumentationLoadTimeWeaver.class的jar添加到我的类路径中.
And add the jar containing InstrumentationLoadTimeWeaver.class to my classpath.
但是,当我这样做时,我会在日志中收到以下错误消息:
However when I do that, I get this error message in the logs:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
etc....
任何人都可以解释如何在命令行中使用-javaagent来设置Spring和Tomcat的加载时织法,而无需修改server.xml吗?
Can anyone explain how to setup load-time weaving with Spring and Tomcat WITHOUT using the -javaagent on the command line, and WITHOUT modifying the server.xml?
推荐答案
这是我设法使用的代码,用于删除您提到的异常. 基本上,您必须实现LoadTimeWeavingConfigurer并重写方法getLoadTimeWeaver().
This is the code that I managed to use in order to removed the exception that you mentioned. Basically you have to implement the LoadTimeWeavingConfigurer and override the method getLoadTimeWeaver().
@Configuration
@ComponentScan(basePackages = "org.myproject")
@EnableAspectJAutoProxy
@EnableSpringConfigured
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT)
public class Config implements LoadTimeWeavingConfigurer {
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new ReflectiveLoadTimeWeaver();
}
@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
return loadTimeWeaver;
}
}
这篇关于如何在命令行上使用-javaagent来设置Spring和Tomcat的加载时织法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!