升级至JDK 11后Jacoco配合JUnit 4测试执行失败求助
JDK 11升级后Jacoco生成.exec文件但单元测试抛出数组越界异常
项目升级至JDK 11后,发现Surefire无法为Jacoco生成.exec文件。为解决该问题,我们修改了Maven POM文件,从Jacoco获取参数并传递给Surefire,配置如下:
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.4</version> <executions> <execution> <id>jacoco-initialize</id> <goals> <goal>prepare-agent</goal> </goals> <!-- 获取参数 --> <configuration> <propertyName>surefireArgLine</propertyName> </configuration> </execution> <execution> <id>post-unit-test</id> <phase>test</phase> <goals> <goal>report</goal> </goals> <configuration> <outputDirectory>./codeCoverage/</outputDirectory> </configuration> </execution> </executions> </plugin> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.7</version> <configuration> <!-- 使用参数 --> <argLine> ${surefireArgLine} -Xmx1024m -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.9/jmockit-1.9.jar --add-reads java.base=java.logging --add-reads java.xml=java.logging </argLine> </configuration> </plugin>
调整后Jacoco已能生成.exec文件,但单元测试执行失败,报错如下:
java.lang.ArrayIndexOutOfBoundsException: Index 110 out of bounds for length 110 at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
我们尝试升级JMockit至1.23、Surefire至2.22.2,但问题仍存在,仅报错信息略有差异。该问题在JDK 1.8环境下未出现,求解决方案。
补充说明:surefireArgLine的实际值为:
[INFO] --- jacoco-maven-plugin:0.8.3:prepare-agent (coverage-initialize) --- [INFO] surefireArgLine set to -javaagent:.m2/repository/org/jacoco/org.jacoco.agent/0.8.3/org.jacoco.agent-0.8.3-runtime.jar=destfile=/target/jacoco.exec
解决方案建议
- 调整JavaAgent加载顺序
JMockit的JavaAgent必须优先于Jacoco加载,因为JMockit需要在字节码层面做前置修改。修改Surefire的argLine配置,将JMockit的-javaagent放在${surefireArgLine}之前:
<argLine> -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.23/jmockit-1.23.jar ${surefireArgLine} -Xmx1024m --add-reads java.base=java.logging --add-reads java.xml=java.logging </argLine>
升级Jacoco至兼容JDK11的版本
旧版本Jacoco(如0.8.3/0.8.4)对JDK11的模块系统支持不完善,建议升级到0.8.10及以上版本,该版本对JDK9+的模块系统兼容性更好。使用最新稳定版Surefire插件
Surefire 2.x版本对JDK11的支持存在部分问题,建议升级到3.0.0-M7及以上稳定版本,同时确保argLine配置避免换行导致的参数解析异常,可将配置合并为一行或使用CDATA包裹:
<argLine><![CDATA[ -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.23/jmockit-1.23.jar ${surefireArgLine} -Xmx1024m --add-reads java.base=java.logging --add-reads java.xml=java.logging ]]></argLine>
- 检查模块可读性配置是否完整
JDK9+的模块系统中,部分测试依赖的模块可能需要额外的--add-reads或--add-opens配置,可根据测试类的依赖情况补充相关参数,例如如果测试中用到了JavaFX或其他模块,需添加对应的可读性配置。
内容的提问来源于stack exchange,提问作者Aaron Aardvark
相关产品推荐
相关产品推荐

