在Google Dataproc集群使用DriverManager连接Azure SQL时遭遇com.microsoft.aad.adal4j.AuthenticationException类未找到错误
你遇到的java.lang.NoClassDefFoundError: com/microsoft/aad/adal4j/AuthenticationException错误,核心原因很明确:你的Dataproc集群环境里缺了adal4j这个依赖包。
虽然Spark的Azure SQL JDBC连接器已经集成了部分必要组件,但直接用DriverManager.getConnection做连接检测时,需要额外的ADAL(Active Directory Authentication Library)相关依赖来处理Azure的AD密码认证逻辑——你的本地开发环境大概率通过Maven/Gradle或者IDE自动拉取了这个依赖,但Dataproc集群默认没有预装它。
下面给你几个可行的解决方案:
方案一:提交作业时手动引入依赖
在spark-submit命令里通过--packages参数直接从Maven仓库拉取adal4j包,这样作业运行时会自动加载依赖:
spark-submit \ --packages com.microsoft.azure:adal4j:1.6.7 \ --class your.main.ApplicationClass \ your-spark-app.jar
注意版本可以根据你使用的SQL Server JDBC驱动版本调整,尽量保持版本兼容。
方案二:把依赖包放到集群全局类路径
如果不想每次提交作业都加参数,可以把adal4j的jar包上传到Dataproc集群的Spark全局jar目录,这样所有Spark作业都能访问到:
# 在集群主节点执行 gsutil cp gs://your-storage-bucket/adal4j-1.6.7.jar /usr/lib/spark/jars/
完成后可以重启Spark服务(部分场景下无需重启也能生效)。
方案三:复用Spark的JDBC连接逻辑(更推荐)
既然你已经能通过Spark连接器正常写入数据,其实完全没必要单独用DriverManager做连接检测——直接用Spark的数据源API做预检测就行,还能复用已有的依赖配置,避免额外的依赖问题:
import org.apache.spark.sql.SparkSession val spark = SparkSession.builder().getOrCreate() val jdbcUrl = "jdbc:sqlserver://***.database.windows.net:1433;databaseName=some_db;encrypt=true;trustServerCertificate=true;authentication=ActiveDirectoryPassword" val connectionProps = new java.util.Properties() connectionProps.setProperty("user", "xxxx") connectionProps.setProperty("password", "******") try { // 执行一个极简查询测试连接(比如查询系统数据库列表) spark.read.jdbc(jdbcUrl, "sys.databases", connectionProps).limit(1).count() log.info("Successfully connected to Azure SQL Server") } catch { case e: Exception => log.error("Failed to connect to Azure SQL Server", e) // 这里添加连接失败后的处理逻辑,比如重试、终止写入流程等 }
这种方式完全贴合Spark的运行环境,不需要额外引入任何依赖。
内容的提问来源于stack exchange,提问作者Harikrishnan Balachandran

