Black Rock Blog

Zero to a Scala SBT Project

| Comments

SBT (Simple Build Tool) is a build environment for Scala (and Java) applications. It features Maven-style dependency management, a build definition language, pluggable architecture and an interactive shell. Roughly akin to Maven for Java and Rake for Ruby, SBT can be used to build, run and deploy apps and can work alongside both text editors and full IDE’s.

In this tutorial I’ll demonstrate how to create a new Scala project (“HelloSBT”) from scratch with SBT, and an extra section on how to load the generated project into Intellij. This tutorial has been tested with SBT 0.12.2 and Scala 2.10.0

Part 1 - Setup

  1. If you don’t already have it on your system, download Java’s JDK 6 or 7 and install it.
  2. Download Scala 2.10 and install it in /usr/local (eg: /usr/local/scala-2.10.0)
  3. Download and install SBT. Homebrew users can run brew install sbt but it’s also pretty easy to install on Windows and Linux.

Part 2 - A Basic Hello SBT App

In which we create a very simple Scala app and SBT project from scratch, starting in your system shell (eg BASH) and finishing with a running example.

1
2
3
4
5
$ mkdir hellosbt
$ cd hellosbt
$ mkdir -p src/main/scala
$ echo 'object Hi extends App { println("Hello SBT") }' > src/main/scala/Hi.scala
$ sbt run

You should see the output after SBT initialized and compiles your app:

Hello SBT

To finish this basic SBT project you need a build definition file, stored in build.sbt at the root of the project. The .sbt file format is a domain specific language (DSL) based on but not exactly like Scala and contains mainly name-value pairs and library dependency management.

1
2
3
4
5
6
7
8
9
10
11
$ cat << EOF > build.sbt

organization := "scala"

name := "HelloSBT"

version := "1.0"

scalaVersion := "2.10.0"

EOF

Since you don’t need any external libraries at this point, your build.sbt file just defines your project information and the desired scala version.

With your project completed, bring up the SBT shell and test-drive just a few of the functions to get acquainted.

To avoid confusion the $ prompt indicates your system shell and the > prompt the SBT shell.

1
2
3
4
5
6
7
8
$ sbt
> about      # information about sbt, plugins, and your project
> help
> tasks      # project-specific task, eg run, compile, test, package
> clean      # cleans up (deletes) all temporary and build files
> compile    # 'run' invokes compile, but useful as an invididual step
> run        # runs the given class, or the main class if none is specified
> package    # builds an artifact from your project, eg .jar or .war file

After running package, exit the shell and check out your new project’s artifact:

target/scala-2.10/hellosbt_2.10-1.0.jar

Good news, you’ve created an SBT project!

Part 3 - Using External Libraries

Better news, since Scala is a JVM language you have access to the full (and massive) collection of open source Java libraries. The main distribution mechanism for Java libraries is Maven artifact repositories, and SBT has full support for adding them to your project. In this section we’ll add the popular Joda-Time Date/Time management library to the project and update the application to demonstrate it.

First open the build.sbt file created in Part 2 and add the following lines:

 
libraryDependencies += "joda-time" % "joda-time" % "1.6.2"

Note: SBT requires that settings in build.sbt must be separate by at least one blank line.

Now edit the Hi.scala file to make use of this new library, then we can try it out.

1
2
3
4
object Hi extends App {
  val now = new org.joda.time.DateTime()
  println("Hi SBT, the time is " + now.toString("hh:mm aa"))
}
1
$ sbt run

When you hit SBT will download the joda-time library from a public Maven repository and cache it in a local repository. You can find the library in ~/.ivy/cache since SBT uses the Java-based Apache Ivy project for library management.

After the library is downloaded and your project is compiled, SBT will display the new greeting with the current time.

Extra Credit: Open your SBT project in Intellij IDEA

I’m not going to argue the benefits of IDE’s vs Text Editors here, and will gamely sidestep the Eclipse vs Intellij IDE battle since this article is already long enough. However if you do like IDE’s and are amenable to using the free Intellij IDEA IDE, here’s how to get it to open your new SBT project so you can write and execute applications from inside without going to the command line.

