There are two options of standalone deployment currently:
- Single .jar using sbt-assembly which contains runtime and webapp resources. Loading resources from the .jar file is quite slow in my experience.
- Distribution .zip file using
scalatra-sbt
plugin, contains a start shell script, the runtime resources and the webapp resources in folders.
1. Standalone JAR
For a standalone .jar file using sbt-assembly
you need to add the plugin first to project/build.sbt
:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.9.0")
Then you need to modify the project build, e.g. project/build.scala
. Import the plugin's settings and keys:
import sbtassembly.Plugin._
import sbtassembly.Plugin.AssemblyKeys._
With that you can create settings for the sbt-assembly
plugin:
// settings for sbt-assembly plugin
val myAssemblySettings = assemblySettings ++ Seq(
// handle conflicts during assembly task
mergeStrategy in assembly <<= (mergeStrategy in assembly) {
(old) => {
case "about.html" => MergeStrategy.first
case x => old(x)
}
},
// copy web resources to /webapp folder
resourceGenerators in Compile <+= (resourceManaged, baseDirectory) map {
(managedBase, base) =>
val webappBase = base / "src" / "main" / "webapp"
for {
(from, to) <- webappBase ** "*" x rebase(webappBase, managedBase / "main" / "webapp")
} yield {
Sync.copy(from, to)
to
}
}
)
The first defines a merge strategy, the last one copies the static web resources from src/main/webapp
to <resourceManaged>/main/webapp
. They will be included in the final .jar in a sub-folder /webapp
.
Include the settings in your project:
lazy val project = Project("myProj", file(".")).settings(mySettings: _*).settings(myAssemblySettings:_*)
Now the launcher needs to be created. Note how the resource base is set:
import org.eclipse.jetty.server.nio.SelectChannelConnector
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.webapp.WebAppContext
import org.scalatra.servlet.ScalatraListener
object JettyMain {
def run = {
val server = new Server
val connector = new SelectChannelConnector
connector.setPort(8080)
server.addConnector(connector)
val context = new WebAppContext
context.setContextPath("/")
val resourceBase = getClass.getClassLoader.getResource("webapp").toExternalForm
context.setResourceBase(resourceBase)
context.setEventListeners(Array(new ScalatraListener))
server.setHandler(context)
server.start
server.join
}
}
2. .zip Distribution using scalatra-sbt
Plugin
You need to add those imports to your SBT build.scala
:
import org.scalatra.sbt.DistPlugin._
import org.scalatra.sbt.DistPlugin.DistKeys._
Then you need to add the plugin's settings to your project. The settings are in DistPlugin.distSettings
.
You can also customize your distribution and add custom memory settings, exports and command line options. Note that those are all optional:
val myDistSettings = DistPlugin.distSettings ++ Seq(
mainClass in Dist := Some("ScalatraLauncher"),
memSetting in Dist := "2g",
permGenSetting in Dist := "256m",
envExports in Dist := Seq("LC_CTYPE=en_US.UTF-8", "LC_ALL=en_US.utf-8"),
javaOptions in Dist ++= Seq("-Xss4m", "-Dfile.encoding=UTF-8")
)
On the SBT prompt you can then type dist
. The .zip file will be in the target
folder.