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

嵌入式Jetty12.0.3运行EE8/EE10 WebApp时Servlet类兼容异常

Jetty 12同时部署EE8与EE10 WAR应用的类冲突问题解决

异常根源

你遇到的javax.servlet.UnavailableException是类加载冲突导致的:Jetty 12的EE8模块依赖javax.servlet包下的Servlet API,而EE10模块依赖jakarta.servlet包下的API(Java EE到Jakarta EE的包名变更)。当两个模块共存时,类加载器会错误地加载到不匹配版本的Servlet接口,导致org.eclipse.jetty.ee8.jsp.JettyJspServlet无法被识别为javax.servlet.Servlet的实现类。

解决方案

1. 为EE8/EE10应用配置隔离类加载器

为每个WebAppContext指定独立的类加载器,确保EE8应用只加载EE8相关依赖,EE10应用只加载EE10相关依赖,避免API包交叉:

// 初始化EE10专属类加载器(仅加载EE10依赖)
URLClassLoader ee10ClassLoader = new URLClassLoader(
    new URL[]{new File("lib/ee10").toURI().toURL()},
    Thread.currentThread().getContextClassLoader().getParent()
);
org.eclipse.jetty.ee10.webapp.WebAppContext context1 = new org.eclipse.jetty.ee10.webapp.WebAppContext();
context1.setClassLoader(ee10ClassLoader);
// 其他EE10应用配置保持不变...

// 初始化EE8专属类加载器(仅加载EE8依赖)
URLClassLoader ee8ClassLoader = new URLClassLoader(
    new URL[]{new File("lib/ee8").toURI().toURL()},
    Thread.currentThread().getContextClassLoader().getParent()
);
org.eclipse.jetty.ee8.webapp.WebAppContext context2 = new org.eclipse.jetty.ee8.webapp.WebAppContext();
context2.setClassLoader(ee8ClassLoader);
// 其他EE8应用配置保持不变...

2. 调整POM依赖,避免全局共存EE8/EE10模块

不在同一个POM中同时引入EE8和EE10的全量依赖,通过Maven的scope控制依赖可见性,仅在编译对应版本应用时生效:

<!-- Jetty核心依赖 -->
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-server</artifactId>
  <version>${jetty.version}</version>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-util</artifactId>
  <version>${jetty.version}</version>
</dependency>

<!-- EE10依赖(仅编译时可用,运行时由类加载器加载) -->
<dependency>
  <groupId>org.eclipse.jetty.ee10</groupId>
  <artifactId>jetty-ee10-webapp</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty.ee10</groupId>
  <artifactId>jetty-ee10-annotations</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>

<!-- EE8依赖(仅编译时可用,运行时由类加载器加载) -->
<dependency>
  <groupId>org.eclipse.jetty.ee8</groupId>
  <artifactId>jetty-ee8-webapp</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty.ee8</groupId>
  <artifactId>jetty-ee8-annotations</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>

3. 禁用父类加载器优先级

当前代码中设置的setParentLoaderPriority(true)会让WebAppContext优先从父类加载器取类,加剧冲突风险。改为false让应用优先使用自身类加载器:

context1.setParentLoaderPriority(false); // EE10应用
context2.setParentLoaderPriority(false); // EE8应用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:35:01