web-dev-qa-db-fra.com

Testng, Emma, ​​Cobertura, la couverture et JDK 7 aboutissent à ClassFormatError et VerifyError

Je suis passé au JDK 7 le plus récent et j'ai des problèmes avec l'exécution du test unitaire testng sur du code d'octets qui est manipulé par l'outil de couverture Emma. Aucun de mes cas de test n'est exécuté correctement et pour la plupart d'entre eux, je reçois de telles erreurs.

 Java.lang.ClassFormatError: Illegal local variable table length 10 in method measurement.meter.AbstractSerialPortMeter.<init>(Lmeasurement/meter/SerialPort;)V at measurement.meter.Elc3133aTest.setUp(Elc3133aTest.Java:42)

J'ai trouvé un article ici JSR 292 Goodness Fast Code Coverage Tool Less 10k , qui dit que "JSR 292 introduit une nouvelle instruction bytecode invokedynamic mais aussi plusieurs nouveaux types de constantes de pool constantes. Ce qui signifie que la plupart des outils qui analysent les bytecodes comme ASM, BCEL, findbugs ou EMMA devront être mis à jour pour être Java 7 compatible. "

Vérifié la page d'accueil d'Emma, ​​mais il semble qu'elle n'ait pas été mise à jour depuis longtemps.

Quelqu'un a-t-il résolu un problème similaire?

J'ai également essayé avec Cobertura. Cela semble fonctionner un peu mieux mais je reçois beaucoup d'exceptions de type VerifyError.

Java.lang.VerifyError: Expecting a stackmap frame at branch target 85 in method measurement.meter.AbstractSerialPortMeter.close()V at offset 26
at measurement.meter.AbstractSerialPortMeterTest.setUp(AbstractSerialPortMeterTest.Java:27)
55
Jagger

J'ai eu le même problème. Heureusement, la bêta fonctionne avec JDK 7.
Lien vers le site de mise à jour: http://download.eclipselab.org/eclemma/beta/2.0.0/update/
Ce lien doit être utilisé dans Eclipse:

Help -> Install new software... -> Add...


Le repos devrait être facile;)

5
wieczorek1990

J'ai eu le même problème en utilisant le plugin maven cobertura. Tous les tests ont échoué lors de l'exécution à partir de cobertura: rapport. Mais tous les tests ont réussi lorsqu'ils étaient exécutés directement à partir du plugin surefire. Comme certains d'entre vous l'ont déjà dit, le problème est que l'instrumentation du code d'octets de coberture n'est pas compatible avec JDK7.

Vous pouvez voir ici http://vikashazrati.wordpress.com/2011/10/09/quicktip-verifyerror-with-jdk-7/ que l'exception est liée au "nouveau vérificateur de type avec StackMapTable attributs "(voir: -X: + Option JVM UseSplitVerifier dans http://www.Oracle.com/technetwork/Java/javase/tech/vmoptions-jsp-140102.html ).

Donc ma solution est de configurer le plugin surefire pour toujours exécuter les tests avec JVM arg "-XX: -UseSplitVerifier. Cela fonctionne bien avec et sans instrumentation cobertura.

Ma configuration infaillible dans maven:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.12</version>
    <configuration>
        <argLine>-XX:-UseSplitVerifier</argLine>
    </configuration>
</plugin>
76

J'ai obtenu Gradle 1.0M9, Java 7 et EMMA 2.1 fonctionnant avec les correctifs suggérés ici: en utilisant l'argument jvm.

Détails ici ... http://marcellodesales.wordpress.com/2012/04/03/running-emma-code-test-coverage-with-Java-7-and-gradle-1-0m9/? preview = true & preview_id = 179 & preview_nonce = 261e892908

configurations{
  emma
}

dependencies {
  // EMMS Code Coverage
  emma "emma:emma:2.1.5320"
  emma "emma:emma_ant:2.1.5320"
  ...
  testCompile group: 'junit', name: 'junit', version: '4.9'
}

