5

我正面临一个开始非常恼人的错误。
这是我所拥有的: 1) Sonar 3.5,它使用 JaCoCo 作为覆盖工具。2) Jmockit lib 使用模拟执行测试。3) 使用 maven 自动化构建过程。

因此,当我首先运行时mvn clean install,这没关系,然后我正在运行mvn sonar:sonar,这里发生了什么:

  • Jmockit 似乎提供了它需要的类。
  • JaCoCo 无法检测已经被 Jmockit 检测的类并吐出大量异常,说不可能检测已经检测的类。然而,Sonar 似乎对这种情况有一个有效的输出。
    所以第一个问题是:我能以某种方式抑制这样的例外吗?这真的很关键,因为我们的 CI 系统上的日志文件大小达到50Mb(!),这是不可接受的。我们的 CI 机器上的此类日志会占用大量可用空间。

以下是我遇到的例外情况:

java.lang.instrument.IllegalClassFormatException: Error while instrumenting class app/MyClass.
Caused by: java.lang.IllegalStateException: Class app/MyClass is already instrumented.

假设抑制这种异常是不可能的,我对其进行了一些调查,发现 JaCoCo(Sonar 使用的一个工具和一个不能检测已经检测过的类的工具)具有这样的模式offline instrumentation(AFAIK Sonar既不支持这offline instrumentation或可以抑制这样的警告)。这个东西被设计用于这种情况。所以我尝试将 JaCoCo 设置为 maven 中的插件,但我没有这样做,因为 JaCoCo 找不到某些执行文件。当我运行时mvn clean install,会弹出以下错误:

[INFO] --- jacoco-maven-plugin:0.6.2.201302030002:report (report) @ webservice-mws --- [INFO] 由于缺少执行数据文件而跳过 JaCoCo 执行

如果我没记错的话,这个执行文件是 JaCoCo 插件的结果。我非常沮丧,不知道该怎么办。

如果有人可以帮助我,将不胜感激!
提前致谢!

我对 JaCoCo 插件的 pom.xml 设置:

             <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.6.2.201302030002</version>
                <executions>
                    <execution>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
4

5 回答 5

4

您可以使用 Cobertura 作为 Sonar 3.5.1 上的代码覆盖率。

要更改它:

  1. 以管理员身份登录
  2. 转到设置 > 配置
  3. 在常规设置类别 > Java
  4. 设置代码覆盖率插件 = cobertura

在我的项目中像魅力一样工作^_-

于 2013-06-05T23:52:16.370 回答
3

根据我对这项研究的见解:也可以将离线插桩类与 JaCoCo Java 代理一起使用。在这种情况下,配置取自代理选项。必须以排除预先检测的类的方式配置代理,例如使用“excludes=*”。否则,如果代理在您的情况下再次检测此类类,则会导致控制台上出现错误消息。Jacoco 插件入口:-

<configuration> 
     <excludes> 
          <exclude>*</exclude> 
     </excludes> 
</configuration>

代理 jacocoagent.jar 是 JaCoCo 发行版的一部分,包括所有必需的依赖项。可以使用以下 JVM 选项(在命令行中)激活 Java 代理:

-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]

对于 JaCoCo 代理选项,请考虑以下链接:http ://www.jacoco.org/jacoco/trunk/doc/agent.html

由于代理 jacocoagent.jar 是 JaCoCo 发行版的一部分,它会自动包含在 argLine 参数中,无需显式设置,但我们应该在执行 mvn clean install 命令时验证 jacocoagent.jar 是否显示为 argLine 中的设置

于 2017-08-11T18:06:30.060 回答
2

据我所知,消息“Class app/MyClass 已被检测”。意味着这个类已经被 JaCoCo 检测了。以下是可能发生这种情况的一些可能原因:

  • 离线仪器与在线混合 - 它们应该专门使用
  • 测试期间附加到 JVM 的两个 JaCoCo 代理 - 这可能会发生,因为 Sonar 尝试自动附加 JaCoCo 代理并执行测试,并且 jacoco-maven-plugin 也附加代理,所以为了避免这种情况,请查看属性“sonar.dynamicAnalysis=重用报告”或不使用 jacoco-maven-plugin,Sonar 将自行完成工作

对我来说,你的消息看起来有点难以理解配置,所以我不能准确地说出你所面临的上述哪种情况,但我敢打赌第二个。

