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