test {
    // add EMMA related JVM args to our tests
    jvmArgs "-XX:-UseSplitVerifier", "-Demma.coverage.out.file=$buildDir/tmp/emma/metadata.emma", "-Demma.coverage.out.merge=true"

    doFirst {
       println "Instrumenting the classes at " + sourceSets.main.output.classesDir.absolutePath
       // define the custom EMMA ant tasks
       ant.taskdef( resource:"emma_ant.properties", classpath: configurations.emma.asPath)

       ant.path(id:"run.classpath") {
          pathelement(location:sourceSets.main.output.classesDir.absolutePath)
       }
       def emmaInstDir = new File(sourceSets.main.output.classesDir.parentFile.parentFile, "tmp/emma/instr")
       emmaInstDir.mkdirs()
       println "Creating $emmaInstDir to instrument from " +       sourceSets.main.output.classesDir.absolutePath
       // instruct our compiled classes and store them at $buildDir/tmp/emma/instr
       ant.emma(enabled: 'true', verbosity:'info'){
          instr(merge:"true", destdir: emmaInstDir.absolutePath, instrpathref:"run.classpath",
                metadatafile: new File(emmaInstDir, '/metadata.emma').absolutePath) {
             instrpath {
             fileset(dir:sourceSets.main.output.classesDir.absolutePath, includes:"**/*.class")
             }
          }
       }
       setClasspath(files("$buildDir/tmp/emma/instr") + configurations.emma +    getClasspath())
    }

    // The report should be generated directly after the tests are done.
    // We create three types (txt, html, xml) of reports here. Running your build script now should
    // result in output like that:
    doLast {
       def srcDir = sourceSets.main.Java.srcDirs.toArray()[0]
       println "Creating test coverage reports for classes " + srcDir
       def emmaInstDir = new File(sourceSets.main.output.classesDir.parentFile.parentFile, "tmp/emma")
       ant.emma(enabled:"true"){
          new File("$buildDir/reports/emma").mkdirs()
          report(sourcepath: srcDir){
             fileset(dir: emmaInstDir.absolutePath){
                include(name:"**/*.emma")
             }
             txt(outfile:"$buildDir/reports/emma/coverage.txt")
             html(outfile:"$buildDir/reports/emma/coverage.html")
             xml(outfile:"$buildDir/reports/emma/coverage.xml")
          }
       }
       println "Test coverage reports available at $buildDir/reports/emma."
       println "txt: $buildDir/reports/emma/coverage.txt"
       println "Test $buildDir/reports/emma/coverage.html"
       println "Test $buildDir/reports/emma/coverage.xml"
    }
}

L'exécution du "test gradle" donne les résultats suivants:

marcello@hawaii:/u1/development/workspaces/open-source/interviews/vmware$ gradle test
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
Instrumenting the classes at /u1/development/workspaces/open-source/interviews/vmware/build/classes/main
Creating /u1/development/workspaces/open-source/interviews/vmware/build/tmp/emma/instr to instrument from /u1/development/workspaces/open-source/interviews/vmware/build/classes/main
Creating test coverage reports for classes /u1/development/workspaces/open-source/interviews/vmware/src/main/Java
Test coverage reports available at /u1/development/workspaces/open-source/interviews/vmware/build/reports/emma.
txt: /u1/development/workspaces/open-source/interviews/vmware/build/reports/emma/coverage.txt
Test /u1/development/workspaces/open-source/interviews/vmware/build/reports/emma/coverage.html
Test /u1/development/workspaces/open-source/interviews/vmware/build/reports/emma/coverage.xml

BUILD SUCCESSFUL
2

J'avais ce problème. La mise à niveau vers 2.0.1.201112281951 à l'aide de la place de marché Eclipse a fonctionné pour moi.

1
Kevin Wong

IntelliJ IDEA 11 L'outil de couverture interne fonctionne bien pour mon projet en utilisant Try-with-Resources, Diamond Operator mais nous n'utilisons pas invokedynamic. Je pense que l'outil de couverture n'est pas inclus dans l'édition communautaire, ultime seulement.

Je n'ai pas encore essayé jacoco - c'est là que la plupart des anciens développeurs d'emma semblent être partis.

1
bcolyn

Emma fonctionne si vous n'utilisez pas de nouvelles fonctionnalités de langage (comme essayer avec des ressources, etc.). Vous pouvez utiliser Java 7 en utilisant de nouvelles bibliothèques (Paths, DirectoryStream, etc.). Je sais que ce ne serait pas une solution à votre problème, mais si vous voulez seulement vérifier "comment JDK 7 fonctionne "ça peut marcher ...

1
rafalmag

L'équivalent Java 8+ de la réponse de Pedro Ballesteros est:

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.12.4</version>
  <configuration>
    <argLine>-noverify</argLine>
  </configuration>
</plugin>

(Ajustez le numéro de version pour qu'il corresponde à la version de Surefire que vous utilisez.)

0
noverify