CDF自定义Dataproc插件报错:无法创建DocumentBuilderFactory类提供者
问题分析与解决方案
问题描述
开发了一款Schema校验的自定义CDAP转换插件,本地CDAP环境测试通过,部署到GCP CDF实例后预览模式运行正常,但在预创建的专属Dataproc集群上执行流水线时抛出如下异常,CDAP版本为6.9.2:
2024-03-06 10:58:28,123 - ERROR [SparkRunner-phase-1:i.c.c.i.a.r.ProgramControllerServiceAdapter@98] - Spark Program 'phase-1' failed. java.lang.Exception: javax.xml.parsers.FactoryConfigurationError: Provider for class javax.xml.parsers.DocumentBuilderFactory cannot be created at io.cdap.cdap.app.runtime.spark.SparkRuntimeService.startUp(SparkRuntimeService.java:389) at com.google.common.util.concurrent.AbstractExecutionThreadService$1$1.run(AbstractExecutionThreadService.java:47) at io.cdap.cdap.app.runtime.spark.SparkRuntimeService.lambda$null$2(SparkRuntimeService.java:525) at java.lang.Thread.run(Thread.java:829) Caused by: javax.xml.parsers.FactoryConfigurationError: Provider for class javax.xml.parsers.DocumentBuilderFactory cannot be created at javax.xml.parsers.FactoryFinder.findServiceProvider(FactoryFinder.java:305) at javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:261) at javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFactory.java:140) at io.cdap.cdap.common.conf.Configuration.asXmlDocument(Configuration.java:1870) at io.cdap.cdap.common.conf.Configuration.writeXml(Configuration.java:1846) at io.cdap.cdap.app.runtime.spark.SparkRuntimeService.saveCConf(SparkRuntimeService.java:908) at io.cdap.cdap.app.runtime.spark.SparkRuntimeService.startUp(SparkRuntimeService.java:334) ... 3 common frames omitted
核心原因
异常根源是JVM无法找到javax.xml.parsers.DocumentBuilderFactory的服务提供者,通常由以下场景导致:
- 自定义插件引入的XML解析依赖(如xerces、xml-apis)与Dataproc集群自带的XML库版本冲突
- Dataproc集群使用的JRE缺失XML解析相关组件(精简版JRE可能不含默认的XML解析库)
- Spark类加载顺序问题,导致集群自带的XML解析库未被优先加载
解决方案
1. 清理插件依赖冲突
检查自定义插件的依赖配置,排除可能引发冲突的XML解析相关jar包,将这类依赖的范围标记为provided(复用CDAP/Dataproc环境自带的库)。例如在Maven项目的pom.xml中添加排除规则:
<dependency> <!-- 你的插件业务依赖 --> <groupId>com.yourcompany</groupId> <artifactId>schema-validation-lib</artifactId> <version>1.0.0</version> <exclusions> <!-- 排除冲突的XML解析依赖 --> <exclusion> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> </exclusion> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> <exclusion> <groupId>org.apache.xalan</groupId> <artifactId>xalan</artifactId> </exclusion> </exclusions> </dependency>
2. 确保Dataproc集群JRE完整性
检查Dataproc节点使用的JDK/JRE版本,确保安装的是完整版本而非精简版。例如对于Debian/Ubuntu系统,安装OpenJDK完整包:
apt-get install openjdk-11-jdk
3. 调整Spark类加载配置
修改Dataproc集群的Spark配置,强制优先加载系统类路径的XML解析库:
- 在集群创建时添加初始化动作,设置Spark属性:
echo "spark.driver.extraClassPath=/usr/lib/jvm/java-11-openjdk-amd64/lib/*" >> /etc/spark/conf/spark-defaults.conf echo "spark.executor.extraClassPath=/usr/lib/jvm/java-11-openjdk-amd64/lib/*" >> /etc/spark/conf/spark-defaults.conf
4. 优化插件打包流程
使用CDAP官方的cdap-maven-plugin工具进行打包,确保只包含必要的业务依赖,避免将JRE自带的XML相关jar包打包进插件包。
内容的提问来源于stack exchange,提问作者Rajiv R
相关产品推荐
相关产品推荐

