Repository navigation
Description
问题与触发条件
在应用优先导入 spring-boot-dependencies、随后导入 trpc-dependencies-bom 时,tRPC HTTP transport 的 Jetty 依赖可能混入两个大版本,导致 ServletContextHandler 无法构造。这会阻断 protocol: http/h2、transporter: jetty 服务端的初始化路径。
环境:tRPC 2.0.5、Spring Boot BOM 3.5.16、JDK 21.0.5。
这不是 tRPC 自身默认 BOM 组合必现的问题:其默认管理 Jetty 11.0.25;触发条件是应用让 Boot BOM 的版本管理优先。
实际依赖与原因
trpc-transport-http:2.0.5 声明旧 Jetty Servlet / HTTP2 坐标。Boot BOM 管理相同坐标的核心库后,最终组合为:
jetty-server/http/io/util/security 12.0.36
jetty-servlet 11.0.25
http2-server/common/hpack 11.0.25
jakarta.servlet-api 6.0.0
Jetty 12 的 Servlet 与 HTTP2 使用了新坐标(jetty-ee10-servlet、jetty-http2-server 等),旧坐标仍落到 tRPC BOM 的 11.0.25,因此只覆盖部分组件造成二进制不兼容。
相关源码:HTTP transport POM、JettyHttpServer。
最小复现(已执行)
下面的 POM 仅保留 HTTP transport 涉及的 Jetty / Servlet 依赖,以隔离问题,无需完整业务应用。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>trpc-jetty-bom-repro</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.5.16</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.tencent.trpc</groupId>
<artifactId>trpc-dependencies-bom</artifactId>
<version>2.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Isolate the Jetty dependencies used by trpc-transport-http. -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
</dependencies>
</project>保存为 Probe.java:
public class Probe {
public static void main(String[] args) throws Exception {
Class.forName("org.eclipse.jetty.servlet.ServletContextHandler")
.getConstructor().newInstance();
System.out.println("ServletContextHandler constructed successfully");
}
}在 JDK 21 下执行:
mvn -q org.apache.maven.plugins:maven-dependency-plugin:3.8.1:build-classpath -Dmdep.outputFile=classpath.txt
java --class-path "$(cat classpath.txt)" Probe.java实际结果:
java.lang.NoClassDefFoundError: org/eclipse/jetty/server/handler/ContextHandler$Context
另一次使用完整应用依赖的类加载探针首先报缺少 org/eclipse/jetty/server/handler/HandlerWrapper;两者均来自 Jetty 11 Servlet 对旧核心 API 的引用。
对照实验:在同一最小复现的运行时 classpath 中,仅将 5 个 Jetty 12 核心 JAR 替换为同名 11.0.25 JAR,保留 Servlet 6.0.0 和其他依赖,构造成功。
本次验证止于类加载与 Servlet 上下文构造,没有启动 HTTP 服务;不据此声称 Jetty 11 + Servlet 6 的所有 HTTP 功能均兼容。
希望确认的支持策略
是否计划在 Boot 3 支持分支适配 Jetty 12?如果暂时维持 Jetty 11,建议明确记录应用采用 Boot BOM 时所需的 Jetty 版本管理与 BOM 优先级,避免部分模块被覆盖。
Activity
wardseptember commentedon Nov 2, 2026
能帮优化下不,直接支持jetty12。 @JingkaiTang
JingkaiTang commentedon Nov 2, 2026
@wardseptember 可以,我这边已经基于
JDK17/Springboot3分支做了一版 Jetty 12 EE10 适配:通过 Jetty core / EE10 BOM 统一版本,迁移 Servlet、HTTP/2 和 gateway 的旧依赖坐标,并调整 Servlet 上下文初始化,保留现有HttpExecutor接口。本地 JDK 21 下,HTTP / HTTPS / h2c / h2、POST 正文和异步响应,以及 Boot BOM 优先导入的回归场景均已通过,相关 RPC 测试也已通过。旧版 2.0.5 在同一消费方场景下仍可复现初始化失败。
目前改动还在本地,我再整理一下改动和回归用例,提 PR 供 review。JDK 17 的实际运行和上游 CI 仍待验证。