Setting up Scala is really easy. Just extract it, add the bin/
directory to your %PATH%
, and you are ready to run scala and fsc. But as with java, this is seldom enough. Normally, you want to use an IDE like eclipse. This is no problem, there’s scala-ide as an eclipse plugin out there. Next, you want to be able to write some tests. The scalatest library looks good! But this is where the problems start: how to run all tests in eclipse? Do you have to manage your dependencies manually? A great tool for this build management tasks is maven. Maven works well with Java and Scala. A more integrated approach can be found in SBT: the Scala Build Tool. It has an interactive console which makes it pretty fast, and it introduces some cool features like the „~
„-Prefix: „~ test
“ means: execute the test-Target every time the source changes. I will show how to install SBT and we will create a small example project which solves the factorization kata.
The full documentation of SBT can be found in its wiki. What I will discuss here is how to set up SBT together with Eclipse (and cygwin), so that you can write your code in eclipse while SBT is used to build and test it. I use Windows for this little tutorial, but the basic steps to get Linux support are the same. In Linux, the „Local Terminal“ plugin even allows you to integrate sbt fully into eclipse.
Update: I updated the sbt bash script since the arrow keys did not properly work.
Setup SBT
General install
First, you need to install a copy of SBT. Download sbt-launch.jar from the SBT Website. Place the jar-File in a directory which is in your %PATH%
(we call this directory %SCRIPT_DIR%
). Next, create a file „sbt.bat
“ in the same directory. The content of this file should be:
@echo off set SCRIPT_DIR=%~dp0 java -Xmx512M -jar "%SCRIPT_DIR%sbt-launch.jar" %* @echo on
It only starts sbt-launch and passes all parameters. This would be enough to use sbt the first time.
(Optional) Setup Maven Repository
If you already have a local maven Repository, we can add this to SBT’s resolver. This is easily done by editing SBT’s local configuration. Go to %USERPOFILE%
and create a directory named „.sbt
„. Inside this directory, create a file „local.sbt
“ with the following content (if you do not use the default maven repository location, you should change the path here):
resolvers <<= resolvers {rs => val localMaven = "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository" localMaven +: rs }
That’s enough to use maven’s repository as well.
Setup Eclipse Integration
Next, we want to be able to create eclipse projects from sbt projects. It is possible with the sbteclipse-plugin. This step is important if you want to develop scala projects with eclipse, because eclipse must be able to use sbt’s classpath. Otherwise, imported libraries (e.g. scalaTest) would not be visible in eclipse.
If not already done in the last step, create a „.sbt
“ directory in %USERPROFILE%
. Inside the directory, create a directory „plugins
“ and place a „build.sbt
“ there with the following content:
resolvers += Classpaths.typesafeResolver addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0-RC1")
Now every project has the ability to generate an eclipse configuration just by typing „sbt eclipse
„. I.e. there is no need to setup the sbteclipse plugin per project.
A first project
It’s time for the first project. Navigate into the eclipse workspace and create a new folder, let’s call it „katas
„. Inside this folder, create a new „build.sbt
“ and enter some basic information:
name := "Katas" version := "1.0" scalaVersion := "2.9.1" libraryDependencies += "org.scalatest" %% "scalatest" % "1.7.1" % "test"
Next, fire up sbt in this directory and the sbt prompt appears. Type „eclipse
„. You can now start eclipse and you will find a new project „Katas“ there. Fine! Go back to the sbt prompt and type „~ test
“ to automatically run all tests everytime the project changes.
Inside eclipse, go to src/test/scala
, create a namespace „factorization
“ and add a file „factorizationTest.scala
„, also add „factorization.scala
“ to src/main/scala/factorization
. I will skip the TDD-Cycles here, you can do them on your own :-). When you do it, note that SBT builds and executes the tests everytime you save the file. A possible solution (inspired by the ruby solution of Robert C. Martin) is the following:
// factorizationTest.scala: package factorization import org.scalatest.FunSpec class FactorizationTest extends FunSpec { describe("A factorization object") { for ((input, output) <- List( (1, List(1)), (2, List(2)), (4, List(2, 2)), (97, List(97)), (2*3*5*5*7, List(7, 5, 5, 3, 2)) )) { it("should factor "+input+" to "+output.mkString("*")) { val fac = new Factorization assert(fac.factorize(input) === output) } } } } // factorization.scala: package factorization import scala.annotation.tailrec class Factorization { def factorize(x: Int): List[Int] = { @tailrec def factorizeInternal(x: Int, factor: Int, result: List[Int]): List[Int] = { if (factor > x) result else if (x % factor == 0) return factorizeInternal(x / factor, factor, factor :: result) else if (factor > math.sqrt(x)) return factorizeInternal(x, x, result) else return factorizeInternal(x, factor + 1, result) } if (x == 1) return List(1) else return factorizeInternal(x, 2, Nil) } }
Now that everything runs we can go back to sbt, abort the test cycle by pressing return. Typing „package
“ builds us a jar file with contains the Factorization class.
Using SBT inside cygwin
I really love linux, so I use cygwin as much as I can. As you have may noticed, the output of SBT is black and white in the Windows command prompt. This makes it hard to distinguish between output of sbt and scalatest. It is even harder to see, if a test failed. If you’re using SBT inside cygwin, you can enable color support, which makes sbt much easier to read. Just add a new file „sbt
“ next to „sbt.bat
“ (the directory should also be in your cygwin’s $PATH
):
#!/bin/bash JAVA_ARGS="-Xmx1024M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -Dfile.encoding=UTF8 -Djline.terminal=jline.UnixTerminal" SCRIPT_DIR=$(cygpath -w "$(dirname "$(readlink -f "$0")")") stty -icanon min 1 -echo > /dev/null 2>&1 java $JAVA_ARGS -jar "$SCRIPT_DIR\\sbt-launch.jar" "$@" stty icanon echo > /dev/null 2>&1
Note the „-Djline.terminal=jline.UnixTerminal
“ parameter. If you now type „sbt
“ inside your bash/zsh/whatever, sbt will support more colorful output.
Have fun while experimenting with Scala