Testng, Emma, ​​Cobertura, покрытие и JDK 7 приводят к ClassFormatError и VerifyError - PullRequest
55 голосов
/ 10 августа 2011

Я перешел на новейшую версию JDK 7, и у меня возникли проблемы с запуском юнит-теста testng на байт-код, который обрабатывается инструментом покрытия emma.Ни один из моих тестов не выполняется правильно, и для большинства из них я получаю такие ошибки.

 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 вводит новую инструкцию байт-кода, вызывающую динамическую, но также и несколько новых видов констант пула. Это означает, что большинство инструментов, анализирующих байт-коды, таких как ASM, BCEL, findbugs или EMMA, должны быть обновлены, чтобы быть Java 7совместимо. "

Проверено на домашней странице Эммы, но, похоже, она долгое время не обновлялась.

Кто-нибудь решал подобную проблему?

У меня тоже естьпробовал с кобертурой.Это выглядит работать немного лучше, но я получаю много исключений типа 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)

Ответы [ 6 ]

76 голосов
/ 06 марта 2012

У меня была такая же проблема при использовании плагина maven cobertura.Все тесты не пройдены при запуске из cobertura: отчет.Но все тесты были успешными, когда они запускались прямо из плагина surefire.Как некоторые из вас уже сказали, проблема в том, что инструментарий боб-кода coberture не совместим с JDK7.

Здесь вы можете увидеть http://vikashazrati.wordpress.com/2011/10/09/quicktip-verifyerror-with-jdk-7/, что исключение связано с «средством проверки нового типа с атрибутами StackMapTable» (см. Параметр -X: + UseSplitVerifier JVM в http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html).

Поэтому мое решение состоит в том, чтобы сконфигурировать плагин surefire, чтобы он всегда выполнял тесты с JVM arg "-XX: -UseSplitVerifier. Он хорошо работает с инструментарием cobertura и без него.

Моя верная конфигурация в maven:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.12</version>
    <configuration>
        <argLine>-XX:-UseSplitVerifier</argLine>
    </configuration>
</plugin>
5 голосов
/ 14 декабря 2011

У меня была такая же проблема. К счастью, бета-версия работает с JDK 7.
Обновить ссылку на сайт: http://download.eclipselab.org/eclemma/beta/2.0.0/update/
Эту ссылку следует использовать в Eclipse:

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


Отдых должен быть легким;)

2 голосов
/ 03 апреля 2012

Я получил 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" дает следующее:

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
1 голос
/ 16 января 2012

Инструмент внутреннего покрытия IntelliJ IDEA 11 отлично работает для моего проекта с использованием оператора try с ресурсами, но мы не используем invokedynamic.Я думаю, что инструмент охвата не включен в выпуск сообщества, только окончательный вариант.

Я еще не попробовал jacoco - это то, куда большинство бывших разработчиков Эммы, похоже, ушли.

1 голос
/ 04 января 2012

У меня была эта проблема. Обновление до 2.0.1.201112281951 с использованием торговой площадки Eclipse мне помогло.

1 голос
/ 16 ноября 2011

Эмма работает, если вы не используете новые языковые функции (например, попробовать с ресурсами и т. Д.). Вы можете использовать Java 7, используя новые библиотеки (Paths, DirectoryStream и т. Д.). Я знаю, что это не будет решением вашей проблемы, но если вы хотите проверить только "как работает JDK 7", это может сработать ...

...