Jacoco-JVM-Args und todsichere JVM-Args können in Maven nicht zusammen verwendet werden

Ich benutze Maven mit demjacoco Plugin zum Generieren von Kennzahlen zur Codeabdeckung. Ich habe einige Schwierigkeiten bei der Konfiguration dertodsicher Plugin mit den Java-Optionen, die von derjacoco Plugin. Ich habe bereits bei Stack Overflow einige Antworten dazu gesehen, aber bei mir funktioniert etwas nicht.

Ich habe ein Projekt mit mehreren Modulen und eines meiner Module konfiguriert dastodsicher Plugin wie folgt:

foo/pom.xml:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>-XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
</plugins>

Das funktioniert wie erwartet.

Jetzt möchte ich jacoco einbinden, um Kennzahlen zur Codeabdeckung zu erhaltenCodeCoverage Profil, das die gesamte Jacoco-Konfiguration verarbeitet:

parent/pom.xml:

<profile>
  <id>CodeCoverage</id>
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.jacoco</groupId>
          <artifactId>jacoco-maven-plugin</artifactId>
          <executions>
            <execution>
              <id>jacoco-initialize</id>
              <goals><goal>prepare-agent</goal></goals>
              <configuration>
                <propertyName>surefire.argLine</propertyName>
              </configuration>
              ...
            </execution>
          <executions> 
        </plugin>
      </plugins>
    </pluginManagement>
  </build>   
</profile>

Es ist hier zu sehen, dass, wenn dieCodeCoverage Profil angegeben ist, dann diejacoco Plugin ist so konfiguriert, dass es das verwendetsurefire.argLine Eigenschaft, und diese Eigenschaft wird verwendet, um die zu konfigurierenargLine für dietodsicher Plugin.

Ich habe dann das aktualisiertpom.xml Datei für diefoo Modul zur Verwendung dersurefire.argLine Eigentum generiert von derjacoco Plugin:

foo/pom.xml:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>${surefire.argLine} -XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
</plugins>

Dieser Ansatz ist in derjacoco Plugin-Dokumentation (siehe [1]).

Wenn ich die bauefoo Modul mit derCodeCoverage Profil sehe ich folgendes:

