Vakindu
Vakindu

Reputation: 815

Akka HTTP SBT modules were resolved with conflicting cross-version suffixes in ProjectRrf

I am building an Akka HTTP application using Scala 3 and SBT and it was running fine at the start.

But when I added the new dependencies below to build.sbt, the app began giving the error modules were resolved with conflicting cross-version suffixes in ProjectRrf.

The new dependencies added are: akka-http-circe, akka-http-json4s, json4s-native, circe-generic, scala-logging.

To make the dependencies compatible with scala3, I wrapped some of them using .cross(CrossVersion.for3Use2_13).

What could be the cause of this error?

Thanks in advance!

The New dependencies added:


("com.typesafe.scala-logging" %% "scala-logging"   % "3.9.3").cross(CrossVersion.for3Use2_13),
("de.heikoseeberger" %% "akka-http-circe"          % "1.39.2").cross(CrossVersion.for3Use2_13),
("de.heikoseeberger" %% "akka-http-json4s"         % "1.39.2").cross(CrossVersion.for3Use2_13),
("org.json4s"        %% "json4s-native"            % "4.1.0-M4").cross(CrossVersion.for3Use2_13),
("io.circe"          %% "circe-generic"            % "0.15.0-M1").cross(CrossVersion.for3Use2_13),

build.sbt:


lazy val akkaHttpVersion = "10.6.3"
lazy val akkaVersion    = "2.9.4"

resolvers += "Akka library repository".at("https://repo.akka.io/maven")

fork := true

lazy val root = (project in file(".")).
  settings(
    inThisBuild(List(
      organization    := "com.example",
      scalaVersion    := "3.3.3"
    )),
    name := "eskimi-bidding-agent",
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-http"                % akkaHttpVersion,
      "com.typesafe.akka" %% "akka-http-spray-json"     % akkaHttpVersion,
      "com.typesafe.akka" %% "akka-actor-typed"         % akkaVersion,
      "com.typesafe.akka" %% "akka-stream"              % akkaVersion,
      "com.typesafe.akka" %% "akka-pki"                 % akkaVersion,
      ("com.typesafe.scala-logging" %% "scala-logging"   % "3.9.3").cross(CrossVersion.for3Use2_13),
      ("de.heikoseeberger" %% "akka-http-circe"          % "1.39.2").cross(CrossVersion.for3Use2_13),
      ("de.heikoseeberger" %% "akka-http-json4s"         % "1.39.2").cross(CrossVersion.for3Use2_13),
      ("org.json4s"        %% "json4s-native"            % "4.1.0-M4").cross(CrossVersion.for3Use2_13),
      ("io.circe"          %% "circe-generic"            % "0.15.0-M1").cross(CrossVersion.for3Use2_13),
      "ch.qos.logback"    % "logback-classic"           % "1.2.11",

      "com.typesafe.akka" %% "akka-http-testkit"        % akkaHttpVersion % Test,
      "com.typesafe.akka" %% "akka-actor-testkit-typed" % akkaVersion     % Test,
      "org.scalatest"     %% "scalatest"                % "3.2.12"        % Test
    )
  )

Upvotes: 0

Views: 90

Answers (2)

Dmytro Mitin
Dmytro Mitin

Reputation: 51648

You didn't include the most significant part of the error. It's

[error] Modules were resolved with conflicting cross-version suffixes in ProjectRef(uri("file:/path/to/yourproject/"), "root"):
[error]    com.typesafe.akka:akka-http-core _3, _2.13
[error]    com.typesafe.akka:akka-parsing _3, _2.13
[error]    com.typesafe.akka:akka-http _3, _2.13

Since you write

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-http"                % akkaHttpVersion,
  "com.typesafe.akka" %% "akka-http-spray-json"     % akkaHttpVersion,
  "com.typesafe.akka" %% "akka-actor-typed"         % akkaVersion,
  "com.typesafe.akka" %% "akka-stream"              % akkaVersion,
  "com.typesafe.akka" %% "akka-pki"                 % akkaVersion,

probably you prefer to use _3 versions of libraries rather than _2.13 whenever possible.

