I like Christmas because, beside resting from work and having fun with family and friends, usually there is time to learn something new. During this Xmas I’ve been playing with Scala: First, trying to finish the Coursera Functional Programming Principles course. Later, working a bit in a personal project. Better late than never :smile

As for my personal project, it provides more than one executable entry point:

Working with Scala and SBT, the command sbt run looks like the natural alternative. It seeks for every Scala Object in the project that could be used as the assembly entry point:

  • an object that defines a main method
  • an object that inherits from App

If your application has more than one object fitting the previous requirement, the command sbt run will ask for your help to finish the execution.

Let’s consider the following snippet of code, having two objects that define a main method:

# File src/main/Foo.scala
object Foo {
    def main(args: Array[String]) = println("Hello from Foo")

# File src/main/Bar.scala
object Bar extends App{
    println("Hello from Bar")

When you execute the sbt run command, the following text shows up:

> sbt run

Multiple main classes detected, select one to run:

 [1] Bar
 [2] Foo

Enter number: 2
[info] Running Foo
Hello from Foo
[success] Total time: 29 s, completed Dec 30, 2012 11:36:28 PM

It requires human action (in the previous example, fill in the number 2), as the run command does not receive any parameter to automate the process.

Fortunately, there’s an easy solution using the SBT plugin sbt-start-script :squirrel:. You just need to follow these three steps:

  • Create (or update) the file project/plugins.sbt, including:
addSbtPlugin("com.typesafe.sbt" % "sbt-start-script" % "0.6.0")
  • Create (or update) the file build.sbt, adding:
import com.typesafe.sbt.SbtStartScript
seq(SbtStartScript.startScriptForClassesSettings: _*)
  • Execute:
sbt update
sbt start-script

As result, a new file target/start is created. A file that requires the main class name to be executed as the first argument:

> target/start Foo
Hello from Foo

> target/start Bar
Hello from Bar

Two last tips:

  • In case your program just has a single main class, the script does not require any argument.

  • Remember to add the automatically generated file target/start to your CVS

« Home