Spark 链接 Mongodb 报错:java.lang.NoSuchFieldError: UNSPECIFIED

  • Post author:
  • Post category:java


这两天写 spark 的各种连接器,今天连接 mongodb 的时候遇到了一个很稀少的错误,这里记录一下,同时给遇到相同问题的朋友提供一个解决方案。



spark connect mongodb

这里是我写的一个简单的测试:

	val mongoUrl="mongodb://192.168.*.***/"
    val database="XXX"
    val dbCollection="XXXXXX"
    val  port = 27017

    // TODO: 方法一
    val spark = SparkSession.builder()
      .master("local[*]")
      .appName("ReadMongodb")
      .config("spark.mongodb.input.uri", mongoUrl)
      .config("spark.mongodb.input.database", database)
      .config("spark.mongodb.input.collection", dbCollection)
      .getOrCreate()

    val frame = MongoSpark.load(spark)
    frame.printSchema()
    frame.createTempView("table")
    val res = spark.sql("select * from table limit 10")
    res.show()

	// TODO: 方法二
    val collection = new StructType()
      .add("_id", DataTypes.StringType)
      .add("deviceCode", DataTypes.StringType)
      .add("funCode", DataTypes.StringType)
      .add("deptId", DataTypes.StringType)
      .add("deptName", DataTypes.StringType)
      .add("monthId", DataTypes.StringType)
      .add("mountName", DataTypes.StringType)
      .add("deviceId", DataTypes.StringType)
      .add("pointId", DataTypes.StringType)
      .add("pointOrderNum", DataTypes.StringType)
      .add("value", DataTypes.StringType)
      .add("pointDisplayName", DataTypes.StringType)
      .add("unit", DataTypes.StringType)
      .add("pointName", DataTypes.StringType)
      .add("originName", DataTypes.StringType)
      .add("originTime", DataTypes.StringType)
      .add("createTime", DataTypes.StringType)
      .add("_class", DataTypes.StringType)

    val session = SparkSession.builder().master("local").appName("test").getOrCreate()
    val table = session.read.schema(collection)
      .format("com.mongodb.spark.sql")
      .option("spark.mongodb.input.uri", mongoUrl + database + "." + dbCollection)
      .option("spark.mongodb.input.batchSize", 1000)
      .option("spark.mongodb.input.partitioner", "MongoPaginateByCountPartitioner")
      .option("spark.mongodb.input.partitionerOptions.partitionKey", "_id")
      .option("spark.mongodb.input.partitionerOptions.numberOfPartitions", 32)
      .load().createTempView("table")

    session.sql("select * from table limit 10").toDF().printSchema()



error message

经过测试,代码是没有任何问题的,但是无论哪种方法都会有一个报错:

Exception in thread “main” java.lang.NoSuchFieldError: UNSPECIFIED

具体报错信息如图:

在这里插入图片描述

信息意思是配置不完全,配置信息不明确!

网上找了好多帖子都没有类似情况的,然后微信上请教了他人;奇怪的是,类似的代码,他的能跑,我的就是有报错。



solution

最后我觉得应该不是代码的问题,会不会是依赖版本的问题。

尝试降低了 mongo-spark-connector 依赖的版本,果然不报错了,问题解决。

    <!-- https://mvnrepository.com/artifact/org.mongodb.spark/mongo-spark-connector -->
    <dependency>
      <groupId>org.mongodb.spark</groupId>
      <artifactId>mongo-spark-connector_2.12</artifactId>
      <version>3.0.0</version>
    </dependency>

版本降低至 2.4 即可

    <!-- https://mvnrepository.com/artifact/org.mongodb.spark/mongo-spark-connector -->
    <dependency>
      <groupId>org.mongodb.spark</groupId>
      <artifactId>mongo-spark-connector_2.12</artifactId>
      <version>2.4.0</version>
    </dependency>

总结:版本不匹配问题,究竟为什么,具体我也讲不出,有大佬知道的,欢迎找我探讨。



版权声明:本文为weixin_42151880原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。