web-dev-qa-db-ja.com

Testng、Emma、Cobertura、カバレッジ、およびJDK 7はClassFormatErrorおよびVerifyErrorになります

最新のJDK 7に切り替えましたが、エマカバレッジツールで処理されたバイトコードでtestngユニットテストを実行すると問題が発生します。私のテストケースはどれも正しく実行されず、ほとんどの場合、そのようなエラーを受け取ります。

 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)

ここで記事を見つけました JSR 292 Goodness Fast Code Coverage Tool Less 10k 、「JSR 292は新しいバイトコード命令invokedynamicを導入しますが、いくつかの新しい種類の定数プール定数も導入しています。 ASM、BCEL、findbugs、EMMAなどのバイトコードを解析するツールの一部は、Java 7と互換性があるように更新する必要があります。

Emmaホームページをチェックしましたが、長い間更新されていないようです。

誰かが同様の問題を解決しましたか?

私もCoberturaで試しました。少し良くなっているように見えますが、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

同じ問題がありました。幸いなことに、ベータ版はJDK 7で動作します。
サイトリンクの更新: http://download.eclipselab.org/eclemma/beta/2.0.0/update/
このリンクはEclipseで使用する必要があります。

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


残りは簡単でなければなりません;)

5
wieczorek1990

Maven Coberturaプラグインを使用しても同じ問題が発生しました。 cobertura:reportから実行すると、すべてのテストが失敗しました。ただし、surefireプラグインから直接実行すると、すべてのテストは成功しました。すでにいくつかの人が言ったように、問題は、cobertureバイトコードインストルメンテーションがJDK7と互換性がないことです。

ここで見ることができます http://vikashazrati.wordpress.com/2011/10/09/quicktip-verifyerror-with-jdk-7/ 例外は「StackMapTable属性を持つ新しいタイプチェッカー」に関連しています( http://www.Oracle.com/technetwork/Java/javase/techの-X:+ UseSplitVerifier JVMオプションを参照) /vmoptions-jsp-140102.html )。

そのため、私のソリューションは、常にJVM引数 "-XX:-UseSplitVerifierを使用してテストを実行するようにsurefire-pluginを構成することです。これは、コベルトゥーラインスツルメンテーションの有無にかかわらず動作します。

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

Gradle 1.0M9、Java 7およびEMMA 2.1がここで提案されたパッチで動作しました:jvm引数を使用しました。

詳細はこちら... 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"
    }
}

「gradle test」を実行すると、次の結果が得られます。

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

私はこの問題を抱えていました。 Eclipseマーケットプレイスを使用して2.0.1.201112281951にアップグレードするとうまくいきました。

1
Kevin Wong

IntelliJ IDEA 11の内部カバレッジツールは、try-with-resources、ダイヤモンド演算子を使用するプロジェクトで正常に動作しますが、invokedynamicを使用していません。カバレッジツールは、コミュニティ版、のみ。

私はまだjacocoを試していない-それはエマの前の開発者のほとんどが行ったように見える場所です。

1
bcolyn

Emmaは、新しい言語機能(try-with-resourcesなど)を使用しない場合に機能します。新しいライブラリ(パス、DirectoryStreamなど)を使用してJava 7を使用できます。これはあなたの問題の解決策ではないことはわかっていますが、 「うまくいくかもしれない...

1
rafalmag

Java 8+ Pedro Ballesterosによる回答に相当するものは:

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

(使用しているSurefireのバージョンと一致するようにバージョン番号を調整します。)

0
noverify