You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Java 17后WireMock测试失败问题求助

问题分析与解决方案

背景

原技术栈:Spring Boot 2.7 + Java 8 + Jersey(JAX-RS)+ com.github.tomakehurst:wiremock-jre8:2.35.0,测试正常。
升级路径:

  1. 仅升级Java 17:应用运行正常,但所有WireMock测试失败,尝试多个WireMock版本(jre8 3.0.0、wiremock 3.0.0、org.wiremock 3.0.4)无效。
  2. 升级至Spring Boot 3(完成javax→jakarta命名空间迁移):应用恢复正常,但WireMock测试仍失败,测试了2.27.2、3.0.4、3.1.0、3.2.0、3.3.0等版本的常规/独立包均无效。

测试代码示例:

public void stubDelete(String url, int status) {
    WireMock.stubFor(delete(urlEqualTo(url))
        .willReturn(aResponse()
            .withHeader("Content-Type", "application/json")
            .withStatus(status))
        );
}

核心报错:

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: java.lang.ArithmeticException: long overflow

核心原因分析

long overflow 异常在该场景下的常见触发点:

  1. WireMock与Spring Boot 3的依赖冲突:二者底层依赖(如Netty、Jetty)版本不兼容,导致WireMock初始化时出现数值计算溢出。
  2. Java 17的严格溢出检查/模块权限限制:Java 17对整数溢出的检测更严格,或WireMock因模块权限不足无法访问核心类,间接引发计算异常。
  3. WireMock内部逻辑兼容性问题:部分版本在高Java版本下,端口随机分配、时间戳计算(如System.nanoTime()运算)时出现溢出。

分步解决方案

1. 先定位具体溢出位置

当前报错仅显示根因,需获取完整异常堆栈跟踪,找到抛出ArithmeticException的具体类和方法,这是精准解决的关键。可通过:

  • 在测试运行配置中开启完整栈打印(如Maven Surefire添加-Dtest.stacktrace=true)。
  • 查看CI/CD日志中的完整异常信息。

2. 修复WireMock与Spring Boot 3的依赖兼容性

  • 统一使用WireMock 3.x的官方坐标:org.wiremock:wiremock(3.x后不再区分jre8包),推荐版本3.3.0+(与Spring Boot 3兼容性最佳)。
  • 排除冲突依赖(如Spring Boot自带的Netty、Jetty):
<dependency>
    <groupId>org.wiremock</groupId>
    <artifactId>wiremock</artifactId>
    <version>3.3.0</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3. 解决端口/时间计算溢出问题

若堆栈显示溢出发生在端口分配或时间计算:

  • 手动指定WireMock端口,避免随机分配时的计算错误:
@BeforeEach
void setUp() {
    WireMock.configureFor("localhost", 8089); // 固定端口
}
  • 检查自定义WireMock配置(如超时),避免设置超过Long.MAX_VALUE的数值,确保单位正确(毫秒/秒)。

4. 处理Java 17模块权限

若溢出是反射权限不足导致的间接错误:

  • 在测试JVM参数中添加模块开放权限:
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
  • 或在Maven Surefire插件中配置:
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>
            --add-opens java.base/java.lang=ALL-UNNAMED
            --add-opens java.base/java.util=ALL-UNNAMED
        </argLine>
    </configuration>
</plugin>

5. 规范WireMock初始化方式

  • 使用WireMock 3.x提供的@WireMockTest注解替代手动初始化,确保与Spring上下文启动顺序兼容:
@SpringBootTest
@WireMockTest(httpPort = 8089)
public class IntegrationTest {
    // 测试逻辑
}
  • 避免在Spring上下文加载前启动WireMock,防止资源冲突。

6. 验证Jersey兼容性

确保Jersey客户端版本与Spring Boot 3匹配(Spring Boot 3对应Jersey 3.x,基于Jakarta EE 9),避免客户端与WireMock交互时的潜在错误。


内容的提问来源于stack exchange,提问作者aviral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:25:17