java.lang.NoSuchMethodError: akka.actor.ActorCell.addFunctionRef

Я пытаюсь настроить простой проект akka-http 2.4.2, чтобы протестировать его, но мне это не удается.

Мой встроенный .sbt:

import NativePackagerHelper._

lazy val akkaVersion = "2.4.2"

lazy val root = (project in file(".")).
settings(
name := "akkTest",
version := "0.1",
scalaVersion := "2.11.7")

libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-http-spray-json-experimental" % akkaVersion
)

enablePlugins(JavaServerAppPackaging)

мой фрагмент кода в Main.scala

import akka.http.scaladsl.Http
import akka.stream.ActorMaterializer
import akka.stream.scaladsl._
import akka.actor.ActorSystem


object Main extends App {

implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher

val serverSource =
    Http().bind(interface = "localhost", port = 8080)
val bindingFuture =
    serverSource.to(Sink.foreach { connection => // foreach materializes the source
    println("Accepted new connection from " + connection.remoteAddress)
    }).run()

}

Выдает ошибку при выполнении:

Uncaught error from thread [default-akka.actor.default-dispatcher-2] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[default]
java.lang.NoSuchMethodError: akka.actor.ActorCell.addFunctionRef(Lscala/Function2;)Lakka/actor/FunctionRef;
        at akka.stream.stage.GraphStageLogic$StageActor.<init>(GraphStage.scala:143)
        at akka.stream.stage.GraphStageLogic.getStageActor(GraphStage.scala:904)
        at akka.stream.impl.io.ConnectionSourceStage$$anon$1.preStart(TcpStages.scala:56)
        at akka.stream.impl.fusing.GraphInterpreter.init(GraphInterpreter.scala:468)
        at akka.stream.impl.fusing.GraphInterpreterShell.init(ActorGraphInterpreter.scala:363)
        at akka.stream.impl.fusing.ActorGraphInterpreter.tryInit(ActorGraphInterpreter.scala:502)
        at akka.stream.impl.fusing.ActorGraphInterpreter.preStart(ActorGraphInterpreter.scala:539)
        at akka.actor.Actor$class.aroundPreStart(Actor.scala:472)
        at akka.stream.impl.fusing.ActorGraphInterpreter.aroundPreStart(ActorGraphInterpreter.scala:493)
        at akka.actor.ActorCell.create(ActorCell.scala:580)
        at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:456)
        at akka.actor.ActorCell.systemInvoke(ActorCell.scala:478)
        at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:279)
        at akka.dispatch.Mailbox.run(Mailbox.scala:220)
        at akka.dispatch.Mailbox.exec(Mailbox.scala:231)
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Это должно быть что-то в моей среде, но я не знаю, как отследить проблему. Я использую jdk 1.8u71

[info] Done updating.
[info] Including from cache: ssl-config-akka_2.11-0.1.3.jar
[info] Including from cache: reactive-streams-1.0.0.jar
[info] Including from cache: akka-http-spray-json-experimental_2.11-2.4.2.jar
[info] Including from cache: config-1.3.0.jar
[info] Including from cache: spray-json_2.11-1.3.2.jar
[info] Including from cache: ssl-config-core_2.11-0.1.3.jar
[info] Including from cache: scala-parser-combinators_2.11-1.0.4.jar
[info] Including from cache: scala-java8-compat_2.11-0.7.0.jar
[info] Including from cache: akka-parsing_2.11-2.4.2.jar
[info] Including from cache: akka-http-experimental_2.11-2.4.2.jar
[info] Including from cache: akka-actor_2.11-2.4.2.jar
[info] Including from cache: akka-http-core_2.11-2.4.2.jar
[info] Including from cache: akka-stream_2.11-2.4.2.jar
[info] Including from cache: scala-library-2.11.7.jar

Имейте в виду, что я указываю только на зависимости одной и той же версии akka.

Эта программа отлично работает при использовании sbt run, но не работает при использовании собранного jar с моей собственной программой запуска scala.


