“IllegalStateException:class 中的不兼容执行数据……”当 运行 现有耳朵时,Jacoco 出现异常

“IllegalStateException: Incompatible execution data for class in…” exception from Jacoco when run for an existing ear

我正在尝试使用 Arquillian 和 TestNG 测试遗留的大型 EAR (app.ear) 应用程序。为了 运行 测试,我将可测试的 war 文件 (test.war) 添加到现有的 app.ear 并远程部署在 WildFly 10 服务器上。

@Deployment
public static EnterpriseArchive createDeployment(){
    return ShrinkWrap.createFromZipFile(EnterpriseArchive.class, new File("../earapp/target/earapp-0.0.1-SNAPSHOT.ear"))
            .addAsModule(Testable.archiveToTest(ShrinkWrap.create(WebArchive.class, "test.war")
                    .addClass(CurrencyConverterTest.class)
                    .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")));
}

我的下一部分要求是在测试 运行 之后获得代码覆盖率报告。为此,我正在使用 Jacoco 并 运行 将其与 Jacoco Maven 插件结合使用。

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.7.201606060606</version>
    <executions>
        <execution>
            <id>default-prepare-agent</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>default-report</id>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
</plugin>

app.ear 得到部署,甚至测试 运行 都很好,但是在生成报告时,Jacoco 失败并出现异常 “IllegalStateException:Jacoco 中 class 的不兼容执行数据…………”

异常仅针对包含测试用例的 class。如果我在 Jacoco Maven 插件中使用排除标记排除 class (CurrencyConverterTest.class),则异常消失但 Jacoco 生成的报告不包含任何数据。我还检查了 jacoco.exec,据我所知它包含有效数据。

由于我无法共享我正在使用的专有代码,我在 github 上创建了三个简单的项目来模拟它们。

在我看来,Jacoco 代码中似乎存在一些错误,但我也可能错了。请帮帮我。

更新: 构建在 git 存储库上共享的项目的步骤

第 1 步:检查所有三个项目并将其作为 eclipse 项目导入 eclipse。

第 2 步:运行maven 命令clean instll 项目 1(currencyconverter)

第 3 步:运行 项目 2 (earapp) 的 maven 命令 clean package。这将在目标目录中创建一个 ear 文件。

第 4 步:在本地计算机上以独立模式启动 WildFly 10。

第 5 步:运行 maven 命令 clean install 项目 3(eartest)。这将使用第 3 步中生成的 ear 并将其部署到 WildFly 10 应用程序服务器和 运行 测试中。

很遗憾,无法构建您的示例:

[ERROR] Failed to execute goal on project eartest:
Could not resolve dependencies for project com.sg.eartest:eartest:jar:0.0.1-SNAPSHOT:
Could not find artifact org.jboss.osgi.metadata:jbosgi-metadata:jar:3.0.1.Final in central (https://repo.maven.apache.org/maven2)

如果它位于单个 GitHub 存储库中,使用起来也会更简单。

但是:

确保在所有被测模块中使用完全相同版本的 JaCoCo。

并确保被测 JVM 正常终止,否则您可能会收到损坏的 "jacoco.exec" 文件,因为默认情况下它是在 JVM 关闭期间保存的。在早期版本的 JaCoCo 中,此类损坏的文件可能会导致

IllegalStateException: Incompatible execution data for class...

(根据 https://github.com/jacoco/jacoco/issues/95#issuecomment-17271597

JaCoCo 0.7.7 版改进了文件被截断时的错误消息 - https://github.com/jacoco/jacoco/pull/397 And it is a good practice to use latest released versions as they bring bug-fixes and improvements - http://www.eclemma.org/jacoco/trunk/doc/changes.html

最后 - 似乎您的测试完全位于与被测主代码不同的模块中。 "report" mojo 为当前模块的 类 创建报告。使用 "report-aggregate" 聚合跨模块的覆盖范围 - 其文档可以在 http://www.eclemma.org/jacoco/trunk/doc/report-aggregate-mojo.html Some examples were mentioned in https://groups.google.com/forum/#!msg/jacoco/8zjkSseaxD4/QOux-Ws-AgAJ

找到