mardi 24 février 2015

Gradle Failing to run Spring integration tests with Load-time Weaving

I got stuck trying to make my Spring Integration tests run again in gradle build after I enabled load-time weaving.


I have a RESTful Web application implemented using Spring MVC, and I have a set of Spring integration tests that were working fine, but after enabling weaving they started to fail. Actually the test don't fail, it is just Gradle execution of my tests what fails. The application works just fine if I run it in the actual container.


This is my configuration. First, I enabled load-time weaving and I am using it for my transactional behavior. This is on my application context configuration file:



<context:load-time-weaver aspectj-weaving="autodetect"/>
<tx:annotation-driven mode="aspectj"/>


Since I am using Tomcat, I followed the specifications on the Spring Documentation, and I have added the spring-instrument-tomcat.jar to my $CATALINA_BASE/lib folder.


And I have added a context file to my webapp/META-INF directory containing the following:



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


All this worked liked a charm form me. Application runs just fine and exhibits expected behavior.


Now if I run my integration tests directly from IDE (IntelliJ in my case), I managed to make them run perfectly by using an agent. So, if I add this to my jvm arguments in the IDE run configuration my tests run just fine:



-javaagent:pring-instrument.jar


However, I have not been able to figure out where to place this Java agent configuration so that my gradle build uses it while running the integration tests.


I have tried different things, like setting the the gradle.properties by using the org.gradle.jvmargs property. I have also tried configuring the the jvmargs for the test task. I have even configured the JVM options directly in the gradle executable script used from my OS shell.


Unfortunately nothing has worked. Spring fails to create the loadTimeWeaver bean with an exception that among other things contains the following details:



Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver]: Constructor threw exception; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method.
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1086)
... 69 more
Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method.
at org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver.<init>(ReflectiveLoadTimeWeaver.java:104)
at org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver.<init>(ReflectiveLoadTimeWeaver.java:86)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 71 more


It looks like my Java agent is being ignored by the gradle build. I have managed to make this work with Maven, for instance, configuring the command line arguments passed to the surefire plugin, but with Gradle I have no clue how to make it work.


Does anyone know how can I enable this in Gradle?


Aucun commentaire:

Enregistrer un commentaire