java.lang.NoSuchMethodError: scala.util.Properties$.coloredOutputEnabled()Z

今天在测试spark3.0的过程中,将spark环境的Scala版本提高到2.12.x版本。
一开始我设置的是Scala版本是2.12.0

<properties>
        <scala.version>2.12.0</scala.version>
        <spark.version>3.0.0</spark.version>
</properties>

<dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>${spark.version}</version>
        </dependency>
</dependencies>

简单执行读取MySQL数据库的代码:

package com.gw.sparkSql

import java.util.Properties

import org.apache.spark.sql.{
    
    DataFrame, SparkSession}

/**
  * 利用sparksql从mysql表中读取数据
  */
object DataFromMysql {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //创建sparkSession对象
    val sparkSession: SparkSession = SparkSession.builder().master("local[4]").appName("DataFromMysql").getOrCreate()

    //读取sql数据需要提前设置rul,table和properties
    val data: DataFrame = sparkSession.read.format("jdbc")
      .option("url", "jdbc:mysql://localhost:3306/test11")
      .option("dbtable", "blood")
      .option("user", "root")
      .option("password", "123")
      .load()

    //获取数据
    data.show()
    data.printSchema()

    //释放资源
    sparkSession.stop()
  }
}

结果执行报错:

Exception in thread "main" java.lang.NoSuchMethodError: scala.util.Properties$.coloredOutputEnabled()Z
	at scala.reflect.internal.TypeDebugging$typeDebug$.<init>(TypeDebugging.scala:69)
	at scala.reflect.internal.SymbolTable.typeDebug$lzycompute$1(SymbolTable.scala:28)
	at scala.reflect.internal.SymbolTable.typeDebug(SymbolTable.scala:28)
	at scala.reflect.runtime.JavaUniverseForce.force(JavaUniverseForce.scala:67)
	at scala.reflect.runtime.JavaUniverseForce.force$(JavaUniverseForce.scala:18)
	at scala.reflect.runtime.JavaUniverse.force(JavaUniverse.scala:30)
	at scala.reflect.runtime.JavaUniverse.init(JavaUniverse.scala:162)
	at scala.reflect.runtime.JavaUniverse.<init>(JavaUniverse.scala:93)
	at scala.reflect.runtime.package$.universe$lzycompute(package.scala:29)
	at scala.reflect.runtime.package$.universe(package.scala:29)
	at org.apache.spark.sql.catalyst.ScalaReflection$.<init>(ScalaReflection.scala:50)
	at org.apache.spark.sql.catalyst.ScalaReflection$.<clinit>(ScalaReflection.scala)
	at org.apache.spark.sql.catalyst.encoders.RowEncoder$.serializerFor(RowEncoder.scala:77)
	at org.apache.spark.sql.catalyst.encoders.RowEncoder$.apply(RowEncoder.scala:66)
	at org.apache.spark.sql.Dataset$.$anonfun$ofRows$1(Dataset.scala:92)
	at org.apache.spark.sql.SparkSession.withActive(SparkSession.scala:763)
	at org.apache.spark.sql.Dataset$.ofRows(Dataset.scala:89)
	at org.apache.spark.sql.SparkSession.baseRelationToDataFrame(SparkSession.scala:427)
	at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:279)
	at org.apache.spark.sql.DataFrameReader.$anonfun$load$2(DataFrameReader.scala:268)
	at scala.Option.getOrElse(Option.scala:121)
	at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:268)
	at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:203)
	at com.gw.sparkSql.DataFromMysql$.main(DataFromMysql.scala:20)
	at com.gw.sparkSql.DataFromMysql.main(DataFromMysql.scala)

百度之后发现仅有以下两篇文章涉及到这个问题,而且根本就没有解决方法。
https://stackoverflow.com/questions/60121386/what-dependencies-i-need-to-run-spark-read-csv-in-local-distribution#
https://stackoverflow.com/questions/59935502/java-lang-nosuchmethoderror-boolean-scala-util-properties-coloredoutputenable

没办法只能自己摸索了。
从错误类型来看,很明显示Scala的问题。我首先想到的是Scala2.12.x和Java的版本(我的是Java是1.8版本)对应问题,百度发现其实并不是这个原因。

然后开始针对Scala的版本下手,我首先将Scala的版本改成了:

<scala.version>2.12.1</scala.version>

还是报错。

然后我将Scala的版本改成了2.12.x中最新的版本:

<scala.version>2.12.12</scala.version>

很意外,完美运行。
在这里插入图片描述
以上是瞎猫碰上死耗子,下面是真正的原因分析。

原因分析:
凡是出现NoSuchMethodError一般只会有两种原因:

1、真正的依赖包的缺失,看缺少哪个添加哪个就可以了;
2、依赖包产生了冲突;

至于为什么jar包冲突会产生NoSuchMethodError,参考:
https://blog.csdn.net/ycccsdn/article/details/90549347?depth_1-

这里很明显就第二种原因。
首先回顾我们熟悉的spark2.x版本的依赖包,我一般都是用的2.2.0版本,多年以来下面这个写法一直没变,也就没有深究为什么是这样写:

<properties>
        <scala.version>2.11.8</scala.version>
        <spark.version>2.2.0</spark.version>
</properties>

其实Scala版本和spark版本之间是有对应关系的,这里我使用spark2.2.0,之所以Scala版本选择2.11.8是有原因的。
大家可以看一下spark-core依赖包中有什么?2.2.0版本的spark-core中是存在scala-library依赖的,版本也恰恰是2.11.8。
在这里插入图片描述
所以大家明白了吗,在升级spark3.0后,依赖包也不是随便写的:
我们来看一看spark3.0版本的spark-core包中存在的scala-library依赖是多少版本
在这里插入图片描述
所以到这里问题已经明了,只需将Scala版本和spark-core中的版本对应即可

<properties>
        <scala.version>2.12.10</scala.version>
        <spark.version>3.0.0</spark.version>
</properties>

Scala的版本只要大于等于2.12.10即可。

猜你喜欢

转载自blog.csdn.net/weixin_44455388/article/details/107767760