Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pin Scala compiler version in Gradle #5299

Closed
magnus-madsen opened this issue Jan 13, 2023 · 7 comments · Fixed by #5305
Closed

Pin Scala compiler version in Gradle #5299

magnus-madsen opened this issue Jan 13, 2023 · 7 comments · Fixed by #5305
Assignees

Comments

@magnus-madsen
Copy link
Member

On my machine, gradle took the liberty to install Scala 2.13.10, but that will not work due to a bug in introduced in Scala 2.13.6 (?)

How can we pin the Scala version?

@magnus-madsen
Copy link
Member Author

#4916

@paulbutcher
Copy link
Member

If I'm reading the documentation correctly, then we are already pinning the Scala version. The Scala Plugin documentation says:

Scala projects need to declare a scala-library dependency. This dependency will then be used on compile and runtime class paths. It will also be used to get hold of the Scala compiler and Scaladoc tool, respectively.

This is confirmed by this StackOverflow answer.

So I think we're already pinning the Scala version to 2.13.5.

What makes you think that it's using 2.13.10?

@magnus-madsen
Copy link
Member Author

I should take my own medicine and report back with something reproducible.

@magnus-madsen
Copy link
Member Author

  1. Checkout Flix in a new IDEA project.
  2. Add implementation('io.get-coursier:coursier_2.13:2.1.0-RC4') to build.gradle.
  3. Click "Elephant button" (reload gradle)
  4. Project no longer compiles because of different scala version.

@magnus-madsen
Copy link
Member Author

Plausible guess:

  • Maybe io.get-coursier:coursier_2.13:2.1.0-RC4 wants a newer version of the Scala library.
  • This (silently?) upgrades the "pinned" version?
  • This in turn pulls a new Scala compiler.

@paulbutcher
Copy link
Member

TLDR, I've worked out how to fix this and will submit a PR. But in the spirit of "teach a man to fish", here's an explanation of what's going on:

It looks like your guess is correct. You can see the dependency tree for a Gradle project with ./gradlew -q dependencies --configuration compileClasspath (the --configuration is there to avoid it showing all the other classpaths Gradle is interested in, which makes it difficult to pick out the wood for the trees). This is what it gives with the current master:

------------------------------------------------------------
Root project 'flix'
------------------------------------------------------------

compileClasspath - Compile classpath for source set 'main'.
+--- org.scala-lang:scala-library:2.13.5
+--- org.scala-lang:scala-reflect:2.13.5
|    \--- org.scala-lang:scala-library:2.13.5
+--- org.java-websocket:Java-WebSocket:1.3.9
+--- org.jline:jline:3.5.1
+--- org.json4s:json4s-native_2.13:3.5.5
|    +--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|    \--- org.json4s:json4s-core_2.13:3.5.5
|         +--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|         +--- org.json4s:json4s-ast_2.13:3.5.5
|         |    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|         +--- org.json4s:json4s-scalap_2.13:3.5.5
|         |    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|         +--- com.thoughtworks.paranamer:paranamer:2.8
|         \--- org.scala-lang.modules:scala-xml_2.13:1.2.0
|              \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
+--- org.ow2.asm:asm:9.2
+--- org.parboiled:parboiled_2.13:2.2.1
|    +--- org.scala-lang:scala-library:2.13.3 -> 2.13.5
|    \--- com.chuusai:shapeless_2.13:2.3.3
|         \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
+--- org.tomlj:tomlj:1.1.0
+--- org.scalactic:scalactic_2.13:3.0.8
|    +--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|    \--- org.scala-lang:scala-reflect:2.13.0 -> 2.13.5 (*)
+--- org.scala-lang.modules:scala-parallel-collections_2.13:0.2.0
|    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
+--- com.github.scopt:scopt_2.13:4.0.1
|    \--- org.scala-lang:scala-library:2.13.4 -> 2.13.5
\--- com.google.guava:guava:25.1-jre
     +--- com.google.code.findbugs:jsr305:3.0.2
     +--- org.checkerframework:checker-qual:2.0.0
     +--- com.google.errorprone:error_prone_annotations:2.1.3
     +--- com.google.j2objc:j2objc-annotations:1.1
     \--- org.codehaus.mojo:animal-sniffer-annotations:1.14

