web-dev-qa-db-ja.com

Mavenでjacoco JVM引数とsurefire JVM引数を一緒に使用することはできません

jacocoプラグインでmavenを使用して、コードカバレッジメトリックを生成しています。 jacocoプラグインに必要なJavaオプションを使用してsurefireプラグインを構成するのが少し困難です。 Stack Overflowでこれに関するいくつかの回答を見ましたが、何かがうまくいきません。

マルチモジュールプロジェクトがあり、私のモジュールの1つが次のようにsurefireプラグインを構成します。

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>

これは期待どおりに機能します。

次に、コードカバレッジメトリックを取得するためにjacocoを組み込みたいので、すべてのjacoco構成を処理するCodeCoverageプロファイルを追加しました。

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>

CodeCoverageプロファイルが指定されている場合、jacocoプラグインはsurefire.argLineプロパティを使用するように設定され、そのプロパティはsurefireのargLineを設定するために使用されます。 プラグイン。

次に、fooモジュールのpom.xmlファイルを更新して、jacocoプラグインによって生成されたsurefire.argLineプロパティを使用します。

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>

このアプローチは、jacocoプラグインのドキュメントで指定されています([1]を参照)。

CodeCoverageプロファイルを使用してfooモジュールをビルドすると、次のように表示されます。

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

したがって、jacocoプラグインが実行され、surefire.argLineプロパティが作成され、surefireプラグインのargLinesurefire.argLineプロパティとローカルMaxPermSize引数を使用し、target\code-coverage\jacoc-ut-execファイルが予想どおりに生成されました。

ただし、CodeCoverageプロファイルを使用しないと、${surefire.argLine}プロパティ(foo/pom.xmlで使用)がjacocoプラグインによって作成されず、どこにも定義されないため、エラーが発生します。

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

jacocoプラグインが呼び出されなかったため、surefire.argLineプロパティが作成されなかったため、エラーが発生しました。

そこで、parent/pom.xmlに戻り、初期値なしでこのプロパティを作成します。

parent/pom.xml

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

CodeCoverageプロファイルを使用せずにfooモジュールをビルドすると、エラーは発生しません。

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

surefire arglineが正しくなり(空のsurefire.argLineプロパティを使用)、期待どおりtarget\code-coverageディレクトリがありません。

そこで、CodeCoverageプロファイルを使用して、コードメトリックの生成に戻ります。

