How to compile scala library to latest scala version - scala

I want to use this library https://github.com/prismicio/scala-kit.
My project's scala version is 2.13.1. When I add this library as dependency:
val prismic = "io.prismic" % "scala-kit_2.11" % "1.3.1"
I get NoClassDefinitionFound error at runtime. I guess it's due to version conflict. So how do I publish this library so it works for scala version 2.13.1?

Scala has no binary compatibility across major versions (i.e. 2.11.1 and 2.13.1). Either downgrade to 2.11.1 (or 2.12.2 if you switch to the latest version of the library) scalaVersion := "2.11.1" or compile the library to 2.13.1 yourself.

What you should use is
val prismic = "io.prismic" %% "scala-kit" % "1.3.1"
which adds the correct suffix automatically, and you can't forget to change it when changing the Scala version. But if you look at https://mvnrepository.com/artifact/io.prismic/scala-kit, you'll see there is no version for 2.13 at all, but there are versions for 2.12. So if you want to change your Scala version, use 2.12.10 (the latest 2.12).

Related

How to integrate sbt-protoc and scalapb with sbt cross build?

I have a library that needs two different versions of "com.thesamet.scalapb" %% "compilerplugin" depending on the Scala version.
In my project/scalapb.sbt I have this code:
def scalapbVersion(version:String): String =
if(version == "2.11") {
println(s">>>>>>>> Using 0.9.7 to fix 2.11 compat. ${version}")
"0.9.7"
} else {
println(s">>>>>>>> Using last version. ${version}")
"0.10.2"
}
libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % scalapbVersion(scalaBinaryVersion.value)
Executing sbt clean "++2.11.12 compile I get >>>>>>>> Using lastest version. 2.12 but in the logs, also, I can see that the cross-build plugin changes the version to Scala 2.11 after the previous message:
[info] Setting Scala version to 2.11.12 on 13 projects.
[info] Excluded 1 projects, run ++ 2.11.12 -v for more details.
So I suppose that the order is:
sbt load plugins configuration with the default Scala version.
cross-build changes the scala version
How to integrate sbt-protoc with sbt cross-build?
sbt files in the project directory are evaluated before a specific scala version is picked up for cross building. This is why passing ++2.11.12 has no effect on scalaBinaryVersion in the context of project/scalapb.sbt.
Using different versions of compilerplugin in a single build is not officially supported at this point, but there are a few workarounds that you can try:
Download scalapbc for the version of ScalaPB you would like to use. Write a shell script that generates sources using ScalaPBC. Check in the generated sources into your code repository. Manually add scalapb-runtime into your libraryDependencies in build.sbt:
libraryDependencies += "com.thesamet.scalapb" %% "scalapb-runtime" % (if (scalaVersion.value == "2.12.10") "0.10.8" else "0.9.7")
Use 0.9.7 for all scala versions.
If it's reasonable for your situation, consider dropping Scala 2.11 support as Scala 2.11 reached end-of-life a few years ago.

Scala/Spark version compatibility

I am building my first spark application.
http://spark.apache.org/downloads.html tells me that Spark 2.x is built against Scala 2.11.
On the Scala site https://www.scala-lang.org/download/all.html I am seeing the versions from 2.11.0 - 2.11.11
So here is my question: what exactly does the 2.11 on the Spark site mean. Is it any Scala version in the 2.11.0 - 2.11.11 range?
Another question: Can I build my Spark apps using the latest Scala 2.12.2? I assume that Scala is backward compatible, so Spark libraries built with Scala say 2.11.x can be used/called in Scala 2.12.1 applications. Am I correct?
Scala is not backwards compatible, as you assume. You must use scala 2.11 with spark unless you rebuild spark under scala 2.12 (which is an option if you want to use the latest Scala version, but requires more work to get everything working).
When considering compatibility, you need to consider both source compatibility and binary compatibility. Scala does tend to be source backwards compatible, so you can rebuild your jar under a newer version, but it is not binary backward compatible, so you can't use a jar built with an old version with code from a new version.
This is just major versions, so scala 2.10, 2.11, 2.12 etc. are all major versions and are not binary compatible (even if they are source compatible). Within a major version though compatibility is maintained, so Scala 2.11 is compatible with all versions 2.11.0 - 2.11.11 (plus any future 2.11 revisions will also be compatible)
It is for this reason that you will see most Scala libraries have separate releases for each major Scala version. You have to make sure that any library you use provides a jar for the version you are using, and that you use that jar and not one for a different version. If you use SBT %% will handle selecting the correct version for you but with maven you need to make sure to use the correct artifact name. The versions are typically prepended with _2.10, _2.11, and _2.12 referring to the scala version the jar is built for.
For anyone who wants to get jump started, this is the versioning pair I've used.
scalaVersion := "2.11.12"
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % "2.3.2",
"org.apache.spark" %% "spark-sql" % "2.3.2"
)
I used these versions of Scala and Spark and it worked OK for my need:
scalaVersion := "2.12.8"
libraryDependencies += "org.apache.spark" %% "spark-hive" % "2.4.0"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.0"
Some libraries need 2.11 version of Scala, and in this case one should use the versions mentioned by #the775.
NOTE : This is an old answer, it is no longer available now, as newer versions of Scala and Spark exist.