So you should exclude

com.typesafe.akka:akka-http-core _2.13
com.typesafe.akka:akka-parsing _2.13
com.typesafe.akka:akka-http  _2.13

If you do sbt dependencyTree you'll see where akka-http-core _2.13 is used

[info]   +-de.heikoseeberger:akka-http-circe_2.13:1.39.2 [S]
[info]   | +-com.typesafe.akka:akka-http_2.13:10.2.7 [S]
[info]   | | +-com.typesafe.akka:akka-http-core_2.13:10.2.7 [S]

[info]   +-de.heikoseeberger:akka-http-json4s_2.13:1.39.2 [S]
[info]   | +-com.typesafe.akka:akka-http_2.13:10.2.7 [S]
[info]   | | +-com.typesafe.akka:akka-http-core_2.13:10.2.7 [S]

So modify dependencies using .exclude(...)

libraryDependencies ++= Seq(
  ...
  ("de.heikoseeberger" %% "akka-http-circe"          % "1.39.2").cross(CrossVersion.for3Use2_13)
    .exclude("com.typesafe.akka", "akka-http-core_2.13"),
  ("de.heikoseeberger" %% "akka-http-json4s"         % "1.39.2").cross(CrossVersion.for3Use2_13)
    .exclude("com.typesafe.akka", "akka-http-core_2.13"),
  ...

Now the error is

[error] Modules were resolved with conflicting cross-version suffixes in ProjectRef(uri("file:/path/to/yourproject/"), "root"):
[error]    com.typesafe.akka:akka-http _3, _2.13

(Probably what we excluded is enough to exclude akka-parsing _2.13 too.)

If you do sbt dependencyTree again you'll see where akka-http _2.13 is used

[info]   +-de.heikoseeberger:akka-http-circe_2.13:1.39.2 [S]
[info]   | +-com.typesafe.akka:akka-http_2.13:10.2.7 [S]

[info]   +-de.heikoseeberger:akka-http-json4s_2.13:1.39.2 [S]
[info]   | +-com.typesafe.akka:akka-http_2.13:10.2.7 [S]

So .exclude(...) again

libraryDependencies ++= Seq(
  ...
  ("com.typesafe.scala-logging" %% "scala-logging"   % "3.9.3").cross(CrossVersion.for3Use2_13),
  ("de.heikoseeberger" %% "akka-http-circe"          % "1.39.2").cross(CrossVersion.for3Use2_13)
    .exclude("com.typesafe.akka", "akka-http-core_2.13")
    .exclude("com.typesafe.akka", "akka-http_2.13"),
  ("de.heikoseeberger" %% "akka-http-json4s"         % "1.39.2").cross(CrossVersion.for3Use2_13)
    .exclude("com.typesafe.akka", "akka-http-core_2.13")
    .exclude("com.typesafe.akka", "akka-http_2.13"),
  ...

Now the project is built successfully.

You can also write this as

libraryDependencies ++= Seq(
  ...
) ++ Seq(
  ("de.heikoseeberger" %% "akka-http-circe"          % "1.39.2").cross(CrossVersion.for3Use2_13),
  ("de.heikoseeberger" %% "akka-http-json4s"         % "1.39.2").cross(CrossVersion.for3Use2_13)
).map(_
  .exclude("com.typesafe.akka", "akka-http-core_2.13")
  .exclude("com.typesafe.akka", "akka-http_2.13")
)

sbt 1.10.2

Upvotes: 4

Gaël J
Gaël J

Reputation: 15050

The error happens because you have the same dependency/artifact pulled (transitively) with incompatible Scala version suffix.

I didn't check your specific case but for instance it could be that:

  • akka-http for Scala 3 pulls library X for Scala 3
  • akka-http-circe for Scala 3 uses 2.13 (due to for3Use2_13) and pulls library X for Scala 2.13

The conflict being that library X is pulled both for Scala 3 and 2.13.

You might get away with it by excluding one of the two versions. This might not always work though depending the library and if there are differences/incompatibilities between the 2.13/3 versions.

Upvotes: 2

Related Questions