嵌入式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
相关产品推荐
相关产品推荐

