2

I'm pretty new to scala. While upgrading a multi-module project to Scala 2.13, I found this dependency that is compiled in Scala 2.12 which throws class not found exception during runtime

java.lang.NoClassDefFoundError: scala/collection/mutable/ArrayOps$ofRef

This class is removed in 2.13. It is available only until 2.12. I am looking for a way to enforce v2.12 to compile only this dependency.

I tried to use cross-building but that does not work for a core library, because the dependency url constructed using:

"org.scala-lang" % "scala-library" % scalaVersion.value

looks like

https://repo1.maven.org/maven2/org/scala-lang/scala-library_2.12.15/2.12.15/scala-library_2.12.15-2.12.15.pom

Also, cross-building seems to be the way to allow compiling sub-modules with different scala versions with their compatible dependency versions, not meant for enforcing scala versions on individual dependencies.

Edit 1: This is the build definition:

   root
    |
    main
    |---dependency w/o 2.13 build
    |
    acceptanceTests
    |---dependency w/o 2.13 build
    |
    (other modules)

The dependency is an internal commons library. This uses the class scala/collection/mutable/ArrayOps during compile time. From scala-lang -> scala-library.

My questions:

  1. Is it even possible to do this? Or is my only option to downgrade to 2.12 as mentioned here
  2. Why 'core' libraries do not follow the url patters of external libraries like: [organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]. `Instead it looks like https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.15/scala-library-2.12.15.pom
Gaël J
  • 11,274
  • 4
  • 17
  • 32
trel
  • 21
  • 3
  • 4
    Does the dependency have a `2.13` release? if not then you can't upgrade or you can't use that dependency. – Luis Miguel Mejía Suárez Feb 17 '22 at 19:11
  • No, there isn't a 2.13 release for this dependency. So just to be extra sure I've explained my question correctly . There isn't a way we can do something like: 1. enable cross build for the module that uses the dependency. 2. when cross-building with version 2.12, use scala-lang:scala-library:2.12 3. package the compiled classes to target/2.12/classes – trel Feb 17 '22 at 20:36
  • A single **Scala** artifact can't contain classes compiled using different **Scala** versions, as simple as that. If there is no `2.13` version of that library then there is no way to use that library on a `2.13` codebase. – Luis Miguel Mejía Suárez Feb 17 '22 at 21:23
  • Which library are you talking about? If it's scala-library directly then there are several options. Clarify your build definition and which dependency is problematic. – Gaël J Feb 17 '22 at 21:26
  • @GaëlJ : I have added the build definition. See Edit1 – trel Feb 18 '22 at 08:21
  • From what I understand you need to cross compile your _internal commons library_ to Scala 2.12 and 2.13 and that's all. – Gaël J Feb 18 '22 at 14:49

1 Answers1

1

You can do stuff like this:

libraryDependencies ++= {
  CrossVersion.partialVersion(Keys.scalaVersion.value) match {
    case Some((2, 12)) => Seq(
      "com.typesafe.play" %% "play-json"  % "2.6.13"
    )
    case Some((2, 11)) => Seq( 
      "com.typesafe.play" %% "play-json" % "2.5.18"
    )
    case _ => Seq (
      "com.typesafe.play" %% "play-json" % "2.4.11"
    )
  }
}
Steve Waldman
  • 13,689
  • 1
  • 35
  • 45
  • 1
    This would be the solution when there **is** a version of the dependency compiled in 2.13, right? In my case, there isn't such a version. And as mentioned, one of the classes in the dependency uses a class in scala-lang package that's not available in 2.13 there by making it forward incompatible. – trel Feb 17 '22 at 20:23