Skip to content

[Bug] Boot BOM 优先时混入 Jetty 11/12,HTTP transport 创建 Servlet 上下文失败 #152

Open

Description

@JingkaiTang

问题与触发条件

在应用优先导入 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

  1. wardseptember commented on Nov 2, 2026

    @wardseptember
    Collaborator

    能帮优化下不,直接支持jetty12。 @JingkaiTang

  2. JingkaiTang commented on Nov 2, 2026

    @JingkaiTang
    ContributorAuthor

    @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 仍待验证。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions