Clay
Clay

Reputation: 735

Scala claims I am using different versions of Akka

View repository at this specific commit here

I'm putting together a small SBT project and to learn how to use akka actors. I was able to get a simple example working with just akka, but as soon as I use an external library things stop working. I get a very large stack trace with this

objc[15196]: Class JavaLaunchHelper is implemented in both 
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java (0x10cc6c4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10ccf84e0). One of the two will be used. Which one is undefined.
Detected java.lang.NoSuchMethodError error, which MAY be caused by incompatible Akka versions on the classpath. Please note that a given Akka version MUST be the same across all modules of Akka that you are using, e.g. if you use akka-actor [2.5.8 (resolved from current classpath)] all other core Akka modules MUST be of the same version. External projects like Alpakka, Persistence plugins or Akka HTTP etc. have their own version numbers - please make sure you're using a compatible set of libraries.                 
Uncaught error from thread [HelloSystem-akka.actor.default-dispatcher-4]: akka.actor.ActorCell.addFunctionRef(Lscala/Function2;)Lakka/actor/FunctionRef;, shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for for ActorSystem[HelloSystem]
java.lang.NoSuchMethodError: akka.actor.ActorCell.addFunctionRef(Lscala/Function2;)Lakka/actor/FunctionRef;

My dependencies look like this:

  object v {
    val akka = "2.5.8"
    val scrape = "0.4.0"
  }

  val akka = Seq(
    "com.typesafe.akka" %% "akka-actor" % v.akka,
    "com.typesafe.akka" %% "akka-slf4j" % v.akka
  )

  val scrape = Seq(
    "io.bfil" %% "scalescrape" % v.scrape
  )

  lazy val allDeps =  akka ++ scrape

I am using this library that also uses akka version 5.8 so what gives? Where could this conflicting version of akka actor be coming from? Here is my build.sbt that includes the conflict manager I attempted using:

import Dependencies._

name := "sputnik-scraper"

version := "0.1"

scalaVersion := "2.12.4"

conflictManager := ConflictManager.strict

dependencyOverrides += "com.typesafe.akka" %% "akka-actor" % "2.5.8"

lazy val root = (project in file(".")).settings(
  libraryDependencies ++= allDeps
)

EDIT: Added code from main.

import akka.actor.{ActorSystem, Props}
import io.bfil.scalescrape.actor.ScrapingActor

object Main extends App {

  val system = ActorSystem("HelloSystem")
  // default Actor constructor
  val helloActor = system.actorOf(Props[ExampleScraper], name = "helloactor")
  helloActor ! "hello"
  helloActor ! "buenos dias"
}


class ExampleScraper extends ScrapingActor {

  private val baseUrl = "https://www.sputnikmusic.com/"

  override def receive: Receive = {
    case _       => grabMainTitle(baseUrl)
  }

  private def grabMainTitle(url: String) =
    scrape {
          get(url) { response =>
            complete(doIt(response))
          }
    }

  private def doIt(response: Any): Unit = {
    println(response)
  }
}

Upvotes: 4

Views: 3510

Answers (2)

Jeffrey Chung
Jeffrey Chung

Reputation: 19527

From the compatibility guidelines for Akka HTTP 10.0.x (scalescrape 0.4.0 depends on Akka HTTP 10.0.1):

Akka HTTP 10.0.x is (binary) compatible with both Akka 2.4.x as well as Akka 2.5.x, however in order to facilitate this the build (and thus released artifacts) depend on the 2.4 series. Depending on how you structure your dependencies, you may encounter a situation where you depended on akka-actor of the 2.5 series, and you depend on akka-http from the 10.0 series, which in turn would transitively pull in the akka-streams dependency in version 2.4 which breaks the binary compatibility requirement that all Akka modules must be of the same version, so the akka-streams dependency MUST be the same version as akka-actor (so the exact version from the 2.5 series).

In order to resolve this dependency issue, you must depend on akka-streams explicitly, and make it the same version as the rest of your Akka environment....

Change your Akka dependencies to the following:

val akka = Seq(
  "com.typesafe.akka" %% "akka-actor" % v.akka,
  "com.typesafe.akka" %% "akka-slf4j" % v.akka,
  "com.typesafe.akka" %% "akka-stream" % v.akka // <-- add this
)

(Note that the compatibility guidelines for the current 10.1.x branch of Akka HTTP have changed.)

Upvotes: 2

Leo C
Leo C

Reputation: 22449

There is a fairly good chance it's caused by Akka-HTTP version 10.0.1 used in scalescrape being out of sync with Akka 2.5. Here's the release note of the more recent Akka-HTTP 10.0.5:

This is the fifth maintenance release of the Akka HTTP 10.0 series. It is primarily aimed at stability aligning the internals with the upcoming Akka 2.5 release. ...

You might want to consider modifying the Akka-HTTP dependency to a more recent version of Akka HTTP 10.0. Latest version as of now is 10.0.11.

Upvotes: 2

Related Questions