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

Eclipse部署Java Web项目至Tomcat出现Jersey/ASM兼容报错

Eclipse部署Java Web项目Jersey扫描依赖报错修复

问题背景

初始运行环境

  • Eclipse 2022-06 (4.24.0)(官网下载版本)
  • Java JDK 11.0.15.1
  • PostgreSQL Server 14
  • Apache Tomcat 8.5(已在Eclipse中完成配置)
  • 项目所有依赖库统一存放于WEB-INF/lib目录

报错表现

在Eclipse中右键服务器选择Debug模式部署项目时,首先抛出字节码解析数组越界错误:

Exception while processing file, D:\works\micronos\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Cati\WEB-INF\lib\postgresql-42.4.0.jar
java.lang.ArrayIndexOutOfBoundsException: Index 45408 out of bounds for length 17793
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.getClassReader(AnnotatedClassScanner.java:302)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.analyzeClassFile(AnnotatedClassScanner.java:294)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.indexJar(AnnotatedClassScanner.java:256)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.indexJar(AnnotatedClassScanner.java:245)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.indexDir(AnnotatedClassScanner.java:237)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.index(AnnotatedClassScanner.java:196)
    at com.sun.jersey.impl.container.config.AnnotatedClassScanner.scan(AnnotatedClassScanner.java:106)
    at com.sun.jersey.api.core.ClasspathResourceConfig.init(ClasspathResourceConfig.java:135)
    at com.sun.jersey.api.core.ClasspathResourceConfig.<init>(ClasspathResourceConfig.java:106)
    at com.sun.jersey.api.core.ClasspathResourceConfig.<init>(ClasspathResourceConfig.java:88)
    at com.sun.jersey.spi.container.servlet.ServletContainer.createResourceConfig(ServletContainer.java:342)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:144)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1173)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1118)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1011)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4952)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5266)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

giu 21, 2022 10:56:29 PM com.sun.jersey.impl.application.WebApplicationImpl processRootResources
SEVERE: The ResourceConfig instance does not contain any root resource classes.
giu 21, 2022 10:56:29 PM org.apache.catalina.core.ApplicationContext log
SEVERE: Servlet.init() for servlet [ServletAdaptor] threw exception
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
    at com.sun.jersey.impl.application.WebApplicationImpl.processRootResources(WebApplicationImpl.java:713)
    at com.sun.jersey.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:609)
    at com.sun.jersey.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:472)
    at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:541)
    at com.sun.jersey.spi.container.servlet.ServletContainer.load(ServletContainer.java:465)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:147)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1173)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1118)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1011)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4952)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5266)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

后续尝试调整依赖、环境后仍未解决问题:

  1. 更换多个版本的ASM、Jersey依赖,替换为最新版ASM后抛出类不兼容错误:
java.lang.IncompatibleClassChangeError: Found class org.objectweb.asm.MethodVisitor, but interface was expected
  1. 调整运行环境为Java 1.7、使用postgresql-9.4.1212.jre7.jar驱动,仍然抛出资源类缺失错误:
GRAVE: The ResourceConfig instance does not contain any root resource classes.
giu 22, 2022 1:05:24 AM org.apache.catalina.core.ApplicationContext log
GRAVE: Servlet.init() for servlet [ServletAdaptor] threw exception
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
    at com.sun.jersey.impl.application.WebApplicationImpl.processRootResources(WebApplicationImpl.java:713)
    at com.sun.jersey.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:609)
    at com.sun.jersey.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:472)
    at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:541)
    at com.sun.jersey.spi.container.servlet.ServletContainer.load(ServletContainer.java:465)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:147)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1173)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1118)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1011)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4952)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5266)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

根因分析

所有报错是Jersey 1.x版本过旧、依赖组件版本不兼容引发的连锁问题:

  1. 初始数组越界错误:Jersey 1.x内置ASM 3.x字节码解析库,仅支持解析JDK 7及更早版本编译的Class文件。引入的postgresql-42.4.0.jar为高版本JDK编译产物,Class文件版本超出ASM 3.x解析范围,扫描JAR时直接触发越界,整个类扫描流程中断。
  2. 替换新版ASM后的类不兼容错误:ASM从4.0版本开始做了不兼容API调整,将org.objectweb.asm.MethodVisitor从接口改为抽象类,而Jersey 1.x完全基于ASM 3.x API编写,直接替换高版本ASM必然触发类结构不兼容错误。
  3. 切换JDK 1.7、旧版PG驱动后仍提示无可用根资源类:一方面JAR扫描异常直接中断了整个资源类扫描流程,另一方面未明确指定Jersey的资源扫描路径,默认全量扫描逻辑在环境切换后没有正确识别到项目中标注@Path的REST资源类。

修复方案

方案1:最小改动,保留现有Jersey 1.x架构

  • 调整PostgreSQL驱动版本为postgresql-42.2.x系列(如42.2.27),该系列驱动为JDK7/8兼容编译版本,可被ASM 3.x正常解析,禁止使用42.3.0及以上高版本PG驱动。
  • 删除手动引入的高版本ASM依赖,保持Jersey 1.x自带的ASM 3.x版本不变,避免API不兼容问题。
  • 修改web.xml中Jersey Servlet配置,明确指定资源类扫描包路径,禁止全量扫描所有依赖JAR,既避免第三方JAR扫描异常,也能加快启动速度。配置示例如下:
<servlet>
    <servlet-name>ServletAdaptor</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.your.project.resource</param-value>
        <!-- 上述值替换为项目中实际存放@Path注解资源类的包路径 -->
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
  • 若继续使用JDK 11运行,需在Tomcat启动配置的VM参数中添加--add-opens java.base/java.lang=ALL-UNNAMED,规避高版本JDK模块化限制导致的反射报错。

方案2:长期稳定方案

直接将Jersey 1.x升级到Jersey 2.x或其他仍在维护的REST框架,新版本框架内置高版本ASM,支持JDK8-17版本的Class文件解析,不存在ASM版本不兼容的历史包袱,后续升级JDK、引入第三方依赖也不会触发同类扫描错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:24:35