Spring Boot+ApplicationRunner运行Apache Spark时出现NoClassDefFoundError
问题解决:Spring Boot + Spark 启动时出现 javax.servlet.HttpServletRequest 类找不到错误
问题场景
在Mac OS系统、Java 17环境下,使用Spring Boot 2.6.6(已通过spring.main.web-application-type=none设置为非Web应用)结合ApplicationRunner运行Apache Spark 3.3.2,启动SparkSession时抛出NoClassDefFoundError: javax/servlet/http/HttpServletRequest。
错误原因
Spark 3.3.2的Metrics模块依赖javax.servlet API,但因为你将Spring Boot设置为非Web应用,Spring Boot不会自动引入servlet相关依赖;同时Java 17默认使用Jakarta EE的包结构(jakarta.servlet.*),与Spark所需的javax.servlet.*包不兼容,最终导致类加载失败。
解决方案
方案1:添加javax.servlet API依赖
直接在Maven pom.xml中引入Spark需要的javax.servlet依赖:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
scope=provided表示该依赖仅在编译和测试阶段需要,避免与Spark运行时的依赖冲突。
方案2:禁用Spark的MetricsServlet
既然错误源于Spark的MetricsServlet组件,也可以通过配置直接禁用该sink,修改SparkSession构建代码:
SparkSession spark = SparkSession.builder() .master("local[*]") .config("spark.ui.enabled", "false") .config("spark.metrics.conf", "*.sink.servlet.class=org.apache.spark.metrics.sink.NoOpSink") .getOrCreate();
- 这里用
NoOpSink(空实现)替换默认的MetricsServlet,避免触发servlet相关类的加载。
额外说明
Spark 3.3.x对Java 17的支持为实验性特性,如果后续遇到其他兼容性问题,可以考虑调整Spark版本(如升级到Spark 3.4+,对Java17支持更完善)或Spring Boot版本,但当前问题的核心是servlet依赖缺失或冲突。
内容的提问来源于stack exchange,提问作者Nikhil
相关产品推荐
相关产品推荐