This step uses Mike Peltonen’s excellent sbt-idea plugin for SBT to convert SBT projects to Intellij format. You’ll need to install the Intellij IDEA and its Scala plugin, which are free and open source. See my previous blog post Zero to Hello World in Scala for download links and installation instructions.

When Intellij is installed, run this to install the sbt-idea plugin globally :

1
2
3
4
5
6
7
8
$ mkdir -p ~/.sbt/plugins
$ cat << EOF >> ~/.sbt/plugins/build.sbt

resolvers += "Sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.3.0-SNAPSHOT")

EOF

Then run this in your hellosbt directory to generate the IDEA project:

1
$ sbt gen-idea

You can now open this project directly in Intellij IDEA. To execute the app, right-click on the Hi.scala file in the Project tab and choose Run Hi.main().

Next Steps

At this point you can create a simple SBT project with dependencies and optionally edit it in an IDE (or using a regular text editor).

If you’re still learning Scala I recommend picking up the classic Programming in Scala: A Comprehensive Step-by-Step Guide by one of the creators of the language. It’s a long read but covers the majority of the language and progresses at an easy pace.

A good next step is to start developing your first Scala web application, using one of the common Scala web frameworks such as Lift, Play or Scalatra.

Zero to Hello World in Scala

| Comments

For many developers, the first big hurdle in learning a new language is overcome when they can write and run a basic command-line application in an IDE. Although Scala developers can use the excellent REPL that comes with the scala app, being able to write and run an application in the IDE provides a comfortable foundation for the extensive learning curve of the Scala language (and of functional programming in general).

This tutorial shows how to go from zero to running a basic “Hello, World” Scala application in Intellij IDEA 12 CE IDE (the free, open-source version of Intellij IDEA). The intructions cover OS X but should be applicable with minor effort on Windows and Linux systems.

Part 1 - Setup

  1. If you don’t already have it on your system, download Java’s JDK 6 or 7 and install it.
  2. Download Scala 2.10 and install it in /usr/local (eg: /usr/local/scala-2.10.0)
  3. Download the free Intellij IDEA 12 CE IDE for your system and install it.

The last downloadable, Intellij’s Scala plugin, is installed within the Intellij app.

  1. Launch Intellij (aka the Intellij IDEA 12 CE app) which should bring up the “Intellij IDEA” dialog
  2. Select Configure and then Plugins
  3. Click on the Browse Repositories button and search for “Scala”
  4. Right-click on the Scala plugin and choose *Download and Install” to install it.

After closing the dialog and restarting Intellij you are ready to create the project.

Part 2 - Create The Scala Project

  1. In the “Intellij IDEA” dialog select Create New Project
  2. When the “New Project” dialog appears, select Scala Module on the left side
  3. Enter a name & location for your project
  4. If the Project SDK dropdown is set to ”” click New.. to select your JDK installation directory.
  5. On the right side of the dialog select Set Scala Home and enter “/usr/local/scala-2.10.0” in the text field immediately below this option. You should see a message that you have selected version 2.10.0, and the Compiler library and Standard library fields should be filled out.
  6. Select the Make global libraries feature to ensure future Scala projects can use this configuration
  7. Select Finish to create your new Scala project

Part 3 - Hello, Scala

  1. When your project appears, click the 1: Project tab on the left side of the window to display the “Project” view. You can also select View -> Tool Windows -> Project from the menu bar. Even better, Intellij ought to have shown this view by default when you create a new project since you can’t get started without it!
  2. Open your project and right-click on the src folder, then select New -> Scala Class in the contextual menu.
  3. In the “Create New Scala Class” dialog enter the name “Hello” and set the Kind dropdown to “Object”. Click OK to create the new file.

Now your new Scala object is ready, but it requires some work before you can execute it.

  1. Extend Scala’s App trait to make your object an entry point for an application. You can do this by changing object Hello to object Hello extends App .
  2. Add the idiomatic Hello, World statement. This simply requires writing println("Hello, World") in the body of the object.

Your code should look like this:

1
2
3
object Hello extends App {
    println("Hello, World")
}

