What version manager should I use to manage multiple Scala versions? - scala

I come from a background in Ruby, and I use RVM to manage multiple Ruby and gemsets. I have googled around, and I found these two SVM and PVM, not sure what should I use?
Anyone can recommend what should I use to manage multiple scala?
PVM Play Version Manager https://github.com/kaiinkinen/pvm
SVM Scala Version Manager https://github.com/yuroyoro/svm

You don't need a version manager. You need a build tool.
Scala projects work differently than Ruby projects. If you use SBT as a build tool, you specify the Scala version in your build file:
//build.sbt
scalaVersion := "2.11.0" // or some other version
SBT then proceeds to download the specified Scala version for you if it hasn't been downloaded before, and builds and runs your project with this version. If you want, you can even specify which version of SBT you want, and it'll arrange everything for you as well.
This is because Scala, contrary to Ruby, is a compiled language - it must be compiled/built before running. Ruby projects don't have a build process, and can be (attempted to) run on any Ruby version. Scala projects might not build on incompatible versions, let alone run, so you need to specify which Scala version your project is supposed to be built against.
There's also no such thing as gemsets for Scala. For Ruby, gems were originally system-wide libraries and executables, shared by all Ruby scripts on the system. Therefore, gems override each other and you need to maintain gemsets with the specific versions you require for each project. In Scala, a dependency is just a library specifically for your project. They don't override each other, and you just specify which version you need in your build file. SBT then automatically downloads it for you when you build.
This just works:
// myproject1/build.sbt
scalaVersion := "2.10.2"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.2.0"
// myproject2/build.sbt
scalaVersion := "2.11.0"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.3"

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.

Where can I download the library .jar-files for Akka 2.5.6?

I would like to update from Akka 2.4.10 to the current Akka 2.5.6. For any reasons I can't find a Download-Link on https://akka.io. On Github I found the source files but what I'm looking for are the compiled .class-files bundled in .jar-files, so that I can directly integrate them as library in IntelliJ IDEA. (With version 2.4.10 there was a file "akka_2.11-2.4.10.zip" available for download at https://akka.io, which had these .jar-files in the "lib"-subdirectory.)
You can get the JARs directly from Maven Central, but you should really consider using a build management tool like SBT. You don't even have to install anything, you can just use the one bundled with IntelliJ. Simply create a file named build.sbt in the root of your project with these contents (taken straight from the Akka documentation):
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.5.6",
"com.typesafe.akka" %% "akka-testkit" % "2.5.6" % Test
)
Open it in IntelliJ and a bar should appear on top of your editor window, prompting you to import the file. This will take care of downloading the appropriate JARs (along with any dependencies).
You should update akka dependency version and your build system would automatically fetch the necessary jar files compatible with the scala version. From here you can find all akka libraries published to maven repository.

How to add ScalaScriptEngine library in IntelliJ Idea

