scala 使用的是二进制发行版附带的 akka,而不是 sbt 的发行版

Posted

技术标签:

【中文标题】scala 使用的是二进制发行版附带的 akka,而不是 sbt 的发行版【英文标题】:scala is using akka shipped with binary distribution instead of sbt 's one 【发布时间】:2021-03-04 02:54:37 【问题描述】:

我有一个项目在 2.11_2.5.21 版本中使用 akka,它是我的 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 run,因为 sbt 使用了自己的 scala 版本。

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

【问题讨论】:

为什么 Scala 会包含 Akka?另外,为什么要使用 Scala 运行程序集 JAR 程序集 JAR 的想法是能够仅使用 执行它Java. 【参考方案1】:

假设“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运行脚本的下面sn-p

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 的 jar,位于最后一个 "$@" 之前,后者包含您的参数,例如 -cp。最后,JVM 将选择它在类路径中找到的 first 匹配类,在您的情况下,它将是来自 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

【讨论】:

以上是关于scala 使用的是二进制发行版附带的 akka,而不是 sbt 的发行版的主要内容,如果未能解决你的问题,请参考以下文章

Scala笔记整理:Actor和AKKA

Scala笔记整理:Actor和AKKA

Eclipse 是不是使用自己的发行版发布 ant?

Scala-Unit7-Scala并发编程模型AKKA

如何使用 scala 2.9.x 运行 akka 2.1-snapshots?

使用 Scala/Akka 在 JVM 中进行高频交易