希望这些信息对您有用。如果这不能帮助您解决问题,请随时返回 Sonar 用户邮件列表。

于 2013-06-01T21:02:41.060 回答
1

我有同样的问题。它似乎已在 jacoco 插件 0.7.1+ 中修复。我正在使用 0.7.3.201502191951 并且问题对我来说消失了。

本质上,jMockit 代理加载类并在 JaCoCo 代理看到它们之前重新转换它们。之后 JaCoCo 不能再执行所需的仪器。看到这个链接

https://github.com/jacoco/jacoco/issues/208

于 2015-02-26T18:44:19.383 回答
0

问题是 JMockit “重新加载”类来模拟它们。然后 JaCoCo 再次尝试检测它们。就在这个时候,错误发生了。

注意:模拟接口不会发生这种情况。

运行 EclEmma+JaCoCo 时查看以下堆栈跟踪

java.lang.instrument.IllegalClassFormatException: Error while instrumenting class com/company/AbstractClass.
    at org.jacoco.agent.rt.internal_9dd1198.CoverageTransformer.transform(CoverageTransformer.java:89)
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)
    at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
    at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
    at mockit.internal.startup.Startup.redefineMethods(Startup.java:260)
    at mockit.internal.RedefinitionEngine.redefineClasses(RedefinitionEngine.java:26)
    at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineClass(BaseTypeRedefinition.java:172)
    at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineClassAndItsSuperClasses(BaseTypeRedefinition.java:147)
    at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineMethodsAndConstructorsInTargetType(BaseTypeRedefinition.java:134)
    at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineTargetClassAndCreateInstanceFactory(BaseTypeRedefinition.java:197)
    at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineType(BaseTypeRedefinition.java:57)
    at mockit.internal.expectations.mocking.TypeRedefinition.redefineType(TypeRedefinition.java:47)
    at mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions.redefineTypeForMockField(SharedFieldTypeRedefinitions.java:60)
    at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldType(FieldTypeRedefinitions.java:48)
    at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldTypes(FieldTypeRedefinitions.java:38)
    at mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions.redefineTypesForTestClass(SharedFieldTypeRedefinitions.java:43)
    at mockit.integration.internal.TestRunnerDecorator.handleMockFieldsForWholeTestClass(TestRunnerDecorator.java:135)
    at mockit.integration.internal.TestRunnerDecorator.updateTestClassState(TestRunnerDecorator.java:34)
    at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.handleMockingOutsideTestMethods(JUnit4TestRunnerDecorator.java:107)
    at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.invokeExplosively(JUnit4TestRunnerDecorator.java:37)
    at mockit.integration.junit4.internal.MockFrameworkMethod.invokeExplosively(MockFrameworkMethod.java:32)
    at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at mockit.internal.util.MethodReflection.invokeWithCheckedThrows(MethodReflection.java:106)
    at mockit.internal.mockups.MockMethodBridge.callMock(MockMethodBridge.java:85)
    at mockit.internal.mockups.MockMethodBridge.invoke(MockMethodBridge.java:44)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.io.IOException: Error while instrumenting class com/afklm/cco/slt/integrator/batch/AbstractData.
    at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrumentError(Instrumenter.java:147)
    at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrument(Instrumenter.java:98)
    at org.jacoco.agent.rt.internal_9dd1198.CoverageTransformer.transform(CoverageTransformer.java:87)
    ... 44 more
Caused by: java.lang.IllegalStateException: Class com/company/AbstractClass is already instrumented.
    at org.jacoco.agent.rt.internal_9dd1198.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:81)
    at org.jacoco.agent.rt.internal_9dd1198.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:79)
    at org.jacoco.agent.rt.internal_9dd1198.asm.ClassVisitor.visitField(Unknown Source)
    at org.jacoco.agent.rt.internal_9dd1198.asm.ClassReader.a(Unknown Source)
    at org.jacoco.agent.rt.internal_9dd1198.asm.ClassReader.accept(Unknown Source)
    at org.jacoco.agent.rt.internal_9dd1198.asm.ClassReader.accept(Unknown Source)
    at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrument(Instrumenter.java:78)
    at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrument(Instrumenter.java:96)
    ... 45 more
于 2014-04-08T07:45:33.490 回答