55

我已切换到最新的 JDK 7,并且在对 emma 覆盖工具摆弄的字节码运行 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)
4

7 回答 7

76

我在使用 maven cobertura 插件时遇到了同样的问题。从 cobertura:report 运行时,所有测试均失败。但是当直接从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-plugin配置为始终使用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>
于 2012-03-06T12:00:36.340 回答
5

我遇到过同样的问题。幸运的是,测试版适用于 JDK 7。
更新站点链接: http: //download.eclipselab.org/eclemma/beta/2.0.0/update/
这个链接应该在 Eclipse 中使用:

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


休息应该很容易;)

于 2011-12-13T22:51:52.720 回答
2

我让 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
于 2012-04-03T18:21:37.073 回答
1

IntelliJ IDEA 11 的内部覆盖工具适用于我的项目,使用 try-with-resources、菱形运算符,但我们没有使用 invokedynamic。我认为社区版中不包含覆盖工具,只有终极版。

我还没有尝试过 jacoco——大多数 emma 的前开发人员似乎都去了那里。

于 2012-01-15T21:08:57.203 回答
1

如果您不使用新的语言功能(例如 try-with-resources 等),Emma 就可以工作。您可以通过新库(Paths、DirectoryStream 等)使用 Java 7。我知道这不能解决您的问题,但是如果您只想检查“JDK 7 的执行方式”,它可能会起作用...

于 2011-11-16T16:10:01.543 回答
1

我遇到了这个问题。使用 Eclipse 市场升级到 2.0.1.201112281951 对我有用。

于 2012-01-03T20:48:18.367 回答
0

Pedro Ballesteros 回答的 Java 8+ 等价物是:

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

(调整版本号以匹配您使用的 Surefire 版本。)

于 2019-08-27T17:52:55.210 回答