How to configure boot time using Spring and Tomcat WITHOUT using -javaagent on the command line

I am using Spring 3.2.9, Tomcat 6.0.44

I am trying to configure a Spring provider application (e.g. spring -instrumentation.jar) to load at boot time when deploying it to Tomcat.

I have a requirement NOT to use: "-javaagent: / path / path / spring -instrument.jar" on the command line to complete the configuration.

I read that I can configure the Spring appliance by changing the <Context> element of my Tomcat configuration application (in Tomcat server.xml or in my web application context.xml). Adding the appropriate <Context> element to server.xml causes my application to be properly configured to work with the Spring hardware provider. Adding it to context.xml (see below) does NOT result in a working configuration.

I have a META-INF / aop.xml file that 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> 

I also indicate that I want to use time-based recoding by adding this to the Spring context configuration:

  <context:load-time-weaver /> 

And I add this jar to my path to the application class: spring -instrument-tomcat.jar

WHAT I EXCLUDE:

When starting Tomcat, if I locate spring -instrument.jar on the command line using the -javaagent parameter as follows:

 -javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar 

Everything is working fine.


Then I removed "-javaagent: / path / path2 / spring -instrument-3.2.9.RELEASE.jar" from the command line. In the Tomcat server.xml file (located at $ CATALINE_HOME / conf), I added a <Context> element to the <Host> element, for example:

 <Context path="/myApp" docBase="myApp"> <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/> </Context> 

With this configuration, everything behaves correctly. However, I have a requirement not to modify Tomcat server.xml, since I have no control over server.xml (DevOps does and does not want to change it).


Then I deleted <Context> from Tomcat server.xml. According to Spring docs , I can add / META -INF / context.xml to my webapp and put the <Context> that used to be in Tomcat server.xml in the .xml context, for example:

  <Context> <Context path="/myApp" docBase="myApp"> <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/> </Context> </Context> 

However, when I restart Tomcat, an error message appears in the logs:

  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 agent: -javaagent:org.springframework.instrument.jar 

After digging, I read something that suggested changing the <context:load-time-weaver/> element in my Spring configuration, for example:

  <context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 

And add the jar containing InstrumentationLoadTimeWeaver.class to my classpath.

However, when I do this, 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.... 

Can anyone explain how to set up temporary weaving with Spring and Tomcat WITHOUT using -javaagent on the command line and WITHOUT modifying server.xml?

+6
source share
3 answers

This is the code that I was able to use to remove the exception you were talking about. Basically you need to implement LoadTimeWeavingConfigurer and override the getLoadTimeWeaver () method.

 @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; } } 
0
source

I used invesdwin-instrument to accomplish this. This allows you to dynamically use load time measuring tools, so you do not need to use any kind of javaagent.

It took me a bit of effort to work with Tomcat 8.5. But it finally works using this configuration using Spring Boot:

 @SpringBootApplication @EnableLoadTimeWeaving // instead of @ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml") public class MySpringBootApplication { public static void main(final String[] args) { DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes } } 

It should also work with a previous version of Tomcat.

Hi

0
source
 https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving 

Try connecting to maven from the link above. he works

-one
source

All Articles