迁移Java8 SOAP遗留服务至Tomcat遇ClassCastException问题求助
问题根源
这个ClassCastException的核心原因是Servlet API的包名迁移冲突:Java EE改名为Jakarta EE后,javax.servlet包被迁移为jakarta.servlet。你使用的jaxws-ri版本与Tomcat版本、Servlet API依赖不匹配,导致WSServlet实现的Servlet接口和Tomcat提供的接口分属不同类加载器,无法互相转换。
解决方案
方案1:匹配Tomcat与jaxws-ri版本
若使用Tomcat 10+(支持Jakarta EE 9+)
- 选用jaxws-ri 3.0及以上版本(适配Jakarta EE规范)
- 移除项目中所有
javax.servlet-api依赖,Tomcat 10+自带jakarta.servlet-api,无需打包到war包 - 更新web.xml的命名空间为Jakarta EE规范:
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0">
- 确保web.xml中jaxws的Servlet配置正确:
<listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>myservice</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>myservice</servlet-name> <url-pattern>/myservice/*</url-pattern> </servlet-mapping>
若使用Tomcat 9及以下(支持Java EE 8)
- 改用jaxws-ri 2.3.x版本(适配Java EE 8,基于
javax.servlet) - 移除
jakarta.servlet-api依赖,替换为javax.servlet-api 4.0.1(对应Tomcat 9) - web.xml使用Java EE命名空间:
<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">
方案2:清理依赖冲突
- 检查war包的
WEB-INF/lib目录,确保:- 仅存在一套Servlet API依赖(要么全是
javax.servlet,要么全是jakarta.servlet,禁止混合) - jaxws-ri的所有jar包版本统一,避免不同版本组件混用
- 仅存在一套Servlet API依赖(要么全是
- 不要将Servlet API打包到war中,Tomcat本身会提供对应版本的API,打包易引发类加载冲突
额外检查项
- 若迁移到Java 11+,确认jaxws-ri版本支持对应Java版本:3.0+支持Java 11+,2.3.x支持Java 8-11
- 检查
sun-jaxws.xml(若存在)的路径和配置内容,确保未引用旧的javax包下的类
内容的提问来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

