I want to use Cobertura code coverage recording in my web application, but can’t get it to work. I suspect, the problem is some conflict between Spring or Hibernate and Cobertura since all three use the ASM lib to do their byte code manipulation.
I did the following:
- I used the Cobertura Ant task to instrument my jars in “WEB-INF/lib” and generated the “cobertura.ser” file
- I added the “cobertura.jar” to “WEB-INF/lib”
- I start tomcat providing cobertura file location (net.sourceforge.cobertura.datafile=cobertura.ser)
When I start Tomcat, I get the following error message when the Spring context is initialized:
java.lang.NoSuchMethodException: com.foo.MyClass.setInstance($Proxy28)
at com.foo.common.runtime.spring.PluginInjector.findBestMatchingMethod(PluginInjector.java:252)
at com.foo.common.runtime.spring.PluginInjector.invokeMethod(PluginInjector.java:198)
at com.foo.common.runtime.spring.PluginInjector.afterPropertiesSet(PluginInjector.java:174)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
I’m already aware, that the asm.jar that comes with cobertura should not be in the classpath and therefore I only copied cobertura.jar to WEB-INF\lib.
Besides, I also tried Emma and it worked. However, cobertura looks more modern, active (last update from 2010 instead of 2005) and generates nicer reports so I would prefer it over Emma.
I had to make two changes, to make this work:
I had to set
proxy-target-class="true"in the Spring configuration, so Spring uses CGLIB to generate proxies instead of using JDK dynamic proxies (see Spring Proxying mechanisms).I had to set the JVM Parameter
-XX:-UseSplitVerifier, which causes the JVM to use the old byte code verifier. This seems to be necessary since Cobertura’s byte code manipulation is incompatible with Java 7.