How to run Jacoco with Java 7 and spring-instrumen

2019-07-19 17:29发布

问题:

Since I had some problems using cobertura with Java 7 - I'm trying Jacoco. My project has a parent pom.xml and sub projects. In one project I use spring to run some integration tests - so I have this plugin in this project's pom.xml:

<plugin>
    <version>2.12.4</version>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <!-- -XX:-UseSplitVerifier is for java 7 -->
        <argLine>
            -XX:-UseSplitVerifier 
            -javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring.version}/spring-instrument-${spring.version}.jar
        </argLine>
    </configuration>
</plugin>

Since I use Java 7, I've set this plugin in the parent pom.xml:

<plugin>
    <version>2.5.1</version>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
    <source>1.7</source>
    <target>1.7</target>
    <optimize>true</optimize>
    <debug>true</debug>
    <showDeprecation>true</showDeprecation>
    <showWarnings>true</showWarnings>
    <encoding>utf8</encoding>
    </configuration>
</plugin>

Now, when I'm using mvn clean install all the projects have this file in the /target folder: jacoco.exec ; But this project that uses the spring-instrument does not have this file. I think the problem is that Jacoco wishes to use the asm of spring-instrument but it fails (but I'm not sure I'm right).

The Jacoco version is 0.6.3.201306030806.

Why does Jacoco fails to instrument in this case? How can I overcome this?

I thought maybe I can configure the maven-compiler-plugin to compile the code to 1.6 and then I wouldn't need the maven-surefire-plugin plugin. Does it make sense?

回答1:

The argLine value defined by Jacoco Maven Plugin is being rewritten by the Surefire Plugin.

Set a property name in your "jacoco-maven-plugin" configuration like this:

<propertyName>coverageAgent</propertyName>

and then edit the argLine in your surefire plugin configuration so it includes Jacoco's agent:

<argLine>
    -XX:-UseSplitVerifier
    ${coverageAgent} 
    -javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring.version}/spring-instrument-${spring.version}.jar
</argLine>

Notice that the Jacoco's agent is placed before the Spring's Instrument. That's the way it should be done because Jacoco has problems dealing with modified bytecode (e.g. the one produced by AspectJ LTW).

Actually, even when being the first agent, Jacoco's reports can still be wrong, but the problem is usually limited to a small set of circumstances (e.g. http://sourceforge.net/p/eclemma/discussion/614869/thread/3d875388 ).



回答2:

my guess is that JaCoCo also uses the java command line, as it is probably implemented as a javaagent.

could it be that the spring-instrument javaagent overrides the JaCoCo one ?