person Saif    schedule 23.02.2016    source источник
comment
Думаю, нужно было включить в зависимости и akka-stream-experimental. Не уверен, что это как-то связано с ошибкой.   -  person Wojciech Ptak    schedule 23.02.2016
comment
Я считаю, что в этом случае нет проблем с зависимостями, я пробовал с этими двумя дома, и это сработало.   -  person Saif    schedule 23.02.2016
comment
Возможный дубликат java.lang.NoSuchMethodError с актерами Scala   -  person Suma    schedule 23.02.2016
comment
Не похоже. У меня есть только две зависимости, соответствующие akka 2.4.2.   -  person Saif    schedule 23.02.2016


Ответы (5)


Проблема в том, что Spark внутри использует Akka. Пока вы запускаете задание Spark как автономное приложение (например, sbt run), это не проблема, поскольку будет использоваться ваша собственная версия Akka. Однако все меняется, как только вы отправляете свое приложение в кластер с spark-submit. Затем загрузчик классов Spark выберет внутреннюю версию Akka, а не реализацию Akka, входящую в ваш файл sparkJob.jar. Таким образом, указанный выше NoSuchMethodError происходит от akka-stream_2.11-2.4.2, вызывающего akka-actor_2.11-2.3.x.jar, который используется в Spark, вместо akka-actor_2.11-2.4.2.jar, который связан с вашей работой. Метод addFunctionRef на самом деле очень недавнее добавление и отсутствует в более ранних версиях Akka. Вы можете проверить это, установив точку останова в том месте, где возникает исключение (или используйте точку останова исключения). Приостановив приложение в проблемном месте в GraphStage, оцените

materializer.supervsor.getClass().getResource("ActorCell.class")

Это распечатает местоположение файла класса ActorCell, из которого он был загружен.

Чтобы убедиться, что вы изолированы от версии Akka, которую Spark использует внутри, вы можете использовать параметр --driver-class-path для spark-submit, например

spark-submit --class MyJob \
  --driver-class-path akka-actor_2.11-2.4.2.jar \
  --master spark://master:7077 \
  sparkJob.jar

Если вы сделаете это, я также рекомендую установить akka-actor на "test, provided" в вашем build.sbt, чтобы вы также не включали akka-actor в sparkJob.jar.

person Matthias Langer    schedule 06.04.2016

Scala 2.11 включает в себя старую версию akka-actor. Scala отдает приоритет своим библиотекам над библиотеками, созданными пользователями. Spark может включать в себя то же самое, но внутри Jar сборки.

В scala достаточно удалить akka jar из папки lib. В Spark проблема решается с помощью пути к классу драйвера или с помощью конфигурации SQLContext, чтобы пользовательские библиотеки имели приоритет.

Вопрос без ответа, почему этого не происходит во всех настройках, как этого не происходило дома (возможно, репозиторий ОС не устанавливает scala с библиотекой akka-actor)

https://github.com/sbt/sbt-assembly/issues/204

person Saif    schedule 21.03.2016

Когда это случилось со мной, я решил ее, устранив транзитивную зависимость от более старой версии akka-actor. Несмотря на то, что зависимости кажутся вам очевидными, я бы посоветовал внимательно изучить ваше дерево зависимостей, чтобы увидеть, включена ли более ранняя версия akka-actor.

person greglarious    schedule 21.03.2016
comment
Да, это было решение, которое я тоже нашел. Спасибо - person Saif; 22.03.2016

Для тех, если это произойдет даже с sbt run. Решение для меня состояло в том, чтобы добавить зависимость akka-stream в файл build.sbt, например:

  "com.typesafe.akka" %% "akka-stream" % "2.5.3",
  "com.typesafe.akka" %% "akka-stream-testkit" % "2.5.3" % Test
person Kote    schedule 15.07.2017

У меня была похожая проблема при использовании akka-http-experimental-2.4.11.2 с akka-actor-2.5.6.