I have created a libs folder and placed scalascriptengine-1.3.9-2.11.0.jar in there. After that, I right-clicked on the .jar and selected Add Library.
Then, I created Test.scala:
import java.io.File
import com.googlecode.scalascriptengine.ScalaScriptEngine
object Test {
def main(args: Array[String]): Unit = {
val sourceDir = new File("examples/folder")
val sse = ScalaScriptEngine.onChangeRefresh(sourceDir)
}
}
It correctly recognized ScalaScriptEngine, or at least it did not give any warnings or errors. But it did not compile.
According to the library page I edited my build.sbt:
name := "ScalaScriptEngineTest"
version := "1.0"
libraryDependencies += "com.googlecode.scalascriptengine" %% "scalascriptengine" % "1.3.10"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.11.1"
But upon refreshing, I get this: http://pastebin.com/GdirttUJ
What am I missing? I am learning scala and it is the first time I am trying to add a library to IntelliJ Idea...
Short answer:
Change the two dependency entries in your build.sbt as follows:
libraryDependencies +=
"com.googlecode.scalascriptengine" % "scalascriptengine" % "1.3.9-2.10.3"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.4"
Notice I didn't just change the versions -- I replaced your %% with a single %.
This results in you using a slightly older version of ScalaScriptEngine, and I don't know if that will cause any problems for you.
If you're using sbt build dependencies you don't need to be manually placing jars anywhere.
Explanation:
From your log I see that sbt is looking for the ScalaScriptEngine for Scala 2.10. In fact, it's pretty clear that you're running Scala 2.10.4, even though your sbt file expresses a dependency on the 2.11 compiler, which in fact is consistent with the instructions for using ScalaScriptEngine.
On line 23 of the log you can see exactly where it's looking. If you point your browser part way down that path you'll see that there is a version for Scala 2.11 and another directory, scalascriptengine, without a version qualifier. If you dive down the latter, you'll see it's where they keep all the old versions. There isn't a ScalaScriptEngine 1.3.10 (the one you asked for) compiled for Scala 2.10, so your options seem to be to upgrade to Scala 2.11 (which I don't think currently works if you want to use IntelliJ Idea's tight integration with sbt), or you can use ScalaScriptEngine 1.3.9.
You have basically the same problem with your Scala compiler dependency -- it needs the be the Scala version you're using.
I've confirmed the above solution with Scala 2.10.4. I'm playing it a little fast and loose because there isn't a pre compiled version for 2.10.4, and I gambled that the 2.10.3 build will probably work.
Alternatives:
There may be a cleaner way to solve this, but the way the repository is organized makes me doubt it.
You could build the version of your choice with the compiler of your choice, or persuade the ScalaScriptEngine community to do it for you and put it in The Central Repository, but my guess is that 1.3.10 won't build with anything lower than Scala 2.11.
Finally, if you do want to download jars by hand, you may want to read the "Unmanaged dependencies" section of the sbt documentation. Actually, if you're going to use sbt, just read the whole thing a few times.

How to add native library dependencies to sbt project?

I want to add a Java library (e.g. Apache PDFBox) to an sbt project.
This is the Ivy dependency:
dependency org="org.apache.pdfbox" name="pdfbox" rev="1.8.2"
I first tried to do the following:
resolvers += "Sonatype releases" at "http://oss.sonatype.org/content/repositories/releases/"
libraryDependencies += "org.apache.pdfbox" %% "pdfbox" % "1.8.2"
But it gives me errors of the type
[warn] ==== public: tried [warn]
http://repo1.maven.org/maven2/org/apache/pdfbox/pdfbox_2.10/1.8.2/pdfbox_2.10-1.8.2.pom
So I understand that with this syntax I can just manage Scala dependencies. I am sure that there is a way to manage Java dependencies, but how?
I tried to search in Google for "sbt add java dependencies" but did not find (recognize) a relevant result.
You should replace the %% (double percent) with single one.
libraryDependencies += "org.apache.pdfbox" % "pdfbox" % "1.8.2"
The double-percent is a convenience operator, and causes adding the _+scalaVersion postfix inside the path, which is _2.10 in your case. Single percent should fix the problem.
Short answer:
Use
libraryDependencies += "org.apache.pdfbox" % "pdfbox" % "1.8.2"
For java libraries, and
libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.8"
For Scala libraries, where the difference is the double % for the scala library.
Long answer:
Scala is not backward compatible across major version, so a library compiled for scala 2.12.x cannot be used by a project written in scala 2.13.x.
So when writing a scala library, you will need to compile and publish it one time per scala major version you would like to support. When using a library in a project, you would then have to pick the version compiled for the same Scala major version as your are using. Doing this manually would be cumbersome, so SBT has built in support for it.
When publishing a library, you can add the crossScalaVersions key to SBT like
crossScalaVersions := Seq( "2.10.6", "2.11.11", "2.12.3" )
And then publish with sbt +publish. This will make SBT build and publish a version of the library for both scala 2.10.6, 2.11.11 and 2.12.3. Note that the minor number is in-relevant, when it comes to compatibility for libraries. The published libraries, will have the name suffixed with _2.10, _2.11 and _2.12 to show what scala version it is for. An alternative to using the SBT build in support for this, is to use the experimental plugin sbt-projectmatrix as this gives a lot more options, and often faster builds.
When using a library sbt can also help your use the one compiled for the correct scala version, and thats where %% comes into play. When specifying a library without the _ suffix in the name, but instead use %%, then sbt will fill in suffix matching the Scala major version your use, and thereby fetch the correct version of the library.

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"