sbt: conflicting scala binary versions between project and library dependency - scala

Disclaimer: new sbt/Scala user
So I have the following build.sbt file (sbt.version=1.1.1):
val managedLibs : Setting[_] = libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % "2.11.10" withSources(),
"org.scala-lang" % "scala-library" % "2.11.10" withSources(),
"org.scala-lang" % "scala-reflect" % "2.11.10" withSources()
)
lazy val root = (project in file("."))
.settings(
name := "foo",
organization := "bar",
scalaVersion := "2.12.4",
sourcesInBase := false,
version := "0.1",
managedLibs
)
What I want to do is to use a different compiler version to build my project and a different compiler version from within my project (i.e., as a library). Sbt does not seem to like this and I am getting the following warnings:
[warn] Binary version (2.11) for dependency org.scala-lang#scala-compiler;2.11.10
[warn] in bar#foo_2.12;0.1 differs from Scala binary version in project (2.12).
[warn] Binary version (2.11) for dependency org.scala-lang#scala-library;2.11.10
[warn] in bar#foo_2.12;0.1 differs from Scala binary version in project (2.12).
[warn] Binary version (2.11) for dependency org.scala-lang#scala-reflect;2.11.10
[warn] in bar#foo_2.12;0.1 differs from Scala binary version in project (2.12).
[warn] Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:
[warn] * org.scala-lang:scala-library:(2.12.4, 2.11.10)
My program compiles and runs without an issue using scala 2.12.4 (it looks like sbt ignored 2.11.10) but I am just curious: is it even possible to use different versions in that way ? Is this a hard restriction imposed by sbt ?
Thanks in advance for your help !

Related

SBT binary incompatible issue scala-parser-combinators

