akka-http icon indicating copy to clipboard operation
akka-http copied to clipboard

[Scala 3] NoSuchMethodError when trying to create Http

Open jgongo opened this issue 2 years ago • 3 comments

Sorry, I don't know if this is a bug in Akka HTTP, or a bug in Scala 3 / CrossVersion itself, so I'm reporting it here just in case. If this is not the proper place I'd be glad to create another issue if you point me in the right direction. Or maybe this isn't worthy to fix, as there is already ongoing work to publish a Scala 3 version of Akka HTTP...

Anyway, I have the following build.sbt:

ThisBuild / scalaVersion := "3.1.2"

ThisBuild / version := "0.1.0-SNAPSHOT"

lazy val root = (project in file(".")).settings(
  name := "xxxxxx",
  idePackagePrefix := Some("xxxxxx"),
  // Dependencies
  libraryDependencies ++= {
    val akkaVersion = "2.6.19"
    val akkaHttpVersion = "10.2.9"

    val logbackVersion = "1.2.11"

    val scalaTestVersion = "3.2.11"
    val scalaCheckVersion = "1.15.4"

    Seq(
      // Akka
      // TODO: Remove CrossVersion as soon as Akka HTTP releases a Scala 3 version: https://github.com/akka/akka-http/pull/4079
     ("com.typesafe.akka" %% "akka-http"            % akkaHttpVersion).cross(CrossVersion.for3Use2_13),
     ("com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion).cross(CrossVersion.for3Use2_13),
      // TODO: Also remove this. Although Akka has versions for Scala 3, there seems to be a problem when combining them with Akka HTTP for Scala 2.13
      // https://stackoverflow.com/questions/71981716/java-lang-nosuchmethoderror-void-akka-actor-extensionid-initakka-actor-exte
     ("com.typesafe.akka" %% "akka-actor-typed"     % akkaVersion).cross(CrossVersion.for3Use2_13),
     ("com.typesafe.akka" %% "akka-stream"          % akkaVersion).cross(CrossVersion.for3Use2_13),

      // Logging
      "ch.qos.logback" % "logback-classic" % logbackVersion,

      // Tests
      "org.scalatest"     %% "scalatest"                % scalaTestVersion  % Test,
      "org.scalacheck"    %% "scalacheck"               % scalaCheckVersion % Test,
     ("com.typesafe.akka" %% "akka-http-testkit"        % akkaHttpVersion   % Test).cross(CrossVersion.for3Use2_13),
     ("com.typesafe.akka" %% "akka-actor-testkit-typed" % akkaVersion).cross(CrossVersion.for3Use2_13)
    )
  }
)

and the following snippet of code:

@main
def main(): Unit = {
  implicit val system = ActorSystem(Behaviors.empty, "actor-system")

  val route = path("hello") {
    get {
      complete("Hello there!")
    }
  }

  Http().newServerAt("localhost", 8080).bind(route)
}

When I try to run this without using CrossVersion for the Akka libraries I get the following exception:

Exception in thread "sbt-bg-threads-1" java.lang.NoSuchMethodError: 'void akka.actor.ExtensionId.$init$(akka.actor.ExtensionId)'
	at akka.http.scaladsl.Http$.<clinit>(Http.scala:845)
...

As mentioned in the code comments I found this StackOverflow discussion where they suggest to use CrossVersion for all the Akka libraries, not only the HTTP ones. This seems to solve the problem.

jgongo avatar May 05 '22 11:05 jgongo

Yes, you cannot mix Scala 2 and Scala 3 artifacts.

There's nothing to do for right now. Scala 3 is not yet supported, but once we have it (#3901), we can add a section to the docs.

jrudolph avatar May 05 '22 11:05 jrudolph

Ok, I didn't know that, I thought you could just pull in versions for 2.13 to be used in Scala 3 along with other Scala 3 artefacts. Thanks for the clarification, and sorry for the noise.

jgongo avatar May 05 '22 13:05 jgongo

Ok, I didn't know that, I thought you could just pull in versions for 2.13 to be used in Scala 3 along with other Scala 3 artefacts. Thanks for the clarification, and sorry for the noise.

You can, as long as there are no inter-dependencies between those artifacts you have pulled in :)

jrudolph avatar May 05 '22 13:05 jrudolph