Development Tip

maven에서 jacoco JVM 인수와 확실한 JVM 인수를 함께 사용할 수 없습니다.

yourdevel 2020. 12. 11. 20:20
반응형

maven에서 jacoco JVM 인수와 확실한 JVM 인수를 함께 사용할 수 없습니다.


코드 커버리지 메트릭을 생성하기 위해 jacoco 플러그인 과 함께 maven을 사용하고 있습니다. jacoco 플러그인에 필요한 Java 옵션으로 surefire 플러그인을 구성하는 데 어려움이 있습니다 . 이미 Stack Overflow에서 이에 대한 몇 가지 답변을 보았지만 무언가가 작동하지 않습니다.

다중 모듈 프로젝트가 있고 내 모듈 중 하나가 다음과 같이 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>

경우에 것을 여기 볼 코드 커버리지의 프로필을 지정, 다음 jacoco의 플러그인이 사용하도록 구성되어 surefire.argLine속성을, 그 속성은을 구성하는 데 사용됩니다 argLine에 대한 확실한 플러그인.

그런 다음 jacoco 플러그인에서 생성 한 속성 을 사용하도록 foo 모듈 pom.xml 파일 을 업데이트했습니다 .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속성이 생성 argLine되고 surefire 플러그인의 경우 surefire.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}`

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

확실한의 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.argLineparent/pom.xml파일에 정의 된 빈 값이있는 속성 surefire 플러그인 의 argline을 만드는 데 사용됩니다 .

결과적으로 CodeCoverage 프로필을 사용할 때 jacoco-ut.exec파일과 target\code-coverage디렉터리 가 없습니다 .

내가 여기서 뭘 잘못하고 있는지 잘 모르겠습니다. jacoco 문서에서 argLine제안한대로 속성을 선언 하고 확실한 플러그인이 추가 인수를 지정해야 할 때마다 사용합니다 . Stack Overflow에 대한 다른 답변은 jacoco 가 호출되지 않은 경우를 처리하기 위해 jacoco argLine 속성 과 동일한 이름의 속성을 만드는 것이 좋습니다 .

어떤 제안?

편집하다

한 가지 해결책은 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>

그러면 jacoco 플러그인에 필요한 Java 에이전트를 사용 하는 surefire.argLine 속성 이 생성되고 해당 JVM 인수에 해당 속성을 사용 하도록 surefire 플러그인을 구성합니다 . jacoco의 플러그인은 이제 만듭니다 argLine의 속성을,하지만이 무시됩니다. 이것은 우아한 해결책이 아닙니다 ( jacoco 플러그인이 어떻게 작동 하는지에 대한 가정을하고 있기 때문에 향후 버전에서 변경 될 수 있습니다).

편집하다

jacoco.agent.jar속성은 또한 (이 강력한 확실하지 경우) 로컬 저장소에서의 위치를 가리키는하거나 사용하여 설정해야합니다 종속성을 복사하는 플러그인 jacoco의 로컬 빌드 디렉토리에 에이전트 항아리 :

<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


이후 jacoco-maven-plugin:prepare-agent받는다는 - 확실한 - 플러그인 전에 골이 실행의 추가 시도 ${argLine}에 변수를 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의 다른 섹션을 재구성 할 필요없이 저에게 효과적이었습니다.


사용해보십시오

@{argLine}

대신에

${argLine}

(또는 surefire.argLine귀하의 경우)

확실한 것은 Maven 자체로 대체 된 것을 읽는 대신 다른 플러그인에 의해 수정 된 속성을 읽을 수 있도록합니다. 그런 다음 argLineMaven 속성에서 매개 변수를 비워 둘 수 있습니다.

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

이제는 문제가 발생하지 않습니다. 더보기 : argLine의 다른 플러그인에서 설정 한 속성을 어떻게 사용합니까?


프로젝트에서 이미 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


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를


나는 최근에 동일한 문제에 부딪 쳤고 동일한 결과로 설명한 것과 동일한 단계를 암시 적으로 수행했습니다. 내가 찾은 깨끗한 솔루션이 나를 위해 일하지 않았습니다.

그래서 디버그 모드에서 여러 단계를 실행했는데 Maven이 속성을 두 번 대체하는 것 같습니다. 그것은 내가 생각했던 것처럼 게으른 방식이 아니라 열심과 게으른 방식 모두입니다.

  1. 열심히 (목표를 실행하기 전에) 정적 속성 ( propertiesPOM 섹션 및 settings.xml에 정의 됨)으로 대체 됩니다 .
  2. 느리게 (각 실행 전) 동적 속성 으로 대체 됩니다.

빈 속성을 기본값으로 설정하는 단계가 실패한 곳입니다. 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 파일이 생성되고 비활성 프로필에서는 빈 기본값이 사용되며 빌드가 성공합니다.


내 해결책은 여러 프로필을 사용하는 것입니다.

첫 번째 프로필은 surefire.argLine및의 빈 값을 설정하며 failsafe.argLine기본적으로 활성화됩니다.

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

두 번째 프로필에는 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>

소나 프로필을 활성화하면 비소 나 프로필이 자동으로 꺼집니다.

이것은 다른 플러그인을 사용하는 것보다 조금 더 우아해야합니다. 이제 ${surefire.argLine}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>

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>

버전을 0.7.7.201606060606에서 0.7.9로 업그레이드하면이 문제도 해결되었습니다.

I had to explicitly add the version to the commandline (not just to the pom) because the build server kept using the old verison. This can be done as follows:

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

instead of

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

The jacoco plugin site (for sonar) states that argline must be added as a property. For me it also worken when using the @{argLine} in the surefire plugin settings.


Update the POM.xml as

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

and then the most important thing is to run the Maven project with goals: mvn jacoco:prepare-agent clean test jacoco:report


I have added a Maven/Java project with 1 domain class with the following features:

  • Unit or Integration testing with the plugins Surefire and Failsafe.
  • Findbugs.
  • Test coverage via Jacoco.

I kept the project as simple as possible. The project puts many suggestions from these and other posts together in an example project. Thank you, contributors!

The readme file gives a brief explanation. It explains how you can run either a user or an integration test with Jacoco.

Enjoy!

참고URL : https://stackoverflow.com/questions/23190107/cannot-use-jacoco-jvm-args-and-surefire-jvm-args-together-in-maven

반응형