(*) - dependencies omitted (listed previously)

A web-based, searchable dependency report is available by adding the --scan option.

If we add the Coursier dependency, then we get:

------------------------------------------------------------
Root project 'flix'
------------------------------------------------------------

compileClasspath - Compile classpath for source set 'main'.
+--- org.scala-lang:scala-library:2.13.5 -> 2.13.10
+--- org.scala-lang:scala-reflect:2.13.5
|    \--- org.scala-lang:scala-library:2.13.5 -> 2.13.10
+--- org.java-websocket:Java-WebSocket:1.3.9
+--- org.jline:jline:3.5.1
+--- org.json4s:json4s-native_2.13:3.5.5
|    +--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
|    \--- org.json4s:json4s-core_2.13:3.5.5
|         +--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
|         +--- org.json4s:json4s-ast_2.13:3.5.5
|         |    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
|         +--- org.json4s:json4s-scalap_2.13:3.5.5
|         |    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
|         +--- com.thoughtworks.paranamer:paranamer:2.8
|         \--- org.scala-lang.modules:scala-xml_2.13:1.2.0 -> 2.1.0
|              \--- org.scala-lang:scala-library:2.13.8 -> 2.13.10
+--- org.ow2.asm:asm:9.2
+--- org.parboiled:parboiled_2.13:2.2.1
|    +--- org.scala-lang:scala-library:2.13.3 -> 2.13.10
|    \--- com.chuusai:shapeless_2.13:2.3.3
|         \--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
+--- org.tomlj:tomlj:1.1.0
+--- org.scalactic:scalactic_2.13:3.0.8
|    +--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
|    \--- org.scala-lang:scala-reflect:2.13.0 -> 2.13.5 (*)
+--- org.scala-lang.modules:scala-parallel-collections_2.13:0.2.0
|    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.10
+--- com.github.scopt:scopt_2.13:4.0.1
|    \--- org.scala-lang:scala-library:2.13.4 -> 2.13.10
+--- com.google.guava:guava:25.1-jre
|    +--- com.google.code.findbugs:jsr305:3.0.2
|    +--- org.checkerframework:checker-qual:2.0.0
|    +--- com.google.errorprone:error_prone_annotations:2.1.3
|    +--- com.google.j2objc:j2objc-annotations:1.1
|    \--- org.codehaus.mojo:animal-sniffer-annotations:1.14
\--- io.get-coursier:coursier_2.13:2.1.0-RC4
     +--- com.github.plokhotnyuk.jsoniter-scala:jsoniter-scala-core_2.13:2.13.5
     |    \--- org.scala-lang:scala-library:2.13.8 -> 2.13.10
     +--- org.scala-lang:scala-library:2.13.6 -> 2.13.10
     +--- io.get-coursier:coursier-core_2.13:2.1.0-RC4
     |    +--- io.github.alexarchambault:concurrent-reference-hash-map:1.1.0
     |    +--- org.scala-lang.modules:scala-xml_2.13:2.1.0 (*)
     |    +--- org.scala-lang:scala-library:2.13.6 -> 2.13.10
     |    \--- io.get-coursier:coursier-util_2.13:2.1.0-RC4
     |         +--- org.scala-lang.modules:scala-collection-compat_2.13:2.9.0
     |         |    \--- org.scala-lang:scala-library:2.13.10
     |         \--- org.scala-lang:scala-library:2.13.6 -> 2.13.10
     +--- io.get-coursier:coursier-cache_2.13:2.1.0-RC4
     |    +--- io.get-coursier.jniutils:windows-jni-utils:0.3.3
     |    +--- org.codehaus.plexus:plexus-archiver:4.6.0
     |    |    +--- javax.inject:javax.inject:1
     |    |    +--- org.codehaus.plexus:plexus-utils:3.5.0
     |    |    +--- org.codehaus.plexus:plexus-io:3.4.0
     |    |    |    +--- javax.inject:javax.inject:1
     |    |    |    +--- org.codehaus.plexus:plexus-utils:3.4.2 -> 3.5.0
     |    |    |    \--- commons-io:commons-io:2.11.0
     |    |    +--- commons-io:commons-io:2.11.0
     |    |    +--- org.apache.commons:commons-compress:1.21
     |    |    +--- org.slf4j:slf4j-api:1.7.36
     |    |    \--- org.iq80.snappy:snappy:0.4
     |    +--- org.codehaus.plexus:plexus-container-default:2.1.1
     |    |    +--- org.codehaus.plexus:plexus-utils:3.1.1 -> 3.5.0
     |    |    +--- org.codehaus.plexus:plexus-classworlds:2.6.0
     |    |    \--- org.apache.xbean:xbean-reflect:3.7
     |    +--- org.virtuslab.scala-cli:config_2.13:0.1.18
     |    |    +--- com.github.plokhotnyuk.jsoniter-scala:jsoniter-scala-core_2.13:2.13.5 (*)
     |    |    \--- org.scala-lang:scala-library:2.13.10
     |    +--- io.github.alexarchambault.windows-ansi:windows-ansi:0.0.4
     |    |    \--- org.fusesource.jansi:jansi:1.18
     |    +--- org.scala-lang:scala-library:2.13.6 -> 2.13.10
     |    \--- io.get-coursier:coursier-util_2.13:2.1.0-RC4 (*)
     \--- io.get-coursier:coursier-proxy-setup:2.1.0-RC4

