java.lang.NoSuchMethodError 在 Scala SBT 中 Shell 执行 JAR 后

java.lang.NoSuchMethodError in Scala SBT Shell after executing JAR

在使用 SBT(版本 1.3.13)打包并执行 Scala 应用程序(build.sbt 版本 2.12.0,但实际上安装了 2.13.3)之后,我收到以下错误:

Exception in thread "main" java.lang.NoSuchMethodError: scala.Predef$.wrapRefArray([Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
    at org.example.GreetWorld$.printMessage(GreetWorld.scala:5)

导致错误的源文件 GreetWorld.scala 如下所示:

package org.example

object GreetWorld {
      def printMessage(theMessage:String):Unit = {
            println(s"${theMessage} from me")
      }
}

调用上面文件的主文件如下所示:

package org.example

object HelloWorld {
    def main(args: Array[String]) = {
        GreetWorld.printMessage("Hello")
    }
}

有人知道根本原因吗?起初我以为这与SBT shell选择Java 11有关,但即使将我的Windows' JAVA_HOME更改为Java 8,我仍然得到同样的错误。在 SBT Shell 中编译和 运行 它工作正常。只有 JAR 执行失败。

错误很简单。当您 运行 package 时,您创建了一个 JAR,它仅包含与您的源代码相对应的 classes,仅此而已。并且您的代码依赖于 Scala 标准库,因此如果您尝试使用 java - jar 运行 它将会失败并出现 class 路径错误。

您有 4 个解决方案:

  1. 运行 JAR 直接使用 scala。但是,您需要使用与编译时相同的主要版本。

  2. 在 运行ning 时将 Scala 库 jar 放在 class 路径中。这个和上面基本一样。因此,您必须再次使用相同的主要版本。

  3. 使用 sbt-assembly.[= 创建一个已经包含 Scala stdlib (以及任何其他依赖项) 的 uber jar 15=]

  4. 使用 sbt-native-packager.

    创建一个将为您设置所有内容的本机可分发文件

对于本地开发和测试,选项 1 通常是最好的。
对于简单的项目,选项 3 是,恕我直言,最简单的选择。
对于非常复杂的项目,选项 4 非常受欢迎。