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

JDK8升级至JDK17时Jersey服务报NoClassDefFoundError求助

JDK8升级JDK17时Jersey 2.35初始化异常排查与适配方案

问题背景

基于Maven的Java项目从JDK8升级至JDK17,使用Jersey 2.35版本,启动时出现Servlet初始化异常,阻碍升级进度。

异常栈信息

顶层异常

javax.servlet.ServletException: Servlet.init() for servlet [Servlet_Class] threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:833)

根因异常

java.lang.NoClassDefFoundError: Could not initialize class org.glassfish.jersey.internal.inject.Providers
org.glassfish.jersey.model.internal.ComponentBag.modelFor(ComponentBag.java:495)
org.glassfish.jersey.model.internal.ComponentBag.lambda$registerModel$10(ComponentBag.java:454)
org.glassfish.jersey.internal.Errors.process(Errors.java:292)
org.glassfish.jersey.internal.Errors.process(Errors.java:274)
org.glassfish.jersey.internal.Errors.process(Errors.java:205)
org.glassfish.jersey.model.internal.ComponentBag.registerModel(ComponentBag.java:446)
org.glassfish.jersey.model.internal.ComponentBag.register(ComponentBag.java:357)
org.glassfish.jersey.model.internal.CommonConfig.register(CommonConfig.java:463)
org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:429)
org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:306)
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154)
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:339)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:833)

项目配置与代码

web.xml配置

<servlet>
      <servlet-name>Servlet_Class</servlet-name>
      <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
      <!--<init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>webservices.Jersey</param-value>
      </init-param> -->
      <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>webservices.Jersey.Servlet_Application</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
      <servlet-name>Servlet_Class</servlet-name>
      <url-pattern>/Jersey/*</url-pattern>
  </servlet-mapping>

Servlet_Application实现代码

package webservices.Jersey;

import org.glassfish.jersey.logging.LoggingFeature;  
import org.glassfish.jersey.server.ResourceConfig;

public class Servlet_Application extends ResourceConfig {
    public Servlet_Application() 
    {
        packages(true, "webservices.Jersey");
        register(LoggingFeature.class);

        register(Servlet_Class.class);
        
    }
}

问题定位

  1. JDK17模块化与反射限制:Jersey 2.35未完全适配JDK17的模块系统(JPMS),其内部依赖的反射操作被JDK17默认禁用的--illegal-access机制阻止,导致org.glassfish.jersey.internal.inject.Providers类初始化失败。
  2. 依赖兼容性缺失:Jersey 2.35的底层依赖(如HK2注入框架、核心组件)未针对JDK17的API变更做适配,触发类加载时的NoClassDefFoundError。
  3. 冗余注册隐患:Servlet_Application中同时调用包扫描和手动注册Servlet_Class,虽然不是本次异常的直接根因,但可能引发重复加载冲突。

适配JDK17的Jersey版本推荐

  • 最低兼容版本:Jersey 2.39.1,该版本开始正式支持JDK17,修复了JPMS模块访问、反射权限等核心适配问题。
  • 推荐稳定版本:Jersey 2.41(截至2024年的最新稳定版),包含更多JDK17及后续版本的兼容性修复,同时修复了多个安全漏洞和功能bug。

解决步骤建议

  1. 统一升级Jersey版本:在Maven的pom.xml中将所有Jersey相关依赖的版本号修改为2.41(或2.39.1),确保组件版本一致,避免版本冲突。
  2. 移除冗余注册代码:删除Servlet_Application中的register(Servlet_Class.class)调用,packages(true, "webservices.Jersey")已完成包内资源类的自动扫描注册。
  3. 可选:调整JVM参数:若升级后仍有反射相关异常,可临时添加JVM启动参数--add-opens java.base/java.lang=ALL-UNNAMED,但优先通过版本升级解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:44:55