Testng, Emma, Cobertura, coverage и JDK 7 приводят к ClassFormatError и VerifyError
я переключился на новейший 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 менее 10k, что говорит о том, что " JSR 292 вводит новую инструкцию байт-кода invokedynamic, но также и несколько новых типов постоянного пула константы. Это означает, что большинство инструментов, которые анализируют байт-коды, такие как ASM, BCEL, findbugs или EMMA, должны быть обновлены, чтобы быть совместимыми с java 7."
проверил домашнюю страницу Эммы, но похоже, что она не обновлялась в течение длительного времени.
кто-нибудь решил подобную проблему?
Я также пробовал с 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)
6 ответов:
У меня была та же проблема. К счастью, бета-версия работает с JDK 7.
обновить ссылку на сайт:http://download.eclipselab.org/eclemma/beta/2.0.0/update/
эта ссылка должна использоваться в Eclipse:Help -> Install new software... -> Add...
отдых должен быть легким ;)
У меня была такая же проблема с использованием плагина maven cobertura. Все тесты не удалось выполнить при запуске из cobertura: report. Но все тесты удались при запуске непосредственно из плагина surefire. Как некоторые из вас уже сказали, проблема заключается в том, что инструментирование байтового кода coberture не совместимо с JDK7.
вы можете посмотреть здесь http://vikashazrati.wordpress.com/2011/10/09/quicktip-verifyerror-with-jdk-7/ что исключение связано с " проверкой нового типа с помощью StackMapTable атрибуты " (см.: - x:+UseSplitVerifier JVM option in http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html).
поэтому мое решение-настроить surefire-plugin, чтобы всегда выполнять тесты с помощью JVM arg "-XX:-UseSplitVerifier. Он хорошо работает с и без приборов измерения.
моя верная конфигурация в maven:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12</version> <configuration> <argLine>-XX:-UseSplitVerifier</argLine> </configuration> </plugin>
Я получил 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
Эмма работает, если вы не используете новые языковые функции (например, try-with-resources и т. д.). Вы можете использовать Java 7, используя новые библиотеки (пути, DirectoryStream и т. д.). Я знаю, что это не будет решением вашей проблемы, но если вы хотите только проверить "как работает JDK 7", он может работать...
У меня была эта проблема. Обновление до 2.0.1.201112281951 с помощью Eclipse marketplace работало для меня.
внутренний инструмент покрытия IntelliJ IDEA 11 отлично работает для моего проекта, используя try-with-resources, diamond operator, но мы не используем invokedynamic. Я думаю, что инструмент покрытия не включен в издание сообщества, только ultimate.
Я еще не пробовал jacoco-это то, где большинство бывших разработчиков Эммы, похоже, ушли.