[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 -->
[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`

Also diejacoco Plugin wird ausgeführt, asurefire.argLine Eigenschaft erstellt wird, dieargLine für dietodsicher Plugin verwendet diesurefire.argLine Eigentum und die lokaleMaxPermSize Argument und atarget\code-coverage\jacoc-ut-exec Datei wird erwartet generiert.

Allerdings, wenn ich das nicht benutzeCodeCoverage Profil bekomme ich dann einen Fehler, weil der${surefire.argLine} Eigentum (verwendet infoo/pom.xml) wird nicht von der erstelltjacoco Plugin und ist nirgends definiert:

[foo] $ mvn clean install -X
...
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator -->
[DEBUG]   (s) argLine = ${surefire.argLine} -XX:MaxPermSize=512m
...
Error: Could not find or load main class ${surefire.argLine}`

Sinec diejacoco Plugin wurde nicht aufgerufen, es gibt keinesurefire.argLine Eigenschaft erstellt, daher der Fehler.

Also gehe ich zurück zumparent/pom.xml und erstellen Sie diese Eigenschaft ohne Anfangswert:

parent/pom.xml:

<properties>
  <surefire.argLine></surefire.argLine>
</properties>

Jetzt wenn ich das bauefoo Modul ohne Verwendung derCodeCoverage Profil erhalte ich keine Fehler:

[foo] $ mvn clean install -X
...
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator -->
[DEBUG]   (s) argLine =  -XX:MaxPermSize=512m
...
[INFO] BUILD SUCCESS`

Dastodsicher argline ist nun korrekt (mit dem leerensurefire.argLine Eigentum) und es gibt keinetarget\code-coverage Verzeichnis, wie erwartet.

Jetzt gehe ich zurück zum Generieren von Codemetriken mit demCodeCoverage Profil:

[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 -->
[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

Hier ist zu beobachten, dass diejacoco Plugin wird aufgerufen und setzt dassurefire.argLine Eigentum, aber diesurefire.argLine Eigenschaft mit dem leeren Wert, der in definiert istparent/pom.xml Datei wird tatsächlich verwendet, um die Gliederung für die zu erstellentodsicher Plugin.

Infolgedessen gibt es keinejacoco-ut.exec Datei und neintarget\code-coverage Verzeichnis, wenn ich das verwendeCodeCoverage Profil.

Ich bin nicht sicher, was ich hier falsch mache. Ich erkläre einargLine Eigentum, wie von der vorgeschlagenjacoco Dokumentation und Verwendung, wann immer atodsicher Das Plugin muss ein zusätzliches Argument angeben. Andere Antworten zu Stack Overflow schlagen vor, eine Eigenschaft mit demselben Namen wie die zu erstellenjacoco argLine-Eigenschaft, die den Fall behandelt, wennjacoco wird nicht aufgerufen.

Irgendwelche Vorschläge?

bearbeiten

Vielleicht besteht eine Lösung darin, das explizit zu deklarierensurefire.argLine Eigentum in derCodeCoverage Profil, und vergessen Sie die Verwendung derargLine desjacoco Plugin:

<profile>
  <id>CodeCoverage</id>
  <properties>
    <surefire.argLine>-javaagent:${jacoco.agent.jar}=destfile=${jacoco.report.path}</surefire.argLine>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>jacoco-initialize</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
            <!-- no longer specifying 'argLine' for jacoco plugin ... -->  
          </execution>
        <executions> 
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <!-- ... instead the arg line is configured explicitly for surefire plugin. -->
          <argLine>${surefire.argLine}</argLine>
        </configuration>
      </plugin>
    </plugins>
  </plugin>
</build>

Dadurch wird das erstellttodsichere.argLine Eigenschaft, um den Java-Agenten zu verwenden, der von derjacoco Plugin, und konfigurieren Sie dietodsicher Plugin, um diese Eigenschaft für seine JVM-Argumente zu verwenden. Dasjacoco Das Plugin erstellt nun einargLine Eigenschaft, aber dies wird ignoriert. Es ist keine elegante Lösung (da ich Annahmen darüber mache, wie diejacoco Plugin funktioniert, und dies kann sich in einer zukünftigen Version ändern).

bearbeiten

Dasjacoco.agent.jar Die Eigenschaft muss auch festgelegt werden, indem auf den Speicherort im lokalen Repository verwiesen wird (nicht sicher, ob dies zuverlässig ist) oder indem die Option verwendet wirdAbhängigkeit Plugin zum Kopieren derjacoco Agent-JAR in das lokale Build-Verzeichnis:

<profile>
  <id>CodeCoverage</id>
  <properties>
    <jacoco.agent.jar>${project.build.directory}/jacoco-agent.jar</jacoco.agent.jar>
    ...
  </project>
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>download-jacoco-agent</id>
            <phase>process-test-resources</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <artifactItems>
                <artifactItem>
                  <groupId>org.jacoco</groupId>
                  <artifactId>org.jacoco.agent</artifactId>
                  <version>${jacoco.version}</version>
                  <classifier>runtime</classifier>
                  <outputDirectory>${project.build.directory}</outputDirectory>
                  <destFileName>jacoco-agent.jar</destFileName>
                </artifactItem>
              </artifactItems>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>

bearbeiten

Ich bin mir nicht sicher, ob ich dieAbhängigkeit Das Plugin ist der richtige Ansatz, oder es verweist auf das Artefakt des Jacoco-Agenten im lokalen Repository:

<profile>
  <id>CodeCoverage</id>
  <properties>
    <jacoco.agent.jar>${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar</jacoco.agent.jar>
  </properties>
  ...
</profile>

Dies ist einfacher und erfordert kein Kopieren eines Artefakts in das lokale Erstellungsverzeichnis, ist jedoch fragil: Änderungen im Repository-Layout können dies verhindern.

[1]http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html

Antworten auf die Frage(10)

Ihre Antwort auf die Frage