I am new to the Scala env and trying to build a test project using play with 'scalikejdbc' for SQL integration. Here is my build.sbt following the documents at http://scalikejdbc.org/documentation/playframework-support.html
name := """run"""
organization := "com.example"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.10"
libraryDependencies ++= Seq(
guice,
"org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test,
"com.h2database" % "h2" % "1.4.200", // your jdbc driver here
"org.scalikejdbc" %% "scalikejdbc" % "4.0.0",
"org.scalikejdbc" %% "scalikejdbc-config" % "4.0.0",
"org.scalikejdbc" %% "scalikejdbc-play-initializer" % "2.8.0-scalikejdbc-3.5",
"com.typesafe.play" %% "play-ws" % "2.3.1"
)
dependencyOverrides += "org.fluentlenium" % "fluentlenium-core" % "0.10.3"
// Adds additional packages into Twirl
//TwirlKeys.templateImports += "com.example.controllers._"
// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.example.binders._"
I have also aded the below on plugins.sbt
resolvers += Resolver.url("SBT Plugins", url("https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
However while trying to update the application before running i am getting the below issue
[error] (update) found version conflict(s) in library dependencies; some are suspected to be binary incompatible:
[error]
[error] * org.scala-lang.modules:scala-parser-combinators_2.13:2.1.0 (early-semver) is selected over {1.1.2}
[error] +- org.scalikejdbc:scalikejdbc-core_2.13:4.0.0 (depends on 2.1.0)
[error] +- com.typesafe.play:play_2.13:2.8.18 (depends on 1.1.2)
[error] +- com.typesafe:ssl-config-core_2.13:0.4.3 (depends on 1.1.2)
[error]
following are relevant versions :
sbt script version: 1.8.0
play version :2.8.18
Scala code runner version 3.2.1 but using as scalaVersion := "2.13.10" in sbt.
version conflict(s) in library dependencies; some are suspected to be binary incompatible
This means that you have at least two dependencies that are needing a 3rd one but they need 2 different versions which are supposed to be incompatible.
As only one can be included and used for your code, SBT is telling you: "I am going to pick one version but there are risks that this version won't work as you might have code that rely on the other version and this might be incompatible".
You have 2 options:
force a version (for scala-parser-combinators) with dependencyOverrides for instance if you know that actually there's no incompatibility, or at least on the way you use the libraries
upgrade or downgrade the libraries (scalikejdbc or play) so that all libraries depend on the same version of the conflicting one (scala-parser-combinators).
In this case, I would downgrade scalikejdbc because there's no newer play version (as of today)

log4j2 in scala on sbt complie gives Unresolved dependencies path

I'm trying to use log4j2 in scala.
Below is my build.sbt
name := "trial"
version := "0.1"
scalaVersion := "2.13.1"
libraryDependencies += "org.apache.logging.log4j" %% "log4j-api" % "2.12.1"
libraryDependencies += "org.apache.logging.log4j" %% "log4j-core" % "2.12.1"
libraryDependencies += "org.apache.logging.log4j" %% "log4j-api-scala" % "2.12.1"
How to resolve these errors:
[warn] Note: Unresolved dependencies path:
[error] sbt.librarymanagement.ResolveException: Error downloading org.apache.logging.log4j:log4j-api_2.13:2.12.1
sbt.librarymanagement.ResolveException: Error downloading org.apache.logging.log4j:log4j-api_2.13:2.12.1
not found: /Users/username/.ivy2/local/org.apache.logging.log4j/log4j-api_2.13/2.12.1/ivys/ivy.xml
Note :
There is no directory /Users/username/.ivy2/local/
but I can see there is /Users/username/.ivy2/cache/
and plugins log4j-api,core,api-scala are present in cache.
The IDE i'm using is IntelliJ IDEA.
There are multiple problems
You are using Scala 2.13 however the latest build of log4j-api-scala is for Scala 2.12.
The latest version of log4j-api-scala is 11.0 not 2.12.1
log4j-api and log4j-core are Java libraries so we should use single % instead of double%%

Resolving import conflicts in Scala SBT

I'm trying to following this tutorial, but I'm getting the same error for two days. i found some similar questions here in SO, but any of them helped me (maybe is because my lack of knowledge in scala and sbt).
Here is my build.sbt
name := "fitman"
version := "1.0"
scalaVersion := "2.11.6"
lazy val versions = new {
val finatra = "2.1.2"
val logback = "1.1.3"
}
resolvers ++= Seq(
Resolver.sonatypeRepo("releases"),
"Twitter Maven" at "https://maven.twttr.com"
)
libraryDependencies += "com.twitter.finatra" %% "finatra-http" % versions.finatra
libraryDependencies += "com.twitter.finatra" %% "finatra-slf4j" % versions.finatra
libraryDependencies += "ch.qos.logback" % "logback-classic" % versions.logback
Here is the warnings that I'm trying to understand:
SBT project import
[warn] Scala version was updated by one of library dependencies:
[warn] * org.scala-lang:scala-library:(2.11.6, 2.11.4, 2.11.0, 2.11.2) -> 2.11.7
[warn] To force scalaVersion, add the following:
[warn] ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }
[warn] Run 'evicted' to see detailed eviction warnings
[warn] Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:
[warn] * org.scala-lang:scala-library:(2.11.7, 2.11.6)
[warn] * org.scala-lang:scala-reflect:(2.11.7, 2.11.6)
[warn] * org.scala-lang.modules:scala-parser-combinators_2.11:(1.0.4, 1.0.3)
[warn] * org.scala-lang.modules:scala-xml_2.11:(1.0.5, 1.0.3)
One of the libraries you are using requires Scala 2.11.7, so SBT is overriding your scalaVersion setting with it. Update the version of Scala in your build file:
scalaVersion := "2.11.7"

Can not resolve dependencies after upgrading to version 2.12

Because I had some dependency issues, I decided to upgrade the Scala installation on my computer to version 2.12.0-M3. I also ran sbt -v, after which many packages were downloaded.
However, when I try to refresh the following build.sbt file
name := """ScalaWeb"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.0-M3"
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
specs2 % Test,
"org.sorm-framework" % "sorm" % "0.3.18"
)
resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator
scalacOptions += "-Ylog-classpath"
I get the following errors:
Error:Unresolved dependencies:
com.typesafe.play#twirl-api_2.12.0-M3;1.1.1: not found
com.typesafe.play#play-server_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-netty-server_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-jdbc_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-cache_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-ws_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-test_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-specs2_2.12.0-M3;2.4.6: not found
com.typesafe.play#play-omnidoc_2.12.0-M3;2.4.6: not found
Version 2-12.0-M3 appeared in October 2015. It seems doubtful that all these packages are still incompatible.
How can I solve this issue?
PS
I was unable to use scala version 2.11.7 because I have the dependency
"org.sorm-framework" % "sorm" % "0.3.18"
Which, because of its dependencies, produces this issues:
[error] org.scala-lang.modules:scala-xml _2.11, _2.12.0-M3
[error] org.scala-lang.modules:scala-parser-combinators _2.11, _2.12.0-M3
It seems the SORMS author is defining Scala library dependencies wrongly. As a result you have horrible transitive Scala dependencies for versions like [2.10,2.12), so it will pick whatever latest Scala version was published, including in your case 2.12.0-M3 apparently.
Looking at the POM of 0.3.18 and the POM of 0.3.19, it seems that the later version uses (still wrong!!) [2.10,2.11.999).
So I think you can solve your issue using these settings:
scalaVersion := "2.11.7"
libraryDependencies += "org.sorm-framework" % "sorm" % "0.3.19"
If not, you will have to exclude the problematic transitive dependencies from SORM.
Update: The bug report also hints that the dependency you need to exclude is actually embrace. For example, using the sbt-dependency-graph plugin, running sbt dependency-dot and inspecting the result I find:
"com.github.nikita-volkov:embrace:0.1.4" -> "org.scala-lang:scala-compiler:2.12.0-M3"
which seems to be the origin of the evil.
Instead of excluding, I am now forcing a version of Scala:
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
"org.sorm-framework" % "sorm" % "0.3.19",
"org.scala-lang" % "scala-compiler" % scalaVersion.value force() // !!
)
This worked for me.

Adding an SBT plugin which does not specify an SBT version in its URL

Specs2 does not define the SBT version in its URL:
https://oss.sonatype.org/content/repositories/releases/org/specs2/specs2_2.9.2/1.12.3/
This is causing problems for SBT when trying to resolve it...
[warn] ==== sonatype-snapshots: tried
[warn] https://oss.sonatype.org/content/repositories/snapshots/org/specs2/specs2_2.9.2_0.12/1.12.3/specs2-1.12.3.pom
[warn] ==== sonatype-releases: tried
[warn] https://oss.sonatype.org/content/repositories/releases/org/specs2/specs2_2.9.2_0.12/1.12.3/specs2-1.12.3.pom
How do I get SBT to resolve the correct URL?
specs2 is not a sbt plugin it's a Scala library for writing executable software specifications.
There are two levels of sbt projects. Your own projects (for now call them "apps") and the build project definition itself (call it "the build").
library dependencies
When apps use other libraries during compilation or test, they are called library dependencies (or "deps" for short). These deps are declared in build.sbt (or *.sbt or project/*.scala) as follows:
libraryDependencies += "org.specs2" %% "specs2" % "2.2" % "test"
By saying %%, artifacts published using sbt automatically appends Scala binary version postfix such as _2.10 on Maven. This is due to the fact that (unlike Java) not all Scala releases are binary compatible with each other. Scala 2.9.1 and 2.9.2 are not compatible, so they both have distinct postfix _2.9.1 and _2.9.2, but Scala 2.10.x are all compatible among the series so they are given _2.10.
Unfortunately, however, different versions of Specs2 are required for Scala versions, you might have to do something more like:
libraryDependencies <+= scalaVersion({
case "2.9.2" => "org.specs2" %% "specs2" % "1.12.3" % "test"
case x if x startsWith "2.10" => "org.specs2" %% "specs2" % "2.2" % "test"
})
For more details check out Getting Started guide.
sbt plugins
There are special type of libraries that the build can depend on to extend its abilities, and they are sbt plugins. These are declared in project/plugins.sbt (or project/*.sbt) as follows:
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.2.5")
Since sbt plugins are dependent on sbt version and the Scala version that the build uses, both of those information are encoded somehow into the published artifact path. On Ivy, they are expressed as folder names but on Maven they are expressed as postfix:
http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.eed3si9n/sbt-buildinfo/scala_2.9.2/sbt_0.12/0.2.5/
https://oss.sonatype.org/content/repositories/public/org/scalaxb/sbt-scalaxb_2.10_0.13/1.1.2/