Using a 2.10-only SBT plugin in a project that's cross-built against 2.9

Suppose I've got a SBT 0.13 project that's cross-built against Scala 2.9.3 and 2.10.4. I want to use an SBT plugin (sbt-coveralls) for the 2.10 build only, because the plugin isn't available for 2.9.
I know that I could use CrossVersion to conditionally add the plugin settings to the 2.10 build, but that doesn't help with the fact that addSbtPlugin isn't going to find anything for the 2.9 build, etc.
I'm assuming this is impossible (short of some really messy ad-hoc shell scripting) but I'm not an SBT wizard, and it would be nice to be surprised by the mysteries of SBT in a good way for once.
Found this horrible hack of a workaround, but it does seem to work:
resolvers <++= scalaVersion {
case v if v startsWith( "2.12" ) =>
Seq.empty
case _ =>
addSbtPlugin( "org.scoverage" % "sbt-scoverage" % "1.0.4" )
addSbtPlugin( "org.scoverage" % "sbt-coveralls" % "1.0.0" )
Seq( Classpaths.sbtPluginReleases )
}
I might misunderstand the question, but I think you may be confused with sbt's vs a project's versions of Scala.
You cannot use a plugin that's incompatible with sbt - the runtime. If a plugin doesn't support the version of Scala sbt uses under the covers the plugin is deemed incompatible and hence sbt will refuse starting up. sbt 0.13.5 uses 2.10.4 so the plugins can only use Scala API 2.10.4. That's why addSbtPlugin offers no %%.
For projects, it's different. Here you could use whatever version you want regardless of the version sbt uses and hence the plugins. Once you've addSbtPlugin'ed a plugin, the plugin's available in a project, and to enable it, add the settings to projects.

Does scala-pickling work with Scala 2.11?

Is there any way to use scala-pickling with scala 2.11 yet?
I've tried the only scala-pickling_2.11 artifact at the sonatype repository but it doesn't seem to work. I get the message:
Error:(26, 43) can't expand macros compiled by previous versions of Scala
I think you can't use scala-pickling with higher versions of scala but there is boopickle which might help you out.
You can easily import it into an sbt project with
libraryDependencies += "io.suzaku" %% "boopickle" % "1.3.2"
and this works with scala version 2.13.3 at least.

Cross building in sbt with 2.10.0

I am cross building a scala project with sbt 12.1.
crossScalaVersions := Seq("2.9.2", "2.10.0")
However, it can't find the dependencies because they are named _2.10 not _2.10.0. It seems like it's regular to name your library 2.10 instead of 2.10.0 with the exception of scala-language and scala-compiler. For example, scalaz is not found at http://repo1.maven.org/maven2/org/scalaz/scalaz-core_2.10.0/6.0.4/scalaz-core_2.10.0-6.0.4.pom but at http://repo1.maven.org/maven2/org/scalaz/scalaz-core_2.10/6.0.4/scalaz-core_2.10-6.0.4.pom.
Is there an easy way to handle this without writing custom rules for all of my dependencies?
The actual build.sbt is available online.
Since 2.10.x releases are binary compatible between each other, libraries need to be built only with one version of scala library - and they can (and must) drop the .0 part (if you publish with sbt, it is done automatically). When the maintainer of a library releases a library with _2.10.0 tag, it's a mistake and you should consider filing a bug.
By the way, I looked on your build.sbt - running +compile on it works for me (sbt 0.12.1). Do you experience some errors?
To get the Scala version incorporated into the artifact name in the Scala way, you specify the dependency with the %% operator:
libraryDependencies += "io.backchat.jerkson" %% "jerkson" % "0.7.0"
When the exact match is not available, you can specify the Scala version explicitly (but remember compatibility only exists across patch releases of a given major/minor release of Scala):
libraryDependencies += "io.backchat.jerkson" % "jerkson_2.9.2" % "0.7.0"