79
votes

Could you guys please explain to me how to set main class in SBT project ? I'm trying to use version 0.13.

My directory structure is very simple (unlike SBT's documentation). In the root folder I have build.sbt with following content

name := "sbt_test"

version := "1.0"

scalaVersion := "2.10.1-local"

autoScalaLibrary := false

scalaHome := Some(file("/Program Files (x86)/scala/"))

mainClass := Some("Hi")

libraryDependencies ++= Seq(
    "org.scalatest" % "scalatest_2.10" % "2.0.M5b" % "test"
)

EclipseKeys.withSource := true

And I have subfolder project with single file Hi.scala which contains following code

object Hi {
  def main(args: Array[String]) = println("Hi!")
}

I'm able to compile it by calling sbt compile but sbt run returns

The system cannot find the file C:\work\externals\sbt\bin\sbtconfig.txt.
[info] Loading project definition from C:\work\test_projects\sbt_test\project
[info] Set current project to sbt_test (in build file:/C:/work/test_projects/sbt_test/)
java.lang.RuntimeException: No main class detected.
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) No main class detected.
[error] Total time: 0 s, completed Apr 8, 2013 6:14:41 PM
9
Your experience is not typical. Have you considered whether your non-standard Scala build might be part of the problem?Randall Schulz
@RandallSchulz Nope. Because I can compile. Also for the sake of experiment I changed setting to let SBT get Scala compiler and renamed name of the class in mainClass. sbt run worked anyway :) Which indicates that SBT simply ignores the setting.expert
@HeikoSeeberger I took whatever was latest on SBT's website. Directory structure of standard Play Framework project is different. I wanted to force Play to use latest version of scala instead of forcing to 2.9.2. Could you please upvote the question ?expert
You are missing some important points: First, scala-sbt.org shows 0.12.3 as the latest (released) version. Second, the Scala version sbt is using internally is not related to the Scala version for your project, except that it is used as a default if you don't set a different scalaVersion in your build. Third, Play, like many other Scala libraries, is compiled against a specific version of Scala and you must use that (or a binary compatible upgrade). Fourth, I'm exclusively acting on my own behalf here.Heiko Seeberger
@HeikoSeeberger Issues described in this question were not related to alpha version. But nice try.expert

9 Answers

52
votes

You need to put your application's source in src/main/scala/, project/ is for build definition code.

25
votes

Try to use an object and extend it from App instead of using class

object Main extends App {
  println("Hello from main scala object")
}
16
votes

Here is how to specify main class

mainClass in (Compile,run) := Some("my.fully.qualified.MainClassName")

6
votes

For custom modules in SBT (0.13), just enter on the SBT console:

 project moduleX
 [info] Set current project to moduleX (in build file:/path/to/Projects/)
 >   run
 [info] Running main 

to switch scope to moduleX, as define in Built.scala. All main classes within that scope will be detected automatically. Otherwise you get the same error of no main class detected. For God's sake, SBT does not tell you that the default scope is not set. It has nothing to do with default versus non default source folders but only with SBT not telling anything that it doesn't know which module to use by default.

Big Hint to typesafe: PLEASE add a default output like:

[info] Project module is not set. Please use ''project moduleX''  set scope 
or set in Built file (LinkToDocu)  

at the end of SBT start to lower the level of frustration while using SBT on multi module projects.....

3
votes

If you have multiple main methods in your project you can add the following line to your build.sbt file:

val projectMainClass = "com.saeed.ApplicationMain"

mainClass in (Compile, run) := Some(projectMainClass)

If you want 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:

mainClass in (Compile, packageBin) := Some(projectMainClass)

You can also specify main class using run-main command in sbt and activator to run:

sbt "run-main com.saeed.ApplicationMain"

or

activator "run-main com.saeed.ApplicationMain"
3
votes

I had the same issue: was mode following the tutorial at http://www.scala-sbt.org/0.13/docs/Hello.html, and in my opinion, as a build tool sbt's interaction and error messages can be quite misleading to a newcomer.

It turned out, hours of head scratching later, that I missed the critical cd hello line in the example each time. :-(

2
votes

There are 4 options

  1. you have 1 main class

    • sbt run and sbt will find main for you
  2. you have 2 or more main classes

    • sbt run and sbt will propose to select which one you want to run.

Multiple main classes detected, select one to run:
[1] a.b.DummyMain1
[2] a.b.DummyMain2
Enter number:

  1. You want to set main class manually.

    mainClass in run := Some("a.b.DummyMain1")
    
  2. You could run with main class as parameter

    sbt runMain a.b.DummyMain1
    
1
votes

If the Main class is in a different project then by setting the below command in build.sbt would work:

addCommandAlias("run", "; project_folder/run")
0
votes

I had the same issue. Resolved it after adding PlayMinimalJava plugin in build.sbt.

Not sure how it got fixed, if someone can highlight how PlayMinimalJava solves it, would be great.

enablePlugins(PlayMinimalJava)

My build.sbt looks like this

organization := "org"
version := "1.0-SNAPSHOT"
scalaVersion := "2.13.1"
libraryDependencies += guice
enablePlugins(PlayMinimalJava)

Log

C:\Users\KulwantSingh\repository\pdfdemo>sbt run
Java HotSpot(TM) Client VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
[info] Loading settings for project pdfdemo-build from plugins.sbt ...
[info] Loading project definition from C:\Users\KulwantSingh\repository\pdfdemo\project
[info] Loading settings for project pdfdemo from build.sbt ...
[info] Set current project to pdfdemo (in build file:/C:/Users/KulwantSingh/repository/pdfdemo/)
[warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Enter to stop and go back to the console...)

[info] Compiling 6 Scala sources and 2 Java sources to C:\Users\KulwantSingh\repository\pdfdemo\target\scala-2.13\classes ...
[info] p.a.h.EnabledFilters - Enabled Filters (see <https://www.playframework.com/documentation/latest/Filters>):

    play.filters.csrf.CSRFFilter
    play.filters.headers.SecurityHeadersFilter
    play.filters.hosts.AllowedHostsFilter

[info] play.api.Play - Application started (Dev) (no global state)