title: Cannot use jacoco JVM args and surefire JVM args together in maven
body: <p>I am using maven with the <em>jacoco</em> plugin to generate code coverage metrics. I am having some difficulty in configuring the <em>surefire</em> plugin with the java options required by the <em>jacoco</em> plugin. I've seen some answers about this already on Stack Overflow but something is not working for me.</p>
  
  <p>I have a multi-module project, and one of my modules configures the <em>surefire</em> plugin as follows:</p>
  
  <p><code>foo/pom.xml</code>:</p>
  
  <pre><code>&lt;plugins&gt;
    &lt;plugin&gt;
      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
      &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
      &lt;configuration&gt;
        &lt;argLine&gt;-XX:MaxPermSize=512m&lt;/argLine&gt;
      &lt;/configuration&gt;
    &lt;/plugin&gt;
  &lt;/plugins&gt;
  </code></pre>
  
  <p>This works as expected.</p>
  
  <p>Now I want to incorporate jacoco to get code coverage metrics, so I added a <em>CodeCoverage</em> profile that handles all the jacoco configuration:</p>
  
  <p><code>parent/pom.xml</code>:</p>
  
  <pre><code>&lt;profile&gt;
    &lt;id&gt;CodeCoverage&lt;/id&gt;
    &lt;build&gt;
      &lt;pluginManagement&gt;
        &lt;plugins&gt;
          &lt;plugin&gt;
            &lt;groupId&gt;org.jacoco&lt;/groupId&gt;
            &lt;artifactId&gt;jacoco-maven-plugin&lt;/artifactId&gt;
            &lt;executions&gt;
              &lt;execution&gt;
                &lt;id&gt;jacoco-initialize&lt;/id&gt;
                &lt;goals&gt;&lt;goal&gt;prepare-agent&lt;/goal&gt;&lt;/goals&gt;
                &lt;configuration&gt;
                  &lt;propertyName&gt;surefire.argLine&lt;/propertyName&gt;
                &lt;/configuration&gt;
                ...
              &lt;/execution&gt;
            &lt;executions&gt; 
          &lt;/plugin&gt;
        &lt;/plugins&gt;
      &lt;/pluginManagement&gt;
    &lt;/build&gt;   
  &lt;/profile&gt;
  </code></pre>
  
  <p>It is seen here that if the <em>CodeCoverage</em> profile is specified, then the <em>jacoco</em> plugin is configured to use the <code>surefire.argLine</code> property, and that property is used to configure the <code>argLine</code> for the <em>surefire</em> plugin.</p>
  
  <p>I then updated the <em>pom.xml</em> file for the <em>foo</em> module to use the <code>surefire.argLine</code> property generated by the <em>jacoco</em> plugin:</p>
  
  <p><code>foo/pom.xml</code>:</p>
  
  <pre><code>&lt;plugins&gt;
    &lt;plugin&gt;
      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
      &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
      &lt;configuration&gt;
        &lt;argLine&gt;${surefire.argLine} -XX:MaxPermSize=512m&lt;/argLine&gt;
      &lt;/configuration&gt;
    &lt;/plugin&gt;
  &lt;/plugins&gt;
  </code></pre>
  
  <p>This approach is specified in the <em>jacoco</em> plugin documentation (see [1]).</p>
  
  <p>When I build the <em>foo</em> module with the <em>CodeCoverage</em> profile, I see the following:</p>
  
  <pre><code>[foo] $ mvn clean install -X -PCodeCoverage
  ...
  [INFO] --- jacoco-maven-plugin:0.7.0.201403182114:prepare-agent (jacoco-initialize) @ foo ---
  [INFO] surefire.argLine set to -javaagent:...\\org.jacoco.agent\\0.7.0.201403182114\\org.jacoco.agent-0.7.0.201403182114-runtime.jar=destfile=...\foo\\\target\\coverage-reports\\jacoco-ut.exec
  ...
  [DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator --&gt;
  [DEBUG]   (s) argLine = -javaagent:...\\org.jacoco.agent\\0.7.0.201403182114\\org.jacoco.agent-0.7.0.201403182114-runtime.jar=destfile=...\\foo\\target\\coverage-reports\\jacoco-ut.exec -XX:MaxPermSize=512m
  ...
  [INFO] --- jacoco-maven-plugin:0.7.0.201403182114:report (jacoco-site) @ foo ---
  [INFO] Analyzed bundle 'Foo' with 59 classes`
  </code></pre>
  
  <p>So the <em>jacoco</em> plugin is executed, a <code>surefire.argLine</code> property is created, the <code>argLine</code> for the <em>surefire</em> plugin uses the <code>surefire.argLine</code> property and the local <code>MaxPermSize</code> argument, and a <code>target\code-coverage\jacoc-ut-exec</code> file is generated, as expected.</p>
  
  <p>However, if I do not use the <em>CodeCoverage</em> profile, then I get an error, because the <code>${surefire.argLine}</code> property (used in <code>foo/pom.xml</code>) is not created by the <em>jacoco</em> plugin, and is not defined anywhere:</p>
  
  <pre><code>[foo] $ mvn clean install -X
  ...
  [DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator --&gt;
  [DEBUG]   (s) argLine = ${surefire.argLine} -XX:MaxPermSize=512m
  ...
  Error: Could not find or load main class ${surefire.argLine}`
  </code></pre>
  
  <p>Sinec the <em>jacoco</em> plugin was not invoked, there's no <code>surefire.argLine</code> property created, hence the error. </p>
  
  <p>So, I go back to the <code>parent/pom.xml</code> and create this property, with no initial value:</p>
  
  <p><code>parent/pom.xml</code>:</p>
  
  <pre><code>&lt;properties&gt;
    &lt;surefire.argLine&gt;&lt;/surefire.argLine&gt;
  &lt;/properties&gt;
  </code></pre>
  
  <p>Now when I build the <em>foo</em> module without using the <em>CodeCoverage</em> profile, I get no errors:</p>
  
  <pre><code>[foo] $ mvn clean install -X
  ...
  [DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator --&gt;
  [DEBUG]   (s) argLine =  -XX:MaxPermSize=512m
  ...
  [INFO] BUILD SUCCESS`
  </code></pre>
  
  <p>The <em>surefire</em> argline is now correct (using the empty <code>surefire.argLine</code> property) and there is no <code>target\code-coverage</code> directory, as expected.</p>
  
  <p>So now I go back to generating code metrics, using the <em>CodeCoverage</em> profile:</p>
  
  <pre><code>[foo] $ mvn clean install -X -PCodeCoverage
  ...
  [INFO] --- jacoco-maven-plugin:0.7.0.201403182114:prepare-agent (jacoco-initialize) @ foo ---
  [INFO] surefire.argLine set to -javaagent:...\\org.jacoco.agent\\0.7.0.201403182114\\org.jacoco.agent-0.7.0.201403182114-runtime.jar=destfile=...\\foo\\target\\coverage-reports\\jacoco-ut.exec
  ...
  [DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator --&gt;
  [DEBUG]   (s) argLine =  -XX:MaxPermSize=512m
  ...
  [INFO] --- jacoco-maven-plugin:0.7.0.201403182114:report (jacoco-site) @ foo ---
  [INFO] Skipping JaCoCo execution due to missing execution data file:...\foo\target\coverage-reports\jacoco-ut.exec
  </code></pre>
  
  <p>It can be observed here that the <em>jacoco</em> plugin is invoked and sets the <code>surefire.argLine</code> property, but the <code>surefire.argLine</code> property with the empty value defined in the <code>parent/pom.xml</code> file is actually used to create the argline for the <em>surefire</em> plugin.</p>
  
  <p>As a result, there is no <code>jacoco-ut.exec</code> file, and no <code>target\code-coverage</code> directory, when I use the <em>CodeCoverage</em> profile.</p>
  
  <p>I'm not sure what I am doing wrong here. I'm declaring an <code>argLine</code> property as suggested by the <em>jacoco</em> documentation, and using it whenever a <em>surefire</em> plugin needs to specify additional argument. Other answers on Stack Overflow suggest creating a property with the same name as the <em>jacoco</em> argLine property to handle the case when <em>jacoco</em> is not invoked.</p>
  
  <p>Any suggestions?</p>
  
  <p><strong>edit</strong> </p>
  
  <p>Maybe one solution is to explicitly declare the <code>surefire.argLine</code> property in the <em>CodeCoverage</em> profile, and forget about using the <code>argLine</code> of the <em>jacoco</em> plugin:</p>
  
  <pre><code>&lt;profile&gt;
    &lt;id&gt;CodeCoverage&lt;/id&gt;
    &lt;properties&gt;
      &lt;surefire.argLine&gt;-javaagent:${jacoco.agent.jar}=destfile=${jacoco.report.path}&lt;/surefire.argLine&gt;
    &lt;/properties&gt;
    &lt;build&gt;
      &lt;plugins&gt;
        &lt;plugin&gt;
          &lt;groupId&gt;org.jacoco&lt;/groupId&gt;
          &lt;artifactId&gt;jacoco-maven-plugin&lt;/artifactId&gt;
          &lt;executions&gt;
            &lt;execution&gt;
              &lt;id&gt;jacoco-initialize&lt;/id&gt;
              &lt;goals&gt;
                &lt;goal&gt;prepare-agent&lt;/goal&gt;
              &lt;/goals&gt;
              &lt;!-- no longer specifying 'argLine' for jacoco plugin ... --&gt;  
            &lt;/execution&gt;
          &lt;executions&gt; 
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
          &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
          &lt;configuration&gt;
            &lt;!-- ... instead the arg line is configured explicitly for surefire plugin. --&gt;
            &lt;argLine&gt;${surefire.argLine}&lt;/argLine&gt;
          &lt;/configuration&gt;
        &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/plugin&gt;
  &lt;/build&gt;
  </code></pre>
  
  <p></p>
  
  <p>This will create the <em>surefire.argLine</em> property to use the java agent required by the <em>jacoco</em> plugin, and configure the <em>surefire</em> plugin to use that property for its JVM args. The <em>jacoco</em> plugin will now create a <em>argLine</em> property, but this will be ignored. It's not an elegant solution (since I'm making assumptions about how the <em>jacoco</em> plugin works, and this may change in a future version).</p>
  
  <p><strong>edit</strong> </p>
  
  <p>The <code>jacoco.agent.jar</code> property must also be set, by pointing to its location in the local repository (not sure if this is robust) or by using the <em>dependency</em> plugin to copy the <em>jacoco</em> agent jar to the local build directory:</p>
  
  <pre><code>&lt;profile&gt;
    &lt;id&gt;CodeCoverage&lt;/id&gt;
    &lt;properties&gt;
      &lt;jacoco.agent.jar&gt;${project.build.directory}/jacoco-agent.jar&lt;/jacoco.agent.jar&gt;
      ...
    &lt;/project&gt;
    &lt;build&gt;
      ...
      &lt;plugins&gt;
        &lt;plugin&gt;
          &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
          &lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
          &lt;executions&gt;
            &lt;execution&gt;
              &lt;id&gt;download-jacoco-agent&lt;/id&gt;
              &lt;phase&gt;process-test-resources&lt;/phase&gt;
              &lt;goals&gt;
                &lt;goal&gt;copy&lt;/goal&gt;
              &lt;/goals&gt;
              &lt;configuration&gt;
                &lt;artifactItems&gt;
                  &lt;artifactItem&gt;
                    &lt;groupId&gt;org.jacoco&lt;/groupId&gt;
                    &lt;artifactId&gt;org.jacoco.agent&lt;/artifactId&gt;
                    &lt;version&gt;${jacoco.version}&lt;/version&gt;
                    &lt;classifier&gt;runtime&lt;/classifier&gt;
                    &lt;outputDirectory&gt;${project.build.directory}&lt;/outputDirectory&gt;
                    &lt;destFileName&gt;jacoco-agent.jar&lt;/destFileName&gt;
                  &lt;/artifactItem&gt;
                &lt;/artifactItems&gt;
              &lt;/configuration&gt;
            &lt;/execution&gt;
          &lt;/executions&gt;
        &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/build&gt;
  &lt;/profile&gt;
  </code></pre>
  
  <p><strong>edit</strong> </p>
  
  <p>Not sure if using the <em>dependency</em> plugin is the right approach, or pointing to the jacoco agent artifact in the local repository:</p>
  
  <pre><code>&lt;profile&gt;
    &lt;id&gt;CodeCoverage&lt;/id&gt;
    &lt;properties&gt;
      &lt;jacoco.agent.jar&gt;${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar&lt;/jacoco.agent.jar&gt;
    &lt;/properties&gt;
    ...
  &lt;/profile&gt;
  </code></pre>
  
  <p>This is simpler, and does not require copying an artifact to the local build directory, but is fragile: changes in the repository layout will break this.</p>
  
  <p>[1] <a href="http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html" rel="noreferrer">http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html</a></p>