mushroom
mushroom

Reputation: 6289

SBT to run Play app exits immediately when started using scala.sys.process.run?

I am writing an integration test that needs to start up several applications. One of these applications is a Play one as a SBT project called appA.

I am able to start the app on the right port using scala.sys.process as follows:

import scala.sys.process._
import org.scalatest._

class Main extends FeatureSpec with Matchers{
  val app = Seq("sbt", "project appA", "run 7777").run
  println(app.exitValue)
}

The spawned application however exits immediately with return value 0. No errors are displayed to the console. I just see:

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:3000

(Server started, use Ctrl+D to stop and go back to the console...)


[success] Total time: 1 s, completed Feb 27, 2014 10:26:56 PM
0

The 0 at the end of the output is from calling exitValue on the created process. exitValue blocks until the spawned process exits.

How can I run the Play application without it exiting immediately? Is there a better way to start the application?

Upvotes: 3

Views: 1309

Answers (1)

yǝsʞǝla
yǝsʞǝla

Reputation: 16412

SBT has 2 run modes - interactive and batch. If you run without any args it goes to interactive mode and does not exit. When you run it by passing commands it runs in a batch mode and exits when the last command is complete. It does not matter if your application inside SBT runs in a forked JVM or not.

Thus to "fix" it you can apply this hack: add ~ command to the end of the list of sbt commands/args:

val app = Seq("sbt", "project appA", "run 7777", "~").run

~ is used to watch source code for changes and recompile when it happens. Thus SBT will never exit unless stopped by a user or killed.

A cleaner way would be to run Play application in a Jetty container (assuming you have WAR to run) or such by calling a main class that starts up Jetty with a command like java com.example.MyMain but that requires additional setup.

Upvotes: 6

Related Questions