web-dev-qa-db-fra.com

Erreur du plugin Maven JaCoCo

J'ai configuré le plugin Maven JaCoCo comme suit dans mon fichier pom.xml:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <jacoco.version>0.5.9.201207300726</jacoco.version>
</properties>

<profiles>
    <profile>
        <id>jacoco4</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                            <configuration
                            <destfile>${project.build.directory}/target/jacoco.exec</destfile>
                            <datafile>${project.build.directory}/target/jacoco.exec</datafile>
                                <output>file</output>
                                <append>true</append>
                            </configuration>
                        </execution>
                        <execution>
                            <id>report</id>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>report</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

J'utilise Windows 7 et le plugin Apache-maven-3.0.4. Lorsque je tape mvn -P jacoco4 install, à partir d'un terminal cygwin ou d'un terminal d'invite de commande, Maven télécharge et exécute le plug-in JaCoCo, mais le fichier jacoco.exec ne semble pas avoir été créé. Ci-dessous le message d'erreur:

[ERROR] Unable to read execution data file C:\Users\brownru\workspace64new\vps9\vps-fileserver\target\jacoco.exec: C:\Users\brownru\workspace64new\vps9\vps-fileserver\target\jacoco.exec (The system cannot find the file specified)
Java.io.FileNotFoundException: C:\Users\brownru\workspace64new\vps9\vps-fileserver\target\jacoco.exec (The system cannot find the file specified)
        at Java.io.FileInputStream.open(Native Method)
        at Java.io.FileInputStream.<init>(FileInputStream.Java:120)
        at org.jacoco.maven.ReportMojo.loadExecutionData(ReportMojo.Java:251)
        at org.jacoco.maven.ReportMojo.executeReport(ReportMojo.Java:228)
        at org.jacoco.maven.ReportMojo.execute(ReportMojo.Java:217)
        at org.Apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.Java:101)
        at org.Apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.Java:209)
        at org.Apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.Java:153)
        at org.Apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.Java:145)
        at org.Apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.Java:84)
        at org.Apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.Java:59)
        at org.Apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.Java:183)
        at org.Apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.Java:161)
        at org.Apache.maven.DefaultMaven.doExecute(DefaultMaven.Java:320)
        at org.Apache.maven.DefaultMaven.execute(DefaultMaven.Java:156)
        at org.Apache.maven.cli.MavenCli.execute(MavenCli.Java:537)
        at org.Apache.maven.cli.MavenCli.doMain(MavenCli.Java:196)
        at org.Apache.maven.cli.MavenCli.main(MavenCli.Java:141)
        at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
        at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
        at Java.lang.reflect.Method.invoke(Method.Java:597)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.Java:290)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.Java:230)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.Java:409)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.Java:352)

Ce message d'erreur apparaît que j'inclue ou non les spécificateurs destfile et datafile dans la configuration du plug-in:

<destfile>${project.build.directory}/target/jacoco.exec</destfile>
<datafile>${project.build.directory}/target/jacoco.exec</datafile>

Est-ce que quelqu'un peut me dire ce que je fais mal?

19
kirigiri

J'avais le même problème avec jacoco et maven . Cela était lié à un pom parent écrasant la configuration de surefire . Dans ce cas, ce plugin n'a pas utilisé l'argument (pour l'argument jvm) définissant l'agent.

La solution a été de remettre l'élément de configuration "argLine"

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
   <argLine>${argLine}</argLine>
  </configuration>
 </plugin>

Full plugin conf ressemble à

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <skip>true</skip>
  </configuration>
  <executions>
    <execution>
      <id>unit-test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <skip>${maven.test.skip}</skip>
        <argLine>${argLine}</argLine>
        <excludes>
          <exclude>**/*IntegrationTest.Java</exclude>
        </excludes>
      </configuration>
    </execution>
    <execution>
      <id>integration-test</id>
      <phase>integration-test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <skip>${skipITs}</skip>
        <argLine>${argLine}</argLine>
        <includes>
          <include>**/*IntegrationTest.Java</include>
        </includes>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.5.10.201208310627</version>
    <configuration>
        <skip>${maven.test.skip}</skip>
        <destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
        <dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
        <output>file</output>
        <append>true</append>
    </configuration>
    <executions>
        <execution>
            <id>jacoco-initialize</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>jacoco-site</id>
            <phase>verify</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