To run your application, right-click on your Hello object in the Project pane on the left and choose Run ‘Hello.main()’ . After a short period compiling the program you should see the following in the Run view:

1
Hello, World

I hope you found this short tutorial to be useful. Note that although I have used Intellij IDEA in this article and recommend it for Scala development, many Scala developers prefer the Scala IDE for Eclipse IDE instead.

Option.get: The Shortcut That Comes Back to Bite You

| Comments

When you know that your Option reference is valid, Option.get will let you quickly access the wrapped value:

1
2
3
def findById(id: String): Option[UserRecord]
...
val currentUserRecord = findById( userId ).get

That was easy! Option.get removes the Option wrapper and returns the inner value so you can get to work with it.

Well, until you starting seeing these stack traces in production:

1
2
3
java.util.NoSuchElementException: None.get
  at scala.None$.get(Option.scala:274)
  ...

Everything was fine when your method was returning the expected Some wrapper in development… unit tests… staging… and production. But then came an unexpected condition when None was returned and your code wasn’t expecting it. None.get will instead throw the above exception, probably in a place where you weren’t expecting to catch one.

Recommendation: Always use Option.getOrElse instead of Option.get

Use Option.getOrElse to provide a default value or behavior when your reference is empty.

  • If your reference is defined, getOrElse returns the unwrapped value
  • If your reference is empty, getOrElse returns the result of your function literal or default value

For example:

1
2
3
def findById(id: String): Option[UserRecord]
...
val currentUserRecord = findById( userId ).getOrElse( defaultUserRecord )

By providing a workaround for empty references, you are making your application sturdier and emphasizing how it handles unexpected conditions. Future maintainers of your code (and you should always plan for them) will thank you.

Note: your function literal is not actually required to return a valid default value here. In cases where an exception is more appropriate there would not actually be anything returned:

1
2
3
4
5
def findById(id: String): Option[UserRecord]
...
val currentUserRecord = findById( userId ).getOrElse {
  throw new InvalidUserException(s"Whoah! User '${userId}' couldn't be found!")
}

Update - A Very Relevant Tweet On This Subject

Okay, Paul is only half-kidding here. Still its surprising how often one finds our fellow developers still calling Option.get (and ending up with None.get).

Stick with Option.getOrElse and you’ll never get caught by surprise.

Prefer headOption to Head in Scala Collections

| Comments

The List.head() method in Scala’s List collection class provides a simple way to get the first element in the list, but if the list is empty it will throw this exception (since there is nothing it can actually return)

1
2
3
4
5
6
7
val users: List[String] = loadLatestUsers()
val latestUser: String = users.head

java.util.NoSuchElementException: head of empty list
    at scala.collection.immutable.Nil$.head(List.scala:371)
    at scala.collection.immutable.Nil$.head(List.scala:368)
    ...

You can prevent this by checking that the list is non-empty before calling this method. A better (and more Scala-ish) way is to instead call List.headOption() which uses Scala’s Option pattern.

How to handle the case of an empty list depends on your requirements and context, especially what you plan[ned] to do with the first element of the list. If you can defer handling the empty list until the value is used, keep the Option wrapper around the element.

1
val latestUser: Option[String] = users.headOption

Or does an empty list denote a state so broken that you cannot continue?

1
2
3
val latestUser: String = users.headOption.getOrElse {
  throw new RuntimeException("No names are available!") )
}

Does an empty list make the rest of the method simply irrelevant?

1
val latestUser: String = users.headOption.getOrElse( return )

Or can a default, placeholder value be safely used here?

1
val latestUser: String = users.headOption.getOrElse( "" )

After using List.headOption to explicitly handle the case of an empty list, you have now prevented a potential failure at runtime with minimal changes or bulk added to your code.

First Post!

And just in time for the new year! I’m giving up the old Wordpress-based blog and the now-obsolete posts there and am starting out fresh for 2013 with a new blog.

This new blog is based on Octopress and sports a cleaner version of the old BKS2 Black Rock Desert mountainscape and a simpler design.

Thanks to Brandon Mathis for Octopress and Dan Watson for his Category List plugin which will improve site browsing, assuming I write enough posts with fascinating categories.