Scala/SBT: How to specify a main method/class to run

This is an excerpt from the Scala Cookbook. This is Recipe 18.9, “How to Specify a Main Class to Run with SBT.”

Problem

In a Scala SBT project, you have multiple main methods in objects in your project, and you want to specify which main method should be run when you type sbt run, or specify the main method that should be invoked when your project is packaged as a JAR file.

Solution

If you have multiple main methods in your project and want to specify which main method to run when typing sbt run, add a line like this to your build.sbt file:

// set the main class for 'sbt run'
mainClass in (Compile, run) := Some("com.alvinalexander.Foo")

This class can either contain a main method, or extend the App trait.

To specify the class that will be added to the manifest when your application is packaged as a JAR file, add this line to your build.sbt file:

// set the main class for packaging the main jar
mainClass in (Compile, packageBin) := Some("com.alvinalexander.Foo")

That setting tells SBT to add the following line to the META-INF/MANIFEST.MF file in your JAR when you run sbt package:

Main-Class: com.alvinalexander.Foo

Using run-main

When running your application with SBT, you can also use SBT’s run-main command to specify the class to run. Invoke it like this from your operating system command line:

$ sbt "run-main com.alvinalexander.Foo"
[info] Loading global plugins from /Users/Al/.sbt/plugins
[info] Running com.alvinalexander.Foo 
hello
[success] Total time: 1 s

Invoke it like this from inside the SBT shell:

$ sbt

> run-main com.alvinalexander.Foo
[info] Running com.alvinalexander.Foo 
hello
[success] Total time: 1 s

Discussion

If you have only one main method in an object in your project (or one object that extends the App trait), SBT can automatically determine the location of that main method. In that case, these configuration lines aren’t necessary.

If you have multiple main methods in your project, and don’t use any of the approaches shown in the Solution, SBT will prompt you with a list of objects it finds that have a main method or extend the App trait when you execute sbt run:

Multiple main classes detected, select one to run:

[1] com.alvinalexander.testproject.Foo
[2] com.alvinalexander.testproject.Bar

The following code shows what a build.sbt file with both of the mainClass settings looks like:

name := "Simple Test Project"

version := "1.0"

scalaVersion := "2.10.0"

// set the main class for packaging the main jar
mainClass in (Compile, packageBin) := Some("com.alvinalexander.testproject.Foo")

// set the main class for the main 'sbt run' task
mainClass in (Compile, run) := Some("com.alvinalexander.testproject.Foo")

... this post is sponsored by my books ...
 

When your sbt mainClass has command-line parameters

When your main class (mainClass) requires command-line parameters, do the initial configuration in the build.sbt file as shown above, and then when you run your main method/class from inside sbt, supply the parameters there:

sbt> run hello world

For instance, the code that generates this website is written in Scala, and my build.sbt mainClass setting looks like this:

mainClass in (Compile, run) := Some("static_drupal.GenAllNodes")

Then when I want to regenerate all of the web pages that have been updated in the last ten days, I use this sbt run command:

sbt> run 10

If you need to use sbt and run a main class that has command line arguments, I hope this example is helpful.

See Also