Standalone deployment of Scalatra servlet

后端 未结 3 425
梦谈多话
梦谈多话 2020-12-16 03:18

I implemented a Scalatra servlet and now want to create an executable jar, just like described in this tutorial: http://www.scalatra.org/2.2/guides/deployment/standalone.htm

3条回答
  •  無奈伤痛
    2020-12-16 03:45

    There are two options of standalone deployment currently:

    1. Single .jar using sbt-assembly which contains runtime and webapp resources. Loading resources from the .jar file is quite slow in my experience.
    2. 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 /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.

提交回复
热议问题