【问题标题】:java.lang.NoSuchMethodError: scala.Predef$.refArrayOpsjava.lang.NoSuchMethodError: scala.Predef$.refArrayOps
【发布时间】:2016-10-30 12:16:37
【问题描述】:

我有以下课程:

import scala.util.{Success, Failure, Try}


class MyClass {

  def openFile(fileName: String): Try[String]  = {
    Failure( new Exception("some message"))
  }

  def main(args: Array[String]): Unit = {
    openFile(args.head)
  }

}

其中有以下单元测试:

class MyClassTest extends org.scalatest.FunSuite {

  test("pass inexistent file name") {
    val myClass = new MyClass()
    assert(myClass.openFile("./noFile").failed.get.getMessage == "Invalid file name")
  }

}

当我运行sbt test 时,出现以下错误:

java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps;
        at org.scalatest.tools.FriendlyParamsTranslator$.translateArguments(FriendlyParamsTranslator.scala:174)
        at org.scalatest.tools.Framework.runner(Framework.scala:918)
        at sbt.Defaults$$anonfun$createTestRunners$1.apply(Defaults.scala:533)
        at sbt.Defaults$$anonfun$createTestRunners$1.apply(Defaults.scala:527)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
        at scala.collection.immutable.Map$Map1.foreach(Map.scala:109)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
        at scala.collection.AbstractTraversable.map(Traversable.scala:105)
        at sbt.Defaults$.createTestRunners(Defaults.scala:527)
        at sbt.Defaults$.allTestGroupsTask(Defaults.scala:543)
        at sbt.Defaults$$anonfun$testTasks$4.apply(Defaults.scala:410)
        at sbt.Defaults$$anonfun$testTasks$4.apply(Defaults.scala:410)
        at scala.Function8$$anonfun$tupled$1.apply(Function8.scala:35)
        at scala.Function8$$anonfun$tupled$1.apply(Function8.scala:34)
        at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
        at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
        at sbt.std.Transform$$anon$4.work(System.scala:63)
        at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
        at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
        at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
        at sbt.Execute.work(Execute.scala:235)
        at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
        at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
        at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
        at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
[error] (test:executeTests) java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps;

构建定义:

version := "1.0"

scalaVersion := "2.12.0"

// https://mvnrepository.com/artifact/org.scalatest/scalatest_2.11
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "3.0.0"

我不知道是什么原因造成的。我的课程和单元测试看起来很简单。有什么想法吗?

【问题讨论】:

  • 您也可以分享您的构建定义吗?
  • 我确认您的类方法在标准 scala repl 中按预期工作。一定是 sbt build def 的问题。
  • 在 Scala 2.12 项目中使用 Scala 2.11 JAR 文件时会发生此特定错误。 Scalatest 与 Scala 2.11 和 Scala 2.12 交叉编译,因此您可以通过利用 SBT %% 运算符来避免此错误,如已接受的问题中所示。请参阅我的回答以了解有关 SBT %% 运算符和交叉编译的更多信息,所有 Scala 程序员都必须了解以避免头痛的主题。
  • 对于那些使用 spark 的人来说,你提交的运行时中的 scala 是什么也很重要。对于专门使用 AWS EMR 的用户,他们使用 2.11(至少对于 EMR 5.x.x),尽管 2.12 也与 spark 2.4.x 兼容。

标签: scala


【解决方案1】:

我在具有不同版本的 Scala (IntelliJ IDEA) 的全局库中有 SDK。
文件 -> 项目结构 -> 全局库 -> 删除 SDK -> 重建。 它修复了我的例外。

【讨论】:

  • 拯救了我的一天。谢谢!
  • 太棒了!谢谢!
  • 除此之外还有帮助的另一件事:重新导入 maven 模块(如果您正在使用它)。还要检查项目结构 -> 问题,这可能表明对无效/过时的 scala SDK 库的引用。在扩展故障排除并尝试不同的 scala 版本后,这发生在我身上。
  • 像魅力一样工作。还要在全局依赖中再次添加 scala sdk
【解决方案2】:

scalatest_2.11 是仅与 Scala 2.11.x 兼容的 ScalaTest 版本。写libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.0" % "test"(注意%%)自动选择正确的版本并切换到Scala 2.11.8,直到scalatest_2.12发布(应该很快)。请参阅http://www.scala-sbt.org/0.13/docs/Cross-Build.html 了解更多信息。

【讨论】:

  • ScalaTest 现在可用于 Scala 2.12。
【解决方案3】:

我使用了 IntelliJ,然后再次导入项目。 我的意思是,关闭打开的项目并作为 Maven 或 SBT 导入。 注意:我选择了 mvn(自动导入 Maven 项目) 它消失了。

【讨论】:

  • 或者检查你的scala版本,它应该和你的pom.xml或者sbt设置一样
【解决方案4】:

当您将使用 Scala 2.11 编译的 Scala JAR 文件用于 Scala 2.12 项目时,会发生此错误。

Scala 库一般会与不同版本的 Scala 交叉编译,因此不同的项目版本会发布不同的 JAR 文件到 Maven。例如,Scalatest 版本 3.2.3 将单独的 JAR 文件发布到 Maven 到 Scala 2.10、2.11、2.12 和 2.13,为 you can see here

许多 Spark 程序员在将使用 Scala 2.11 编译的 JAR 文件附加到运行 Scala 2.12 的集群时都会遇到此错误。有关如何将 Spark 项目从 Scala 2.11 迁移到 Scala 2.12 的详细指南,请参阅 here

