Scala.js with 3.7.0: package scala contains object and package with same name: caps

I am trying to compile my cross platform project with Scala 3.7.0. The project already compiles with fine with 3.6.4. On JVM everything works fine, however I get following issue on Scala.js:

[warn] package scala contains object and package with same name: caps.
[warn] This indicates that there are several versions of the Scala standard library on the classpath.
[warn] The build should be reconfigured so that only one version of the standard library is on the classpath.

While the error does not say it, the issue is with org.scala-lang:scala3-library_3, which is the one that represents caps as a package instead of object.

It seems it goes away when using:

dependencyOverrides += "org.scala-lang" %% "scala3-library" % "3.7.0",

When checking dependencyTree for JS version of my project, the only instance of scala3-library used by dependencies is org.scala-lang:scala3-library_3:3.3.0, used by enumeratum macros. This is no surprise, the libraries creators are encouraged to use LTS version.

How should this be handled properly?

1 Like

Note: the issue can be reproduced with a simple Scala.js enumeratum project. See GitHub - OndrejSpanel/Enumeratum-Scala3.7: Repro demonstrating issue of mixed Scala3 libraries

Here’s a dedicated issue Build tools issues discovered by binary breakage changes in Scala 3 stdlib · Issue #22890 · scala/scala3 · GitHub and we’re working on resolving this issue.

Typically this kind of issues arise if eviction mechanism picks Scala stdlib (scala3-library_3 artifacts) with version lower then Scala compiler version (scala3-compiler_3 artifacts).

We’ve found out that sometime it can happen when using libraryDependenices := instead of libraryDependenices ++= (probably a hidden stdlib dependency is added by sbt), but it was sometimes also coused by some sbt plugins, eg. the one used by typelevel ecosystem.

One workaround to this problem might be adding explicit dependency scala3-library % scalaVersion.value to ensure that compiler and stdlib are using the same version.

1 Like

My repro is extremely simple. Its sbt is just:

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "3.7.0"

lazy val root = (project in file("."))
  .enablePlugins(ScalaJSPlugin)
  .settings(
    name := "SandboxJS",
    scalaJSUseMainModuleInitializer := true,
    libraryDependencies += "com.beachape" %%% "enumeratum" % "1.7.6"
  )

The Scala.js sbt plugin is modifing the libraryDependencies under the hood, maybe there is some bug in there.

I confirm it can be fixed with:

libraryDependencies += "org.scala-lang" %% "scala3-library" % scalaVersion.value

or

dependencyOverrides += "org.scala-lang" %% "scala3-library" % scalaVersion.value
3 Likes

I just ran into this issue when running with the scala runner (not sbt):
It works fine to use my fat jar like so:

image

But when bumping to 3.7 it gives my the same warning as in the title of this question:

Copy-paste-friendly reproduction:

scala repl -S 3.7.4 --dep reqT:reqT:4.6.3,url=https://github.com/reqT/reqT/releases/download/v4.6.3/reqT-4.6.3.jar

The assembly jar is built with the LTS version Scala 3.3.7 using sbt.

Is there a way for me to fix this while using the scala runner like above?

I tried to add --dep org.scala-lang::scala3-library:3.7.4 but that did not help:
image

Will it be fixed in 3.8.0 even if the fat jar contains Scala 3.3.7. Or do I need to compile it with the assembly with latest non-LTS? @WojciechMazur

This error occurs when scala3-compiler uses different version than scala3-library. In your case you’re using fat jar with embeded scala3-library:3.3.7. When you run REPL you’re using scala3-compiler with the same version as specified (so either 3.7.4, or 3.8.0) - this introduces a conflict.

I don’t think REPL was ever designed to be used with (Scala) fat jars, it breaks the eviction mechanism currently. We might need a larger refactor in the compiler to fix that so that scala-library defined in the fat-jar would be ignored.

It was not fixed in 3.8.0, I’ve just tested it with RC4.
This problem existed in all Scala versions, but it has started to be visible only since 3.7 when first binary incompatible change for experimental definition was introduced.

If sticking to LTS published fat-jar is a hard requirement I’d recommend to use the 3.3 LTS line also at runtime when using REPL.

1 Like

Many thanks for the investigation and explanation @WojciechMazur . I will consider if leaving the LTS behind is viable for my users of the reqT app and lib. Perhaps waiting until 3.8 is released and then rebasing the lib on that is the way to go, given the current situation.

It would be marvelous if there was a way to use a fat jar with the repl of a newer version by somehow give prio to the working stdlib version. Otherwise a fat jar will always nail the compatible repl version to an eventually old one…