J'espère que ça va être utile

22
Sylvain

OK, je pense avoir compris ce qui se passait.

Par défaut, le plug-in jacoco "s'exécute" avant la phase de test (généralement, il exécute l'objectif prepare-agent pendant la phase initialize cycle de vie), et lorsqu'il s'exécute, il définit simplement une propriété maven appelée "argLine" comme suit: -javaagent=jacoco.jar

ex:

[INFO] argLine défini sur -javaagent: /usernamed/.m2/repository/org/jacoco/org.jacoco.agent/ 0.5.6.201201232323/org.jacoco.agent-0.5.6.201201232323-runtime.jar = destfile =/chemin/à/target/jacoco.exec

Par défaut, maven-surefire-plugin "ajoute" généralement cette propriété (si elle est définie sur n'importe quoi) à ses processus de test Java définis, afin qu'ils récupèrent les marchandises. Ex: Java ${argLine ends up here}> -jar /xxx/surefirebooter3741906822495182152.jar

Typiquement (sans jacoco), si vous voulez aussi ajouter quelque chose de votre choix à cet argument (par exemple, -Xmx1G ou similaire), vous devez simplement le définir dans la configuration surefire, comme

 <build>
   <plugins>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
            <argLine>-Xmx1G</argLine>
          </configuration>
     </plugin>

Cependant, si vous utilisez jacoco, vous ne pouvez pas le faire normalement en définissant une propriété globale, de cette façon à la place (il s'agit des propriétés globales de la racine du pom):

  <properties>
    <argLine>-Xmx1G</argLine>
  </properties>

Si vous définissez le <configuration><argLine>, il remplace la propriété système et les arguments jacoco ne sont donc pas transmis au processus enfant. C'est pourquoi vous utilisez plutôt le mode propriété. Si vous spécifiez une propriété argLine, jacoco ajoutera simplement ses paramètres à ce que vous spécifiez, puis surefire l'utilisera.

Cependant, que se passe-t-il si votre pom parent a déjà défini le <configuration><argLine> du plugin sur quelque chose? Ou si vous le définissez vous-même? Il utilisera essentiellement cette valeur à la place de la propriété définie par jacoco (vous avez spécifié une substitution manuelle).

Si vous spécifiez vous-même le <configuration><argLine>, vous pouvez le transformer en propriété (voir ci-dessus) et supprimer le <configuration><argLine> qui devrait fonctionner. Si vous ne pouvez pas contrôler le parent et que celui-ci spécifie quelque chose pour argline, vous devrez alors suivre la route <configuration><argLine>${argLine} -Xmx1G</argLine>. Cela consiste à lui demander d'ignorer tout ce que le parent a défini sur cette valeur et d'utiliser argLine à la place (celle que jacoco définit pour vous). (Il n’est pas clair pour moi s’il existe un moyen simple d’ajouter de la valeur au pom parent pour cette valeur, si vous savez comment vous pouvez vous sentir libre de le commenter ici).

Mais que se passe-t-il si jacoco ne court pas pour une cible ou un profil? Ensuite, la variable ${argLine} n'est jamais définie et vous pouvez rencontrer une erreur comme celle-ci:

Exécution du test par défaut de l'objectif org.Apache.maven.plugins: maven-surefire-plugin: 2.14: le test a échoué: le fichier VM en forme de fourche s'est terminé sans dire au revoir correctement. VM plant ou System.exit appelé? [ERREUR] La commande était/bin/sh -c cd ... Java '$ {argLine}' ...

Eh bien, il s'avère que jacoco "ajoute" uniquement à la propriété nommée argLine, lorsqu'elle s'exécute. Vous pouvez donc ajouter en toute sécurité un <properties><argLine></argLine></properties> à votre pom (à moins que vous ne l'ayez déjà défini dans le pom parent, vous n'avez rien besoin d'ajouter). Si jacoco est invoqué, il y ajoute quelque chose. Sinon, il est défini sur une chaîne vide, ce qui est OK. Il est également difficile de savoir s'il existe un moyen "d'ajouter" à la valeur du parent pour une propriété. Vous pouvez donc l'hériter, si vous savez qu'elle existe, ou le spécifier comme vide.

Donc, à la fin pour moi, puisque mon pom parent en amont (inaccessible) l'a déclaré comme 

<configuration><argList>${argList}</argList></configuration>

J'ai été obligé de suivre essentiellement cette voie, puisqu'elle était déjà placée dans un pom parent (hors de mon contrôle), donc:

<configuration><argList>${argList} -Xmx1G</argList></configuration>

Notez que Intellij se plaindra et "ne pas ajouter de paramètres" à votre test unitaire si vous avez ceci dans votre pom:

<configuration><argLine>${argLine} -DcustomOption=X...</argLine>

mais ne déclarez pas du tout une propriété nommée argLine (même si cela fonctionne très bien en ligne de commande). Correction/contournement: déclarez une propriété globale 'argLine' vide et/ou déplacez simplement votre -DcustomOption=X vers la déclaration de la propriété, voir ci-dessus. Si vous "uniquement" le définissez dans la déclaration de la propriété, vous aurez également besoin de <configuration><argLine>${argLine}</argLine>...: |

13
rogerdpack

J'ai aussi rencontré ce problème: JaCoCo ne produit pas de fichier de sortie 'jacoco.exec', ce qui signifie qu'aucune analyse de la couverture de code n'est effectuée. 

Dans mon cas, cela était également dû à l'utilisation d'une argumentLigne personnalisée dans le plug-in Maven Surefire qui a annulé l'argLine de JaCoCo Maven Plugin, ce qui a empêché l'exécution de JaCoCo.

Pour résoudre ce problème, j'ai utilisé le paramètre facultatif JaCoCo "propertyName" pour exporter son argLine vers une propriété Maven et je l'ai inclus dans l'argLine Surefire:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <configuration>
        <propertyName>jacoco.agent.argLine</propertyName>
    </configuration>
    ...             
</plugin>

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.10</version>
    <configuration>
        <argLine>-XX:-UseSplitVerifier ${jacoco.agent.argLine}</argLine>
    </configuration>
</plugin>

Cependant, cela posait un problème lorsque des tests individuels étaient exécutés dans Netbeans. Le plug-in JaCoCo n'ayant pas été exécuté dans ce scénario, la variable "jacoco.agent.argLine" n'a pas été initialisée et Surefire a échoué avant l'exécution de tout test. 

L'ajout d'une propriété vierge "jacoco.agent.argLine" au pom a permis de résoudre le problème lors de l'exécution de tests simples, mais cela a également empêché JaCoCo d'exporter sa ligne d'argile lors de son exécution, ce qui a effectivement désactivé JaCoCo. 

La dernière partie de la solution que j'ai utilisée consistait à ajouter un profil qui crée la propriété vide et qui s'active uniquement lorsqu'un seul test est spécifié:

<profiles>
    <profile>
        <activation>                
            <property>
                <name>test</name>      
            </property>
        </activation>
        <properties>
            <jacoco.agent.argLine></jacoco.agent.argLine>
        </properties>
    </profile>
</profiles>
7
jimr

J'utilise la configuration:

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
            <configuration>
                    <skip>${skipTests}</skip>
            </configuration>
            <executions>
                    <execution>
                                <id>jacoco-initialize</id>
                                <phase>initialize</phase>
                                <goals>
                                    <goal>prepare-agent</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>jacoco-site</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>report</goal>
                                </goals>
                            </execution>
            </executions>
        </plugin>

Mise à jour: Configuration générée par le sonar (sonar-pom.xml):

<plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12</version>
        <executions>
          <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
              <goal>test</goal>
            </goals>
            <configuration>
              <excludedGroups>server,ignore,integration</excludedGroups>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <excludedGroups>server,ignore,integration</excludedGroups>
          <argLine>-javaagent:/tmp/jacocoagent3671192291664069011.jar=destfile=target/jacoco.exec,excludes=*_javassist_*</argLine>
          <testFailureIgnore>true</testFailureIgnore>
        </configuration>
      </plugin>

Un problème - comment définir "jacocoagent3671192291664069011.jar" pour chaque construction. Il devrait être dans:

$M2_HOME/repository/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar
0
Andrzej Jozwik

J'ai fait face au même problème et résolu en utilisant la commande ci-dessous à la place de jacoco: report - 

mvn -X org.jacoco:jacoco-maven-plugin:report 

Référence - Comment configurer le plug-in JaCoCo maven à partir de la ligne de commande

0
Sanchi Girotra