Scala plugin erroneous compiler version inference with transitive dependencies


(Giovanni Botta) #1

Sometimes the Scala plugin doesn’t infer the compiler version correctly. According to the docs:

“If a scala-library Jar is found on classpath, and the project has at least one repository declared, a corresponding scala-compiler repository dependency will be added to scalaClasspath.”

However, I have a project with the following dependencies:

compile ‘org.scala-lang:scala-library:2.10.1’ compile ‘com.wordnik:swagger-codegen_2.10:2.0.11’

and if I call gradle run (using the application plugin), the generated classpath will have version 2.10.0 of the compiler (I believe that’s because of a transitive dependency). This can be fixed by explicitly adding version 2.10.1 to the dependencies, in which case the correct version is added to the cp.

I noticed the problem because one of the libraries was throwing the following:

java.lang.NoSuchMethodError: scala.reflect.internal.TreeInfo.firstArgument

which can only be fixed by using the compiler library version 2.10.1 (or above).

I assume Gradle picks up the transitive dependency (v 2.10.1) without a warning. I believe it would be nice to have a warning if this happens.


(Peter Niederwieser) #2

The problem isn’t related to Gradle’s inferral of the Scala compiler to be used. (Gradle will never add a ‘scala-compiler’ Jar to the compile or runtime class path.) You simply have inconsistent versions of ‘scala-library’ and ‘scala-compiler’ on your compile, and hence also runtime, class path.

With the current state-of-the-art regarding dependency metadata, such inconsistencies have to be detected and resolved by the user. To help with this, you can add ‘configurations.all { resolutionStrategy.failOnVersionConflict() }’, in which case Gradle would have forced you to choose between ‘scala-library:2.10.0’ and ‘scala-library:2.10.1’. This would have hopefully lead you to the inconsistent ‘scala-compiler’ version as well.

Another solution is to write a dependency resolve rule (see ‘ResolutionStrategy#eachDependency’) that checks that the versions of ‘scala-library’, ‘scala-reflect’, and ‘scala-compiler’ are consistent.


(Giovanni Botta) #3

Peter thanks for the reply, this is much clearer now. I like the idea of failing on version conflict. How do I choose one of the two libraries though? I’m now getting this:

Could not resolve all dependencies for configuration ‘:clientgen:codegen:compile’.

A conflict was found between the following modules:

  • org.scala-lang:scala-library:2.10.1

  • org.scala-lang:scala-library:2.10.0

how do I explicitly choose 2.10.1?

Thanks!


(Peter Niederwieser) #4

ResolutionStrategy in the Gradle Build Language Reference shows how to force a version or implement a resolve rule that chooses consistent versions for ‘org.scala-lang’ modules. (Remember that you also have to choose the correct ‘scala-compiler’, and possibly ‘scala-reflect’, version, even if there is no immediate conflict there.)


(Giovanni Botta) #5

Nevermind, I figured it out. Thanks!