About this post
Already working on an sbt-based Scala project with two sub-projects, I wanted to create a third sub-project, a Play2 application. The following describes what worked for me.
Creating the sub-project structure
Before adding the third sub-project, my sbt project structure looked like this:
importer/ └ src/ ├ main/ └ test/ spark/ └ src/ ├ main/ └ test/ project/ └ plugins.sbt build.sbt
build.sbt, the sub-projects where declared as follows (shortened for brevity):
name := "journeymonitor-analyze" val commonSettings = Seq( organization := "com.journeymonitor", version := "0.1" ) lazy val testDependencies = Seq ( "org.scalatest" %% "scalatest" % "2.2.4" % "test" ) lazy val cassandraDependencies = Seq ( "com.datastax.cassandra" % "cassandra-driver-core" % "2.1.8", "com.chrisomeara" % "pillar_2.11" % "2.0.1" ) lazy val spark = project .settings(commonSettings:_*) .settings(libraryDependencies ++= (testDependencies)) lazy val importer = project .settings(commonSettings:_*) .settings(libraryDependencies ++= (testDependencies ++ cassandraDependencies)) lazy val main = project.in(file(".")) .aggregate(spark, importer)
I wanted to name the new sub-project “api”, and it should reside in a folder of the same name.
First, I installed the TypeSafe Activator onto my Mac OS X system via
brew install typesafe-activator. Next, I changed to the root folder of my project, and ran
activator new api play-scala. This resulted in the following structure:
api/ ├ build.sbt ├ api/ ├ conf/ ├ public/ ├ test/ └ project/ └ plugins.sbt importer/ └ src/ ├ main/ └ test/ spark/ └ src/ ├ main/ └ test/ project/ └ plugins.sbt build.sbt
Next, I added the content of the newly added
api/project/plugins.sbt to the existing
project/plugins.sbt file, and removed the former. Then, I extended the existing
build.sbt file as follows:
name := "journeymonitor-analyze" val commonSettings = ... lazy val testDependencies = ... lazy val cassandraDependencies = ... lazy val spark = project ... lazy val importer = project ... lazy val api = project .settings(commonSettings:_*) .settings(assemblyJarName in assembly := "journeymonitor-analyze-api-assembly.jar") lazy val main = project.in(file(".")) .aggregate(spark, importer, api)
This declares the api sub-project and applies the commonSettings to it, but doesn’t configure it further. This happens via the sub-project specific configuration in file
name := """api""" version := "1.0-SNAPSHOT" enablePlugins(PlayScala) scalaVersion := "2.11.7" libraryDependencies ++= Seq( jdbc, cache, ws, specs2 % Test ) resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases" routesGenerator := InjectedRoutesGenerator
The above shows two changes that were necessary: on line 5, the val declaration needs to be removed, leaving only the enablePlugins call, and on line 7, I changed the scalaVersion from “2.11.6″ to “2.11.7″.
With this, I was now able to run
sbt from the root folder, switch to the new sub-project within sbt via
project api, and successfully run the Play2 test suite via
Commit 4a899b0 on the journeymonitor/analyze repo on Github shows the differences before and after adding the new sub-project.