web.xml配置init-param导致Tomcat9 JAX-RS应用服务404求助
问题:Tomcat9 + Jersey Servlet添加init-param后/services/*路径返回404
在基于Tomcat9、Java JAX-RS(使用Jersey的org.glassfish.jersey.servlet.ServletContainer)的应用中,发现只要在web.xml的Servlet配置里加入<init-param>标签,/services/*路径就会返回404;移除该标签后,http://localhost:8081/app/services/whatever可以正常访问。
相关web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>Test</display-name> <servlet> <display-name>JAX-RS REST Servlet</display-name> <servlet-name>JAX-RS REST Servlet</servlet-name> <servlet-class> org.glassfish.jersey.servlet.ServletContainer </servlet-class> <init-param> <param-name>parname</param-name> <param-value>parval</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JAX-RS REST Servlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
日志对比及疑问
对比有无init-param时的Catalina日志,除时间戳外无其他差异。同时日志中出现了java.lang.ClassCastException,不确定是否和当前问题相关。
含init-param时的Catalina日志
05-Apr-2023 11:04:47.923 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/testDevOps] 05-Apr-2023 11:04:47.933 WARNING [Catalina-utility-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesObjectStreamClassCaches Failed to clear soft references from ObjectStreamClass$Caches for web application [testDevOps] java.lang.ClassCastException: class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap') at org.apache.catalina.loader.WebappClassLoaderBase.clearCache(WebappClassLoaderBase.java:2325) at org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesObjectStreamClassCaches(WebappClassLoaderBase.java:2300) at org.apache.catalina.loader.WebappClassLoaderBase.clearReferences(WebappClassLoaderBase.java:1669) at org.apache.catalina.loader.WebappClassLoaderBase.stop(WebappClassLoaderBase.java:1597) at org.apache.catalina.loader.WebappLoader.stopInternal(WebappLoader.java:463) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5515) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:814) at org.apache.catalina.startup.HostConfig.undeploy(HostConfig.java:1466) at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1391) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1654) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:315) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1162) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1365) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1347) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:829) 05-Apr-2023 11:04:51.828 INFO [http-nio-8081-exec-7] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/var/lib/tomcat9/webapps/testDevOps.war] 05-Apr-2023 11:04:52.340 INFO [http-nio-8081-exec-7] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 05-Apr-2023 11:04:52.439 WARNING [http-nio-8081-exec-7] org.glassfish.jersey.message.internal.MessagingBinders$EnabledProvidersBinder.bindToBinder A class javax.activation.DataSource for a default provider MessageBodyWriter<javax.activation.DataSource> was not found. The provider is not available. 05-Apr-2023 11:04:52.448 WARNING [http-nio-8081-exec-7] org.glassfish.jersey.server.wadl.WadlFeature.configure JAX-B API not found . WADL feature is disabled. 05-Apr-2023 11:04:52.500 INFO [http-nio-8081-exec-7] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/var/lib/tomcat9/webapps/testDevOps.war] has finished in [673] ms
不含init-param时的Catalina日志
05-Apr-2023 11:06:38.449 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/testDevOps] 05-Apr-2023 11:06:38.460 WARNING [Catalina-utility-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesObjectStreamClassCaches Failed to clear soft references from ObjectStreamClass$Caches for web application [testDevOps] java.lang.ClassCastException: class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap') at org.apache.catalina.loader.WebappClassLoaderBase.clearCache(WebappClassLoaderBase.java:2325) at org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesObjectStreamClassCaches(WebappClassLoaderBase.java:2300) at org.apache.catalina.loader.WebappClassLoaderBase.clearReferences(WebappClassLoaderBase.java:1669) at org.apache.catalina.loader.WebappClassLoaderBase.stop(WebappClassLoaderBase.java:1597) at org.apache.catalina.loader.WebappLoader.stopInternal(WebappLoader.java:463) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5515) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:814) at org.apache.catalina.startup.HostConfig.undeploy(HostConfig.java:1466) at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1391) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1654) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:315) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1162) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1365) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1347) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:829) 05-Apr-2023 11:06:39.945 INFO [http-nio-8081-exec-12] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/var/lib/tomcat9/webapps/testDevOps.war] 05-Apr-2023 11:06:40.400 INFO [http-nio-8081-exec-12] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 05-Apr-2023 11:06:40.506 WARNING [http-nio-8081-exec-12] org.glassfish.jersey.message.internal.MessagingBinders$EnabledProvidersBinder.bindToBinder A class javax.activation.DataSource for a default provider MessageBodyWriter<javax.activation.DataSource> was not found. The provider is not available. 05-Apr-2023 11:06:40.512 WARNING [http-nio-8081-exec-12] org.glassfish.jersey.server.wadl.WadlFeature.configure JAX-B API not found . WADL feature is disabled. 05-Apr-2023 11:06:40.594 INFO [http-nio-8081-exec-12] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/var/lib/tomcat9/webapps/testDevOps.war] has finished in [650] ms
排查建议
- 检查Jersey版本兼容性:旧版Jersey可能在处理自定义init-param时存在适配Tomcat9的问题,建议升级到Jersey 2.35及以上版本(适配Java 8+和Tomcat9的稳定分支)
- 替换自定义init-param为Jersey标准参数:比如添加
jersey.config.server.provider.packages参数指定你的JAX-RS资源所在包路径,测试是否仍出现404,排除自定义参数名的干扰 - 开启Jersey调试日志:在Tomcat的
logging.properties中添加org.glassfish.jersey.level = FINE,查看请求到达Servlet后的路由匹配细节,确认是否存在资源匹配失败的日志 - 验证Servlet初始化状态:添加
ServletContextListener,在contextInitialized方法中打印Servlet的init参数,确认参数是否被正确加载 - 关于ClassCastException:该异常发生在web应用卸载阶段,属于Tomcat9在特定Java版本下的已知小问题,和当前请求404无关联,可忽略,不影响应用运行
内容的提问来源于stack exchange,提问作者lewap02
相关产品推荐
相关产品推荐