dependencies {
    compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.11'
    compile group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.5.6'

    compile group: 'com.typesafe.akka', name: 'akka-http-experimental_2.11', version: '2.4.11.2'
}

И проблема заключалась в том, что akka-http-experimental-2.4.11.2 сам использует com.typesafe.akka:akka-actor:2.4.11.2, который был переопределен 2.5.6.

./gradlew dependencies

compileClasspath - Compile classpath for source set 'main'.
+--- org.scala-lang:scala-library:2.11.11
+--- com.typesafe.akka:akka-actor_2.11:2.5.6
|    +--- org.scala-lang:scala-library:2.11.11
|    +--- com.typesafe:config:1.3.1
|    \--- org.scala-lang.modules:scala-java8-compat_2.11:0.7.0
|         \--- org.scala-lang:scala-library:2.11.7 -> 2.11.11
+--- com.typesafe.akka:akka-http-experimental_2.11:2.4.11.2
|    +--- org.scala-lang:scala-library:2.11.8 -> 2.11.11
|    \--- com.typesafe.akka:akka-http-core_2.11:2.4.11.2
|         +--- org.scala-lang:scala-library:2.11.8 -> 2.11.11
|         +--- com.typesafe.akka:akka-stream_2.11:2.4.11.2
|         |    +--- org.scala-lang:scala-library:2.11.8 -> 2.11.11
|         |    +--- com.typesafe.akka:akka-actor_2.11:2.4.11.2 -> 2.5.6 (*)  <---- Ting
|         |    +--- com.typesafe:ssl-config-akka_2.11:0.2.1
|         |    |    +--- org.scala-lang:scala-library:2.11.8 -> 2.11.11
|         |    |    \--- com.typesafe:ssl-config-core_2.11:0.2.1
|         |    |         +--- org.scala-lang:scala-library:2.11.8 -> 2.11.11
|         |    |         +--- com.typesafe:config:1.2.0 -> 1.3.1
|         |    |         \--- org.scala-lang.modules:scala-parser-combinators_2.11:1.0.4
|         |    |              \--- org.scala-lang:scala-library:2.11.6 -> 2.11.11
|         |    \--- org.reactivestreams:reactive-streams:1.0.0
|         \--- com.typesafe.akka:akka-parsing_2.11:2.4.11.2
|              \--- org.scala-lang:scala-library:2.11.8 -> 2.11.11
\--- org.codehaus.groovy:groovy-all:2.4.12

(*) - dependencies omitted (listed previously)

1) Как только я понизил версию akka-actor до 2.4.11, все заработало нормально.

dependencies {
    compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.11'
    compile group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.4.11'
    compile group: 'com.typesafe.akka', name: 'akka-http-experimental_2.11', version: '2.4.11.2'
}

2) Другим способом является exclude нежелательное akka_actor и явное добавление нужного.

dependencies {
    compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.11'
    compile group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.5.6'
    compile group: 'com.typesafe.akka', name: 'akka-http-experimental_2.11', version: '2.4.11.2' {
       exclude group: "com.typesafe.akka", module: "akka-actor_2.11"         // <- exlude actor 2.4.11.2
    }
}
person prayagupd    schedule 04.11.2017
comment
странная StackoverflowDependency, найдя собственный ответ полезным через неделю. На этот раз это было com.typesafe.akka:akka-http_2.12:jar:10.0.10:compile с com.typesafe.akka:akka-testkit_2.12:jar:2.5.6:test. Как только я понизил версию akka-testkit до com.typesafe.akka:akka-testkit_2.12:jar:2.4.19:test, все заработало. Вероятно, это потому, что akka-http_10.0.10 зависит от akka-stream_2.4.19 - person prayagupd; 10.11.2017
comment
Проверьте этот ответ, чтобы исключить версию akka-actor в sbt - например. "com.typesafe.akka" %% "akka-http" % "10.0.10" exclude("com.typesafe.akka", "akka-actor"), - person prayagupd; 04.12.2017