[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

ここで、jacocoプラグインが呼び出され、surefire.argLineプロパティが設定されますが、surefire.argLineファイルで定義された空の値を持つparent/pom.xmlプロパティは、surefireプラグインの引数行を作成するために実際に使用されます。

その結果、CodeCoverageプロファイルを使用すると、jacoco-ut.execファイルとtarget\code-coverageディレクトリがありません。

ここで何が間違っているのかわかりません。 jacocoドキュメンテーションで示唆されているargLineプロパティを宣言し、surefireプラグインが追加の引数を指定する必要があるときはいつでもそれを使用しています。スタックオーバーフローに関する他の回答では、jacoco argLineプロパティと同じ名前のプロパティを作成して、jacocoが呼び出されない場合を処理することを提案しています。

助言がありますか?

編集

たぶん1つの解決策は、CodeCoverageプロファイルでsurefire.argLineプロパティを明示的に宣言し、jacocoプラグインのargLineの使用を忘れることです。

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

これにより、surefire.argLineプロパティが作成され、jacocoプラグインに必要なJavaエージェントが使用され、JVM argsにそのプロパティを使用するようにsurefireプラグインが構成されます。 。 jacocoプラグインはargLineプロパティを作成しますが、これは無視されます。これはエレガントなソリューションではありません(jacocoプラグインがどのように機能するかを仮定しているため、これは将来のバージョンで変更される可能性があります)。

編集

jacoco.agent.jarプロパティも設定する必要があります。これは、ローカルリポジトリ内の場所を指定するか(堅牢かどうか不明)、dependencyプラグインを使用してjacocoエージェントjarをローカルビルドディレクトリにコピーする必要があります:

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

編集

依存関係プラグインを使用するのが正しいアプローチであるか、ローカルリポジトリ内のjacocoエージェントアーティファクトを指すかどうかは不明です。

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

これは簡単で、アーティファクトをローカルビルドディレクトリにコピーする必要はありませんが、脆弱です。リポジトリレイアウトを変更すると、これが壊れます。

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

57
John Q Citizen

jacoco-maven-plugin:prepare-agentゴールはmaven-surefire-pluginの前に実行されます。${argLine}変数をmaven-surefire-pluginによって設定されたargLine値に。

例:

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.12.1</version>
  <configuration>
    <argLine>-server -ea -XX:MaxPermSize=256m -Xmx4g -XX:-UseSplitVerifier ${argLine}</argLine>
  </configuration>
</plugin>

同じ問題があり、POMの他のセクションを再構成する必要なく、この解決策が機能しました。

37
Will Gage

使用してみてください

@{argLine}

の代わりに

${argLine}

(または surefire.argLineあなたの場合)

これにより、Maven自体によって置き換えられたプロパティを読み取る代わりに、他のプラグインによって変更されたプロパティを確実に読み取ることができます。次に、MavenプロパティでargLine paramを空に設定できます。

<properties>
    <argLine></argLine>
</properties>

これで問題は発生しなくなりました。詳細: argLineの他のプラグインによって設定されたプロパティを使用するにはどうすればよいですか?

34
Kaszaq

プロジェクトが既にargLineを使用してsurefire-maven-pluginを構成している場合、プラグイン構成の一部としてではなく、プロパティとしてargLineが定義されていることを確認してください。例えば:

  <properties>
    <argLine>-your -extra -arguments</argLine>
  </properties>
  ...
  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <!-- Do not define argLine here! -->
    </configuration>
  </plugin>

結果のカバレッジ情報は実行中に収集され、デフォルトではプロセスの終了時にファイルに書き込まれます。

私のために働いた。参照: http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html

16
Sebastian

Maven-sure-fireプラグインの構成セクションに追加するのではなく、プロパティセクションにargLineプロパティを追加してみてください(以下のコードを参照)。 Jacoco mavenプラグインはこれに追加するだけで、期待どおりに動作します。

<properties>
  <argLine>-XX:MaxPermSize=512m</argLine>
</properties>

https://docs.sonarqube.org/display/PLUG/Usage+of+JaCoCo+with+Java+Plugin を参照してください

11
Faisal Feroz

私の解決策は、複数のプロファイルを使用することです。

最初のプロファイルは、surefire.argLineおよびfailsafe.argLineに空白の値を設定し、デフォルトでアクティブです。

<profile>
    <id>not-sonar</id>
    <properties>
        <surefire.argLine/>
        <failsafe.argLine/>
    </properties>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>

2番目のプロファイルにはjacocoプラグイン構成があり、デフォルトでは非アクティブです。

<profile>
<id>sonar</id>
<activation>
    <activeByDefault>false</activeByDefault>
</activation>
<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco-maven-plugin-version}</version>
            <executions>
                <execution>
                    <id>default-prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                    <configuration>
                        <propertyName>surefire.argLine</propertyName>
                    </configuration>
                </execution>
                <execution>
                    <id>default-prepare-agent-integration</id>
                    <goals>
                        <goal>prepare-agent-integration</goal>
                    </goals>
                    <configuration>
                        <propertyName>failsafe.argLine</propertyName>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
</profile>

ソナープロファイルをアクティブにすると、非ソナープロファイルは自動的にオフになります。

これは、他のプラグインを使用して作業を行うよりも少しエレガントになります。 argLineで${surefire.argLine}変数を使用できるようになりました。変数は常に存在し、ビルドの実行時に設定されます。

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

$ {surefire.argLine}に値がないためにまだ問題がある場合は、次のようにダミープロパティを設定することもできます。

<profile>
    <id>not-sonar</id>
    <properties>
        <surefire.argLine>-DdummyProperty=notUsed</surefire.argLine>
        <failsafe.argLine>-DdummyProperty=notUsed</failsafe.argLine>
    </properties>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>
4
Ardesco

私は最近同じ問題に遭遇し、あなたが説明したのと同じ結果を暗黙のうちに同じステップで実行しました。きれいな解決策は見つかりませんでした。

