scala 使用的是随二进制分发版一起提供的 akka 而不是 sbt 的

scala is using akka shipped with binary distribution instead of sbt 's one

我有一个在版本 2 中使用 akka 的项目。11_2.5.21 在我的 fat jar 中组装。

我已经下载了 scala 二进制 2.11.12,它附带 lib/akka-actor_2.11-2.3.16.jar(在 bin/scala 旁边)

当我 运行 我的项目时:scala -cp target/scala-2.11/project-assembly-2.4.0.jar foo.MyClass 我得到

java.lang.NoSuchMethodError: akka.actor.OneForOneStrategy.withMaxNrOfRetries(I)Lakka/actor/OneForOneStrategy;

如果我在我的 scala 目录中删除 lib/akka-actor_2.11-2.3.16.jar 它会起作用。

当然它也适用于 sbt 运行 因为 sbt 使用它自己的 scala 版本。

为什么 scala 二进制文件使用它自己的 akka 版本而不是 fat jar 中提供的版本?

假设“Scala 二进制文件”指的是 https://downloads.lightbend.com/scala/2.11.12/scala-2.11.12.tgz

的解压结构
➜  scala-2.11.12 tree -L 2
.
├── bin
│   ├── fsc
│   ├── fsc.bat
│   ├── scala
│   ├── scala.bat
│   ├── scalac
│   ├── scalac.bat
│   ├── scaladoc
│   ├── scaladoc.bat
│   ├── scalap
│   └── scalap.bat
├── doc
│   ├── LICENSE.md
│   ├── License.rtf
│   ├── README
│   ├── licenses
│   └── tools
├── lib
│   ├── akka-actor_2.11-2.3.16.jar
│   ├── config-1.2.1.jar
│   ├── jline-2.14.3.jar
│   ├── scala-actors-2.11.0.jar
│   ├── scala-actors-migration_2.11-1.1.0.jar
│   ├── scala-compiler.jar
│   ├── scala-continuations-library_2.11-1.0.2.jar
│   ├── scala-continuations-plugin_2.11.12-1.0.2.jar
│   ├── scala-library.jar
│   ├── scala-parser-combinators_2.11-1.0.4.jar
│   ├── scala-reflect.jar
│   ├── scala-swing_2.11-1.0.2.jar
│   ├── scala-xml_2.11-1.0.5.jar
│   └── scalap-2.11.12.jar
└── man
    └── man1

那么 lib/ 中的所有内容都将优先于您在 -cp 中指定的内容。要查看此内容,请分析以下 bin/scala 运行脚本

的片段
execCommand \
  "${JAVACMD:=java}" \
  $JAVA_OPTS \
  "${java_args[@]}" \
  "${classpath_args[@]}" \
  -Dscala.home="$SCALA_HOME" \
  $OVERRIDE_USEJAVACP \
  "$EMACS_OPT" \
  $WINDOWS_OPT \
   scala.tools.nsc.MainGenericRunner  "$@"

请注意,"${classpath_args[@]}" 包含来自 lib 的罐子,位于最后一个 "$@" 之前,后者包含您的参数,例如 -cp。最后,JVM 将选择 first 匹配它在 class 路径上找到的 class,在您的情况下将是来自 lib/akka-actor_2.11-2.3.16.jar 的路径。例如

scala -cp target/scala-2.11/project-assembly-2.4.0.jar 

会扩展到类似

java -Xbootclasspath/a:/scala-2.11.12/lib/akka-actor_2.11-2.3.16.jar ... scala.tools.nsc.MainGenericRunner -cp target/scala-2.11/project-assembly-2.4.0.jar

因此 Xbootclasspath 将优先于 -cp