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
。
我有一个在版本 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
。