正如接受的答案所述,在指定 Scala 依赖项时应使用 SBT %% 运算符,以便您可以自动获取与项目的 Scala 版本相对应的库依赖项(如接受的答案中所述)。如果库依赖项没有您要查找的 Scala 版本的 JAR 文件,%% 运算符将无济于事。以 Spark 版本为例:

这个build.sbt 文件可以工作,因为 Spark 3.0.1 有一个 Scala 2.12 版本:

scalaVersion := "2.12.12"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.0.1"

此代码将不起作用,因为 Spark 3.0.1 没有 Scala 2.11 版本:

scalaVersion := "2.12.12"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.0.1"

如果您的库依赖项也被交叉编译,您可以交叉编译您的项目并为不同的 Scala 版本构建 JAR 文件。 Spark 2.4.7 与 Scala 2.11 和 Scala 2.12 交叉编译,因此您可以使用以下代码交叉编译您的项目:

scalaVersion := "2.11.12"
crossScalaVersions := Seq("2.11.12", "2.12.10")
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.4.7"

sbt +assembly 代码将为您的项目构建两个 JAR 文件,一个使用 Scala 2.11 编译,另一个使用 Scala 2.12 编译。发布多个 JAR 文件的库遵循类似的交叉编译工作流程。

【讨论】:

    【解决方案5】:

    根据我的经验,如果在 build.sbt 中匹配 scalatest 版本和 scala 版本后仍然出现错误,则必须考虑在您的计算机上运行的实际 scala 版本。 可以$ scala查看,看到了

    Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_121). Type in expressions for evaluation. Or try :help. 这种类型的消息。 你需要匹配这个 Scala 版本(例如2.12.1 这里)和build.sbt 的版本。

    【讨论】:

      【解决方案6】:

      就我而言,Spark 版本使其不兼容。 更改为 Spark 2.4.0 对我有用。

      【讨论】:

      • AWS EMR 5.x.x 集群始终使用 scala 2.11 进行 spark 提交作业,即使 2.12 scala 应该是与 spark 2.4.x 兼容的选项。
      【解决方案7】:

      这在 DataBricks 中发生在我身上。问题与之前的答案相同,即与 spark 和 scala 版本不兼容。对于 DataBricks,我必须更改集群 DataBricks 运行时版本。默认是 Scala 2.11/Spark 2.4.5,至少升级到 Scala 2.12/Spark 3.0.0

      单击集群 > Cluster_Name > 编辑 > DataBricks 运行时版本

      【讨论】:

      • 2020 年 12 月仍在发生
      【解决方案8】:

      当您使用 SparkHadoopScalajava 时,会出现一些不兼容问题。您可以使用与其他版本兼容的每个版本。我使用 Spark 版本:2.4.1Hadoop:2.7,java:9.0.1 和 Scala:2.11.12 它们相互兼容。

      【讨论】:

      • 需要注意的是,从 Spark 版本 2.4.2 开始,默认发行版是使用 Scala 2.12 编译的;在此之前,默认使用 2.11。因此,如果您遇到此错误并且您在项目中使用 2.11 依赖项,请确保您的 Spark 安装也是使用 2.11 构建的
      【解决方案9】:

      在 Eclipse IDE 中,项目倾向于使用 scala 安装“最新 2.12 捆绑包(动态)”配置进行预选。如果您实际上并未将 2.12 用于您的 Scala 项目并且您尝试通过 IDE 运行您的项目,那么这个问题就会显现出来。

      我还注意到,如果我使用 sbt 命令重建我的 eclipse 项目:“eclipse with-source”,这具有将 eclipse 项目 scala 安装重置回 2.12 设置的副作用(即使我的 build.sbt文件是为 2.11 版本的 Scala 配置的)。因此,请注意这两种情况。

      【讨论】:

        【解决方案10】:

        尝试将以下行添加到您的 build.sbt

        libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
        

        你的 build.sbt 应该是这样的:

        libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.1"
        
        libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
        

        这样,我的错误就解决了。

        【讨论】:

        • libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.1" 和 libraryDependencies += "org.scalatest" %% "scalatest" % "3.0. 1" % "测试"
        • 在maven项目中如何处理?
        【解决方案11】:

        在我的例子中,我有一个依赖于不同版本的 scala 的项目 jar 依赖项。这可以在 Project Structure -> Modules -> (selected project) -> Dependencies 选项卡下找到。项目中的所有其他内容及其库都在 scala 版本 (2.12) 中排列,但另一个 jar 隐藏了对旧版本的传递依赖 (2.11)。

        【讨论】:

          【解决方案12】:

          我正在使用 Apache Spark-3.1.1 和 Apache ignite-2.10 进行 PoC,并尝试将数据从 spark 加载到 ignite 集群。但是在保存数据时出现以下错误。

          java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps;

          我的代码如下:

          df.write
                      .format(FORMAT_IGNITE)
                      .option(OPTION_CONFIG_FILE, CONFIG)
                      .option(OPTION_TABLE, "connect")
                      .option(OPTION_CREATE_TABLE_PRIMARY_KEY_FIELDS, "id")
                      .option(OPTION_CREATE_TABLE_PARAMETERS, "template=replicated").mode(SaveMode.Append)
                      .save()
          

          【讨论】:

          • 谢谢大家,它现在可以工作了,我使用了版本 'ignite-spark-2.4 — 与 Spark 2.4 集成'。谢谢,
          猜你喜欢
          • 2020-08-23
          • 2021-08-18
          • 2017-08-28
          • 1970-01-01
          • 2019-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多