I am trying to create a Scala application consisting of a library project (let's call this common
), a Thrift server project (let's call this server
) and a Play web application project (hereinafter known as web
). All three are written in Scala and built with sbt.
My project structure looks like this:
myproject/ -common/ ... -server/ ... -web/ -app/ -conf/ ... -project/ -Build.scala -build.properties -build.sbt
My build.sbt
file (simplified a bit) looks like this:
import play.Project._ name := "myproject" version := "1.0-SNAPSHOT" lazy val common = project lazy val web = project .settings(playScalaSettings: _*) .dependsOn(common) lazy val server = project .dependsOn(common) lazy val root = project.in(file(".")) .aggregate(common, web, server)
The problem with this is that the root project is not a Play project, so the play
command does not work (it errors out with
java.lang.RuntimeException: */*:playRunHooks is undefined. at scala.sys.package$.error(package.scala:27)
I can fix this by making the root project look like a Play project if I insert the line playScalaSettings
after the version
line in the SBT file, but then I have another problem: the play run
command attempts to run the root project, not the web
subproject. Obviously the play run
command does not work when run in the web
subdirectory since there is no SBT file there to describe the project and its dependencies.
I am looking for a solution that allows me to retain this project structure (meaning the Play project is one of many sub-projects in my application), while retaining all the Play framework hotness like hot updates when code changes (even code in dependent libraries like common
).
I thought I found the solution by running play
to get the interactive console, and then
project web run
That works, but it doesn't work on the command line. play web/run
for some reason runs the root level run
command, which as noted above does not work because the root application is not a Play application.
Note: A similar question was asked before in the context of Play 2.0 at Play Framework as SBT Non-Root Module, but the answer is not satisfactory, nor do I believe it is still correct as of Play 2.2.
Delegate a Scala project build to sbtPress Ctrl+Alt+S to open the IDE settings and select Build, Execution, Deployment | Build Tools | sbt. In the sbt projects section, select a project for which you want to configure build actions. In the sbt shell section, select the builds option. Click OK to save the changes.
sbt file defines settings for your project. You can also define your own custom settings for your project, as described in the sbt documentation. In particular, it helps to be familiar with the settings in sbt.
if
play (entering shell) project web run
works, then you can make it work from the command line:
play "project web" "run"
You can do in command line whatever you can do in the shell.
I have the same project structure and it is the way to do that works fine for me.
By the way, I don't think the hot reload stuff is related to Play. It is incremental compilation that is provided by SBT which is used by Play. The play command is just some hacked SBT launcher I think.
The following command works fine for me:
sbt "project web" "run"
And it starts the Play project with hot reload.
I think you can even use
sbt "project web" "~run"
Which will try to recompile each time you change a source file, instead of waiting for a browser refresh, and will make win some time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With