Maven JaCoCo plugin error

后端 未结 5 1282
温柔的废话
温柔的废话 2020-12-05 05:01

I have configured the Maven JaCoCo plugin as follows in my pom.xml file:


    UTF-8         


        
5条回答
  •  醉酒成梦
    2020-12-05 05:49

    OK I think I figured out what is going on.

    By default, the jacoco plugin "runs" before the test phase (typically it runs the prepare-agent goal during the initialize lifecycle phase), and when it runs, it just sets a maven property called "argLine" to something like -javaagent=jacoco.jar

    ex:

    [INFO] argLine set to -javaagent:/usernamed/.m2/repository/org/jacoco/org.jacoco.agent/ 0.5.6.201201232323/org.jacoco.agent-0.5.6.201201232323-runtime.jar=destfile=/path/to/target/jacoco.exec

    By default, maven-surefire-plugin basically "prepends" this property (if it's set to anything) to its forked java test processes, so they get the goods. Ex: java ${argLine ends up here}> -jar /xxx/surefirebooter3741906822495182152.jar

    Typically (without jacoco), if you want to also add something else of your own to that argLine (for instance, -Xmx1G or the like), you just set it in the surefire configuration, like

     
       
        
           maven-surefire-plugin
             
                -Xmx1G
              
         
    

    However, if you're using jacoco, you can't do it the normal way you do it by setting a global property, this way instead (this is the pom's root global properties):

      
        -Xmx1G
      
    

    If you do set the then it basically overrides the system property, so jacoco arguments aren't passed down to the child process. So that's why you use the property way instead. If you specify a property argLine then jacoco will just add its parameters to whatever you specify, then surefire will use it.

    However, what if your parent pom has already set the plugin's to something? Or if you yourself are setting it? It will basically use that value instead of the property that jacoco is setting (you've specified a manual override).

    If you're specifying yourself, you can change that argLine into a property (see above), and remove the and it should work. If you can't control the parent, and the parent specifies something for argline, then you'll need to go the the ${argLine} -Xmx1G route. This is to instruct it to ignore whatever the parent set this value to, and use argLine instead (the one jacoco sets for you). (It's unclear to me if there's an easy way to "add" to the value the parent pom has for this value, if anybody knows how feel free to comment here).

    But what if jacoco doesn't run for some target, or some profile? Then the variable ${argLine} never gets set, and you can run into an error like this:

    Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.14:test failed: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ? [ERROR] Command was/bin/sh -c cd ...java '${argLine}' ...

    Well it turns out that jacoco only "adds" to the property named argLine, when it runs. So you can safely add a to your pom (unless you already have that set in the parent pom, then you don't need to add anything). If jacoco is ever invoked, it adds to it. If not, it's set to an empty string, which is OK. It's also unclear if there's a way to "add" to the parent's value for a property, so it's either inherit it, if you know it exists, or specify it as empty.

    So, in the end for me, since my upstream (inaccessible) parent pom declared it like

    ${argList}

    I was forced to basically follow that route, since it was set already in an (out of my control) parent pom, thusly:

    ${argList} -Xmx1G

    NB that Intellij will complain and "not add any settings" to your unit test if you have this in your pom:

    ${argLine} -DcustomOption=X...

    but don't declare a property named argLine at all (even though it works on the command line mvn just fine). Fix/work around: declare an empty 'argLine' global property, and/or just move your -DcustomOption=X to the property declaration instead, see above. If you "only" set it in the property declaration then for IntelliJ to pick it up you'll also need ${argLine}... :|

    Unfortunately even this wasn't enough, it hosed sonar, though worked with IntelliJ + maven. Not sure why. Changed the way I parsed times instead, so didn't have to mess with the zones (i.e. "got them right" in the code).

提交回复
热议问题