Dataproc版本升级报错:期望类加载器为URLClassLoader实例
问题详情
我们一直基于CDF 6.8.2和Dataproc 2.0.79-debian10运行Cloud Data Fusion管道。因Dataproc 2.0镜像即将停止支持,尝试单独将Dataproc升级至2.1.35-debian11,不升级Datafusion。但在新版本Dataproc上运行相同管道时,作业启动失败,报错信息如下:
2023-12-22 00:10:28,817 ERROR runtimejob.DataprocJobMain: Uncaught exception from thread Thread[main,5,main]
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.google.cloud.hadoop.services.agent.job.shim.HadoopRunClassShim.main(HadoopRunClassShim.java:19)
Caused by: java.lang.RuntimeException: Classloader is expected to be an instance of URLClassLoader
at io.cdap.cdap.runtime.spi.runtimejob.DataprocJobMain.main(DataprocJobMain.java:94)
... 5 more
怀疑是Java兼容性问题,询问是否可通过添加额外参数使两个版本兼容。
解决方案
问题根源
Dataproc 2.1默认使用Java 11,而CDF 6.8.2的运行时代码依赖URLClassLoader类。但Java 9及以上版本中,系统类加载器已改为AppClassLoader(不再继承URLClassLoader),导致代码中的类型转换逻辑触发异常。
兼容参数配置
可以通过添加JVM参数强制类加载器兼容,具体操作如下:
打开Cloud Data Fusion管道的作业配置,找到Dataproc高级属性模块,添加以下两组参数:
- 针对Driver节点:
- 键:
spark.driver.extraJavaOptions - 值:
-Djdk.system.class.loader=com.sun.nio.zipfs.ZipFSClassLoader
- 键:
- 针对Executor节点:
- 键:
spark.executor.extraJavaOptions - 值:
-Djdk.system.class.loader=com.sun.nio.zipfs.ZipFSClassLoader
- 键:
若上述参数无效,可尝试替换为:
- Driver/Executor的参数值改为:
-Djava.system.class.loader=jdk.internal.loader.ClassLoaders$AppClassLoader
- 针对Driver节点:
验证步骤
- 保存修改后的管道配置,重新提交作业
- 查看作业日志,确认
Classloader is expected to be an instance of URLClassLoader错误是否消除 - 若问题仍存在,可尝试将CDF运行时依赖包更新至适配Java 11的版本(无需升级CDF主版本)
内容的提问来源于stack exchange,提问作者Kolli