(*) - dependencies omitted (listed previously)

You can see that:

  1. Coursier is dragging in a lot of additional dependencies (although almost certainly fewer than if we used Maven directly, so it's probably a net win).
  2. One of them is the 2.13.10 Scala library
  3. This causes our Scala library dependency to be upgraded to 2.13.10 (which in turn causes the matching compiler to be used):
    • You can see this with the org.scala-lang:scala-library:2.13.5 -> 2.13.10 line

The reason for this is that Gradle is apparently allowed to "optimistically upgrade" simple version numbers.

The solution is to add !! to the version:

    implementation 'org.scala-lang:scala-library:2.13.5!!'
    implementation 'org.scala-lang:scala-reflect:2.13.5!!'

Which gives the following dependency tree (note the {strictly 2.13.5}):

------------------------------------------------------------
Root project 'flix'
------------------------------------------------------------

compileClasspath - Compile classpath for source set 'main'.
+--- org.scala-lang:scala-library:{strictly 2.13.5} -> 2.13.5
+--- org.scala-lang:scala-reflect:{strictly 2.13.5} -> 2.13.5
|    \--- org.scala-lang:scala-library:2.13.5
+--- org.java-websocket:Java-WebSocket:1.3.9
+--- org.jline:jline:3.5.1
+--- org.json4s:json4s-native_2.13:3.5.5
|    +--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|    \--- org.json4s:json4s-core_2.13:3.5.5
|         +--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|         +--- org.json4s:json4s-ast_2.13:3.5.5
|         |    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|         +--- org.json4s:json4s-scalap_2.13:3.5.5
|         |    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|         +--- com.thoughtworks.paranamer:paranamer:2.8
|         \--- org.scala-lang.modules:scala-xml_2.13:1.2.0 -> 2.1.0
|              \--- org.scala-lang:scala-library:2.13.8 -> 2.13.5
+--- org.ow2.asm:asm:9.2
+--- org.parboiled:parboiled_2.13:2.2.1
|    +--- org.scala-lang:scala-library:2.13.3 -> 2.13.5
|    \--- com.chuusai:shapeless_2.13:2.3.3
|         \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
+--- org.tomlj:tomlj:1.1.0
+--- org.scalactic:scalactic_2.13:3.0.8
|    +--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
|    \--- org.scala-lang:scala-reflect:2.13.0 -> 2.13.5 (*)
+--- org.scala-lang.modules:scala-parallel-collections_2.13:0.2.0
|    \--- org.scala-lang:scala-library:2.13.0 -> 2.13.5
+--- com.github.scopt:scopt_2.13:4.0.1
|    \--- org.scala-lang:scala-library:2.13.4 -> 2.13.5
+--- com.google.guava:guava:25.1-jre
|    +--- com.google.code.findbugs:jsr305:3.0.2
|    +--- org.checkerframework:checker-qual:2.0.0
|    +--- com.google.errorprone:error_prone_annotations:2.1.3
|    +--- com.google.j2objc:j2objc-annotations:1.1
|    \--- org.codehaus.mojo:animal-sniffer-annotations:1.14
\--- io.get-coursier:coursier_2.13:2.1.0-RC4
     +--- com.github.plokhotnyuk.jsoniter-scala:jsoniter-scala-core_2.13:2.13.5
     |    \--- org.scala-lang:scala-library:2.13.8 -> 2.13.5
     +--- org.scala-lang:scala-library:2.13.6 -> 2.13.5
     +--- io.get-coursier:coursier-core_2.13:2.1.0-RC4
     |    +--- io.github.alexarchambault:concurrent-reference-hash-map:1.1.0
     |    +--- org.scala-lang.modules:scala-xml_2.13:2.1.0 (*)
     |    +--- org.scala-lang:scala-library:2.13.6 -> 2.13.5
     |    \--- io.get-coursier:coursier-util_2.13:2.1.0-RC4
     |         +--- org.scala-lang.modules:scala-collection-compat_2.13:2.9.0
     |         |    \--- org.scala-lang:scala-library:2.13.10 -> 2.13.5
     |         \--- org.scala-lang:scala-library:2.13.6 -> 2.13.5
     +--- io.get-coursier:coursier-cache_2.13:2.1.0-RC4
     |    +--- io.get-coursier.jniutils:windows-jni-utils:0.3.3
     |    +--- org.codehaus.plexus:plexus-archiver:4.6.0
     |    |    +--- javax.inject:javax.inject:1
     |    |    +--- org.codehaus.plexus:plexus-utils:3.5.0
     |    |    +--- org.codehaus.plexus:plexus-io:3.4.0
     |    |    |    +--- javax.inject:javax.inject:1
     |    |    |    +--- org.codehaus.plexus:plexus-utils:3.4.2 -> 3.5.0
     |    |    |    \--- commons-io:commons-io:2.11.0
     |    |    +--- commons-io:commons-io:2.11.0
     |    |    +--- org.apache.commons:commons-compress:1.21
     |    |    +--- org.slf4j:slf4j-api:1.7.36
     |    |    \--- org.iq80.snappy:snappy:0.4
     |    +--- org.codehaus.plexus:plexus-container-default:2.1.1
     |    |    +--- org.codehaus.plexus:plexus-utils:3.1.1 -> 3.5.0
     |    |    +--- org.codehaus.plexus:plexus-classworlds:2.6.0
     |    |    \--- org.apache.xbean:xbean-reflect:3.7
     |    +--- org.virtuslab.scala-cli:config_2.13:0.1.18
     |    |    +--- com.github.plokhotnyuk.jsoniter-scala:jsoniter-scala-core_2.13:2.13.5 (*)
     |    |    \--- org.scala-lang:scala-library:2.13.10 -> 2.13.5
     |    +--- io.github.alexarchambault.windows-ansi:windows-ansi:0.0.4
     |    |    \--- org.fusesource.jansi:jansi:1.18
     |    +--- org.scala-lang:scala-library:2.13.6 -> 2.13.5
     |    \--- io.get-coursier:coursier-util_2.13:2.1.0-RC4 (*)
     \--- io.get-coursier:coursier-proxy-setup:2.1.0-RC4

(*) - dependencies omitted (listed previously)

Of course, it's possible that using Coursier with an older version of the Scala library than it's been developed against might result in problems, so this isn't entirely risk-free.

@magnus-madsen
Copy link
Member Author

... And ordinarily a patch level increase should not result in breaking changes... but it does for us :( (In Scala 2.13.6 or whatever).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants