How do i change the Scala version that sbt works with? - scala

Firing up the SBT console it reads :
[info] Building project AYLIEN 1.0 against Scala 2.8.1
[info] using MyProject with sbt 0.7.4 and Scala 2.7.7
How can I make it use MyProject with sbt 0.7.4 and Scala 2.8.1 ? Please pay attenetion that I'm not asking about the Scala version that is used to build my project (it is the 2.8.1 as you can see), but I rather want to make sbt use MyProject with Scala 2.8.1. Apparently sbt uses it's own scala version to work with project definition (MyProject here) which is different than one it uses to actually build the project! or perhaps I'm missing something ... ?

I can see your concern about SBT still using 2.7.7 internally, but it doesn't really matter since SBT downloads that version on its own. You do not have to install 2.7.7 or anything, just forget about it and pretend your environment is pure Scala 2.8.
The configuration file that holds the SBT version setting is: project/build.properties. The content looks like this:
project.organization=com.ab.web
project.name=cool_proj
sbt.version=0.7.4
project.version=1.0
build.scala.versions=2.8.0
project.initialize=false
When you want to move up to the next SBT version, just change 0.7.4 to that version and SBT will update itself. Eventually SBT will use some other Scala version internally, but this will not matter to the user.

SBT 0.7.* won't work with Scala 2.8.* for your project definition.
Mark Harrah is currently working on the next version of SBT which will work with 2.8.*. This means that you can't use any Scala features or functionality that was added after Scala 2.7.7 in your project definition or plugins. Your project itself is free to use 2.8.*.

Related

How to install scala 2.12

There are multiple binary incompatible scala 2 versions, however the document says the installation is either via IDE or SBT.
DOWNLOAD SCALA 2
Then, install Scala:...either by installing an IDE such as IntelliJ, or sbt, Scala's build tool.
Spark 3 needs Scala 2.12.
Spark 3.1.2 uses Scala 2.12. You will need to use a compatible Scala version (2.12.x).
Then how can we make sure the scala version is 2.12 if we install sbt?
Or the documentation is not accurate and it should be "to use specific version of scala, need to download specific scala version on your own"?
Updates
As per the answer by mario-galic, in ONE-CLICK INSTALL FOR SCALA it is said:
Installing Scala has always been a task more challenging than necessary, with the potential to drive away beginners. Should I install Scala itself? sbt? Some other build tools? What about a better REPL like Ammonite? Oh and before all that I need to install Java?
To solve this problem, the Scala Center contracted Alexandre Archambault in January 2020 to add a one-click install of Scala through coursier. For example, on Linux, all we now need is:
$ curl -Lo cs https://git.io/coursier-cli-linux && chmod +x cs && ./cs setup
The Scala version is specified in the build.sbt file so SBT will download the appropriate version of Scala as necessary.
I personally use SDKMAN! to install Java and then SBT.
The key concept to understand is the difference between system-wide installation and project-specific version. System-wide installation ends up somewhere on the PATH like
/usr/local/bin/scala
and can be installed in various ways, personally I recommend coursier one-click install for Scala
curl -Lo cs https://git.io/coursier-cli-linux && chmod +x cs && ./cs setup
Project-specific version is specified by scalaVersion sbt settings which downloads Scala to coursier cache location. To see the Scala version and location used by the particular project try show scalaInstance which
inspect scalaInstance
[info] Task: sbt.internal.inc.ScalaInstance
[info] Description:
[info] Defines the Scala instance to use for compilation, running, and testing.
Scala should be binary compatible within minor version so Spark 3 or any other software built against any Scala 2.12.x version should work with any other Scala 2.12.x version where we have major.minor.patch. Note binary compatibility is not guaranteed for internal compiler APIs, so for example when publishing compiler plugins the best practice is to publish it against full specific Scala version. For example notice how kind-projector compiler plugin is published against full Scala version 2.13.6
https://repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.6/
whilst scala-cats application-level library is published against any Scala 2.13.x version
https://repo1.maven.org/maven2/org/typelevel/cats-core_2.13/
Similarly spark is published against any Scala 2.12.x version
https://repo1.maven.org/maven2/org/apache/spark/spark-core_2.12/
Regarding system-wide installation one trick I do for quick switching of versions is to put scala-runners on the PATH and then different versions can be launched via --scala-version argument
scala --scala-version 2.12.14
Using coursier or scala-runners you can even switch JDK quickly via -C--jvm for example
scala --scala-version 2.12.14 -C--jvm=11
For a project, there should be no need to download manually a specific version of Scala. sbt either directly or indirectly via an IDE will download all the dependencies behind the scenes for you, so the only thing to specify is sbt setting scalaVersion.
Using Python as analogy to Scala, and Pipenv as anology to sbt, then python_version in Pipfile is similar to scalaVersion in build.sbt. After executing pipenv shell and pipenv install you end up with project-specific shell environment with project specific Python version and dependencies. sbt similarly downloads project specific Scala version and dependencies based of build.sbt although it has no need for lock files or for modifying your shell environment.

Scala 2.13, SBT: sbt compile uses wrong compiler version

I am porting a small legacy library from scala 2.12 to scala 2.13. sbt version is 1.3.3. The project is flat and relatively simple. scalaVersion declared in the project is 2.13.1.
I am executing clean and compile tasks, and then publish to both local ivy and to the artifactory.
The process seemingly goes fine and creates the artifact with the _2.13 suffix. When this binary gets executed against scala 2.13 runtime, it fails with MethodNotFound exception. Further introspection shows that the artifact was compiled for 2.12 but not for 2.13.
Does anybody have an idea why a different compiler version was used by sbt, and how to fix this problem?
Just had similar issue, sbt was compiling my project to the wrong Scala version, found this question without answers in google.
So, my problem was actually very simple. Turns out you need to start sbt in a project root directory (where build.sbt is located). I was running it from a directory where all my .scala files were located, so it haven't parsed build.sbt and compiled project using default Scala version (2.12 in my case).

Do you need to install Scala separately if you use sbt?

Reason I ask, is because it's possible to specify a Scala version in the build.sbt file (using scalaVersion setting), and once you do that, sbt will automatically download that Scala version to use with the project.
I also seem to remember that despite having Scala 2.11.1 on my system, sbt would compile and run with Scala 2.10 if no version was specified.
So the question is, do I need to install Scala separately if I got sbt installed?
No you don't need it. sbt will download Scala for you.
If you install sbt-extras (basically just a script) you don't even need to download sbt: it will automatically download the sbt launcher you need. Very handy since you just need to specify sbt.version in your build.properties and you're good to go.
Edit: removed my comment about not being able to do sbt console in an empty directory, since both sbt and sbt-extras support it now.

Sbt plugin binary incompatibility

I am using the sbtantlr plugin and adapting it to use antlr v3.5. It used to work fine with scala 2.9.2.
Today I upgraded my scala to 2.10.0.
And I compiled the plugin in 2.10.0 and put the plugin 'sbtantlr.jar' in the 'lib' directory of my main scala project.
SBT stopped working with this error message:
Binary incompatibility in plugins detected.
I revert the compiler version to 2.9.2 and it works fine.
Is it because SBT (the official binary release) was built with 2.9? Where can I find the information?
Yes, sbt 0.12.x are built with 2.9x and all plugins need to match the binary Scala version.
To add more information to what Yann said, Scala only guarantees compatibility between minor versions. That is, code compiled with any 2.8.x version is compatible with code compiled with any other 2.8.x version, but no code compiled with 2.8.x is compatible with code compiled by a 2.9.x version.
Now, SBT is a Scala application, and both the plugins and build configuration are libraries to it. SBT 0.12.x was compiled with Scala 2.9.x, so all plugins and project build configuration must also be compiled with Scala 2.9.x.
The project itself can be compiled with any version, as SBT does not need to interact with it.

sbt unresolved dependencies sbt_2.9.1;0.7.4 sbt_2.9.1;0.7.7:

I was getting the unresolved dependencies like the question here.
Getting org.scala-tools.sbt sbt_2.9.1 0.7.7 ...
::::::::::::::::::::::::::::::::::::::::::::::
:: UNRESOLVED DEPENDENCIES ::
::::::::::::::::::::::::::::::::::::::::::::::
:: org.scala-tools.sbt#sbt_2.9.1;0.7.7: not found
::::::::::::::::::::::::::::::::::::::::::::::
SBT 0.7.7 uses Scala 2.7.7 for the project configuration. SBT 0.11 uses Scala 2.9.1. You can use SBT 0.7.7 for configurations up to that version, but versions of SBT newer than 0.7.7 use a non-compatible configuration file.
Note that this is not related to the Scala version that will be used to compile the project itself, just the Scala version that is used to compile the configuration file. These are different things: you can use whatever version of Scala you want to compile your project, but you must use the version of Scala mandated by the SBT version to compile the project configuration.
To get an error message like that you must either have changed the Scala version for the project configuration, or used a newer SBT with a project written for an older version of SBT. Find out which it was, and correct the problem as needed.
I have an SBT 0.7.7 for projects that have not yet migrated to the new version, and the latest SBT for everything else. Put a different name on each script, and you are good to go.
While sbt-launch.jar makes an attempt to download and use the version of sbt specified in the project's project/build.properties, they must be compiled with matching versions of Scala. I think sbt 0.7.7 was compiled with Scala 2.7, but the most recent versions of sbt are compiled with Scala 2.9.
Most folks now just use a version of sbt-launch.jar that matches the version specified in project/build.properties. If you're running on Linux, OS X, or pretty anything that can run a Bash script, I highly recommend the launch script from sbt-extras. It will automagically use the version of sbt-launch.jar according to what's specified in project/build.properties, and gives some other handy command line parameters.
If that doesn't work for you, I think your best bet is different launch scripts to launch the different minor versions of sbt. Such as sbt7, sbt10 and sbt11, which launch 0.7.7, 0.10.1 and 0.11.2, respectively.
I have noticed that the issue can be resolved by updating or removing the sbt.version entry from project_root_folder/project/build.properties My current sbt version is 0.11.2 and I have updated it to sbt.version=0.11.2 . Removing the entry also works.