そのため、デバッグモードでいくつかの手順を実行しましたが、Mavenはプロパティを2回置き換えます。それは私が思ったように怠zyな方法だけでなく、熱心で怠zyな方法の両方です:

  1. 熱心に(目標が実行される前に)置き換えられます静的プロパティ(POMのpropertiesセクションで定義され、おそらくsettings.xmlも)
  2. lazily(各実行前)は置き換えられますdynamicプロパティ。

これは、空白のプロパティをデフォルトとして設定するステップが失敗した場所です。 Mavenがちょうど行きました:

  1. デフォルト値の積極的な置き換え(空白)
  2. JaCoCoは動的な値を設定します
  3. 動的な値の遅延置換(今すぐ置換するものはありません。すでに空白の値が使用されています)

最後に、解決策はデフォルト値を動的に設定することです。これは、次のようなGMavenプラグインで実行できます。

<plugin>
  <groupId>org.codehaus.gmaven</groupId>
  <artifactId>gmaven-plugin</artifactId>
  <version>1.5</version>
  <executions>
    <execution>
      <id>set-default-values</id>
      <phase>initialize</phase>
      <goals>
        <goal>execute</goal>
      </goals>
      <configuration>
        <source>
          project.properties.'surefire.argLine' = ''
        </source>
      </configuration>
    </execution>
  </executions>
</plugin>

だから今Mavenは行く:

  1. 静的プロパティの積極的な置き換え
  2. GMavenはデフォルト値を動的に設定します(プロファイルがアクティブな場合)
  3. JaCoCoは動的な値を設定します
  4. Surefireは正しく設定されたargLineで実行されます

アクティブプロファイルではexecファイルが生成され、非アクティブプロファイルでは空白のデフォルト値が使用され、ビルドが成功します。

4
Mrkvozrout

Maven-surefire-pluginでargLineを安全に使用するための私のソリューション。

<plugin>
    <groupId>org.codehaus.groovy.maven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>2.0</version>
    <executions>
        <execution>
            <id>set-custom-arg-line</id>
            <phase>validate</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <source>
                    def argLine = project.properties['argLine'];
                    if (argLine == null) {
                        argLine = "";
                    }
                    project.properties.argLine = argLine;
                </source>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <argLine>-Xmx1024m ${argLine}</argLine>
    </configuration>
</plugin>
2
Bernicc

POM.xmlを次のように更新します

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.7.201606060606</version>
    <executions>
      <execution>
        <goals>
            <goal>prepare-agent</goal>
        </goals>
      </execution>
      <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>report</goal>
            </goals>
      </execution>
    </executions>
</plugin>

<plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.12.1</version>
      <configuration>
         <argLine>${argLine} -XX:PermSize=256m -XX:MaxPermSize=1048m</argLine> 
      </configuration>
</plugin>

そして最も重要なことは、目標を設定してMavenプロジェクトを実行することです。mvn jacoco:prepare-agent clean test jacoco:report

1
sachit s

0.7.7.201606060606から0.7.9にバージョンをアップグレードすると、これも修正されました。

ビルドサーバーが古いバージョンを使用し続けるため、バージョンをコマンドライン(pomだけでなく)に明示的に追加する必要がありました。これは次のように実行できます。

 org.jacoco:jacoco-maven-plugin:0.7.9:prepare-agent

の代わりに

org.jacoco:jacoco-maven-plugin:prepare-agent

jacocoプラグインサイト(ソナー用) は、arglineをプロパティとして追加する必要があることを示しています。私にとっては、@{argLine}は、firefireプラグイン設定で。

1
Thirler

Maven/Javaプロジェクト に1つのドメインクラスを追加し、次の機能を追加しました。

  • プラグインSurefireおよびFailsafeを使用した単体または統合テスト
  • Findbugs。
  • Jacocoによるカバレッジのテスト。

私はプロジェクトをできるだけシンプルに保ちました。プロジェクトでは、これらの投稿や他の投稿からの多くの提案をプロジェクト例にまとめています。貢献者に感謝します!

Readmeファイルに簡単な説明があります。 Jacocoを使用してユーザーまたは統合テストを実行する方法を説明します。

楽しい!

0
tjm1706