// Ensure we run outside of sbt. This is especially useful for setting JVM-level flags fork in run := true // Set flags for java. Memory, GC settings, properties, etc. javaOptions ++= Seq("-Xmx4g") mainClass in run := Some("mypackage.MyMainClass")
That lets you use "run" to spin up a forked JVM with your provided main class and arguments. (Aside: sbt-revolver is a MUCH friendlier way to run main classes).
But what if you want to run a main class with a different set of JVM flags? Maybe you have a memory hog, or you want to specify a debug logback config - or any other number of reasons. Or maybe you just want to have a shortcut for a long class name, or to have a default set of arguments for your main class.
This can be done with the Fork API:
// Create a task for your new main class. This is an input task so that you // can provide arguments to it via the sbt console. lazy val runMyOtherMain = inputKey[Unit]("run MyOtherMain") runMyOtherMain := { // Parse the arguments typed on the sbt console. val args = sbt.complete.Parsers.spaceDelimited("[main args]").parsed // Build up the classpath for the subprocess. Yes, this must be done manually. // This also ensures that your code will be compiled before you run. val classpath = (fullClasspath in Compile).value val classpathString = Path.makeString(classpath map { _.data }) // Any JVM args you want. You could use javaOptions.value to get your default // list, if you like. val jvmArgs = Seq("-Xmx4g", "-Dlogback.configurationFile=debug_logback.xml") Fork.java( // Full options include whatever you want to add, plus the classpath. ForkOptions(runJVMOptions = jvmArgs ++ Seq("-classpath", classpathString)), // You could also add other default arguments here. "mypackage.MyOtherMainClass" +: args ) }
Now, you can type runMyOtherMain arg1 arg2 from the sbt console, and it'll execute:
java -Xmx4g -Dlogback.configurationFile=debug_logback.xml -classpath [actual classpath] mypackage.MyOtherMainClass arg1 arg2
Sweet!