Java连接Spark报错UnavailableException:ServletContainer非javax.servlet.Servlet
错误原因及解决方案
错误原因
这个错误的核心是Servlet API版本/包名冲突:
Spark底层依赖javax.servlet包下的Servlet API(比如Spark 3.x对应javax.servlet-api 3.1.0),而你的项目中大概率出现了以下两种冲突情况:
- 引入了Jakarta EE版本的Servlet API(包名已改为
jakarta.servlet),导致类加载时无法识别org.glassfish.jersey.servlet.ServletContainer为javax.servlet.Servlet的实现类; - 引入了与Spark内置版本不兼容的
javax.servlet-api高/低版本,引发类定义不匹配。
解决方法
1. 统一Servlet API版本,匹配Spark依赖
在构建配置(Maven/Gradle)中明确指定与Spark兼容的javax.servlet-api版本,并排除其他依赖自带的冲突版本:
Maven示例:
<!-- 明确指定Spark兼容的Servlet API版本 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- 排除其他依赖(如Spring Boot)自带的冲突Servlet API --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </exclusion> </exclusions> </dependency>
Gradle示例:
// 明确指定Servlet API版本 implementation 'javax.servlet:javax.servlet-api:3.1.0' // 排除Spring Boot的冲突依赖 implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'javax.servlet', module: 'javax.servlet-api' }
2. 对齐Jersey依赖版本
Spark内置的Jersey版本(如Spark 3.x用Jersey 2.29.x)需与项目中自行引入的Jersey版本一致,避免类冲突。如果项目不需要额外Jersey功能,建议直接使用Spark自带的Jersey依赖,不要自行引入。
3. Spark Submit运行时排除冲突包
如果通过spark-submit提交应用,可通过参数直接排除冲突的Servlet API包:
spark-submit --exclude-packages jakarta.servlet:jakarta.servlet-api --class com.your.package.MainClass your-application.jar
4. 禁用Jakarta EE Servlet API
确保项目中没有引入jakarta.servlet:jakarta.servlet-api,完全使用javax.servlet包下的API,避免包名不兼容问题。
内容的提问来源于stack exchange,提问作者ritratt
相关产品推荐
相关产品推荐

