基于Jersey 2.26与Apache Tomcat 9搭建REST服务启动异常求助
刚踩过类似的坑,这种Servlet.init() for servlet [javax.ws.rs.core.Application] threw exception的错误,大概率是配置、依赖或者兼容性问题导致的,我给你梳理几个最有效的排查和解决步骤:
1. 先检查web.xml的核心配置是否正确
很多人会在这里踩坑:你配置的Servlet类应该是Jersey提供的ServletContainer,而不是直接用javax.ws.rs.core.Application。正确的配置示例应该是这样的:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <!-- servlet-name可自定义,用Application类名方便识别 --> <servlet-name>javax.ws.rs.core.Application</servlet-name> <!-- 重点:必须指定Jersey的ServletContainer实现类 --> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <!-- 关键参数:指定REST服务类所在的包,让Jersey自动扫描 --> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.yourpackage.rest</param-value> </init-param> <!-- 让Tomcat启动时就加载这个Servlet,避免首次请求初始化出错 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name> <!-- 要和你的请求路径匹配,比如你用的/resources/* --> <url-pattern>/resources/*</url-pattern> </servlet-mapping> </web-app>
如果之前你直接把servlet-class写成javax.ws.rs.core.Application,那肯定会初始化失败——这只是个抽象类,不是实际的Servlet实现。
2. 核对Jersey依赖包的完整性和版本一致性
Jersey 2.26需要的核心包一个都不能少,而且版本必须统一,别混了不同版本的JAR包。你需要确保WEB-INF/lib下有这些包:
jersey-server-2.26.jarjersey-container-servlet-core-2.26.jarjersey-common-2.26.jarjavax.ws.rs-api-2.1.jar(JAX-RS的API包,要和Jersey版本兼容)- 可选:
jersey-client-2.26.jar(如果不需要客户端调用可以不加,但服务端有时也依赖它)
⚠️ 重要提醒:不要把servlet-api.jar放到WEB-INF/lib里!Tomcat 9本身已经自带了Servlet API,你如果自己加这个包,会导致类加载冲突,直接引发初始化异常。
3. 检查REST服务类的注解是否正确
确认你的REST类和方法上的注解都配置对了,而且类所在的包要和web.xml里jersey.config.server.provider.packages指定的包一致。比如一个标准的REST类示例:
package com.yourpackage.rest; // 这个包要和web.xml里的参数匹配 import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/") // 根路径,配合servlet-mapping的/resources/*,访问路径就是/resources/ public class TestResource { @GET @Produces(MediaType.TEXT_PLAIN) public String getHelloMessage() { return "Hello from Jersey REST Service!"; } }
如果你的类不在扫描包下,或者注解写错了(比如把@Path写成@PathS),Jersey找不到可加载的资源类,也会抛出初始化异常。
4. 查看完整的异常栈定位根源
你目前只看到了顶层的javax.servlet.ServletException,这只是个包装异常,真正的原因在它的cause里。去Tomcat的logs目录下找localhost.log或者catalina.out文件,里面会有完整的异常堆栈信息——比如可能是NoClassDefFoundError(说明某个依赖包缺失)、IllegalStateException(配置参数错误),这些细节能帮你快速定位问题。
按这个顺序排查下来,大概率能解决你的问题。我之前就是因为把Servlet类写错了,折腾了半天,改完配置就正常了。
内容的提问来源于stack exchange,提问作者Prateek Ratnaker

