diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/akka-bash-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/akka-bash-template new file mode 100644 index 000000000..9fd9e6d4c --- /dev/null +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/akka-bash-template @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +declare AKKA_HOME="$(cd "$(cd "$(dirname "$0")"; pwd -P)"/..; pwd)" +declare -r app_home="$0" +declare -r lib_dir="${AKKA_HOME}/lib" + +${{template_declares}} + +[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xms1024M -Xmx1024M -Xss1M -XX:MaxPermSize=256M -XX:+UseParallelGC" + +# we will use akka_classpath instead the app_classpath +[ -n "$akka_classpath" ] || akka_classpath="$AKKA_HOME/lib/*:$AKKA_HOME/conf" + +java $JAVA_OPTS -cp "$akka_classpath" -Dakka.home="$AKKA_HOME" -Dakka.kernel.quiet=false akka.kernel.Main $app_mainclass diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/akka-bat-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/akka-bat-template new file mode 100644 index 000000000..a905bd8b0 --- /dev/null +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/akka-bat-template @@ -0,0 +1,11 @@ +echo off + +set _JAVA_OPTS=%_JAVA_OPTS% %_JAVA_PARAMS% + +@@APP_DEFINES@@ + +set AKKA_HOME=%~dp0.. +set JAVA_OPTS=-Xmx1024M -Xms1024M -Xss1M -XX:MaxPermSize=256M -XX:+UseParallelGC +set AKKA_CLASSPATH=%AKKA_HOME%\lib\*;%AKKA_HOME%\config;%AKKA_HOME%\lib\akka\* + +java %JAVA_OPTS% -cp "%AKKA_CLASSPATH%" -Dakka.home="%AKKA_HOME%" akka.kernel.Main %APP_MAIN_CLASS% %* diff --git a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala index 484d77a85..0759b1b8f 100644 --- a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala @@ -47,6 +47,8 @@ object SbtNativePackager extends Plugin private[this] def genericMappingSettings: Seq[Setting[_]] = packagerSettings ++ mapGenericFilesToLinux ++ mapGenericFilesToWindows def java_application: Seq[Setting[_]] = genericMappingSettings ++ archetypes.JavaAppPackaging.settings + def akka_application: Seq[Setting[_]] = + genericMappingSettings ++ archetypes.AkkaApp.settings def java_server: Seq[Setting[_]] = genericMappingSettings ++ archetypes.JavaServerAppPackaging.settings } diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala new file mode 100644 index 000000000..30d62b01c --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala @@ -0,0 +1,11 @@ +package com.typesafe.sbt +package packager +package archetypes + +/** + * Created by max.cai on 2014-09-27. + */ +object AkkaApp extends JavaApp { + val bashTemplate = "akka-bash-template" + val batTemplate = "akka-bat-template" +} diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala index 8c4e3d33d..5c9d4c5f6 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala @@ -18,7 +18,14 @@ import SbtNativePackager._ * * **NOTE: EXPERIMENTAL** This currently only supports universal distributions. */ -object JavaAppPackaging { +object JavaAppPackaging extends JavaApp { + val bashTemplate = "bash-template" + val batTemplate = "bat-template" + +} +trait JavaApp { + val bashTemplate: String + val batTemplate: String def settings: Seq[Setting[_]] = Seq( // Here we record the classpath as it's added to the mappings separately, so @@ -85,10 +92,14 @@ object JavaAppPackaging { def makeUniversalBinScript(defines: Seq[String], tmpDir: File, name: String, sourceDir: File): Option[File] = if (defines.isEmpty) None else { - val defaultTemplateLocation = sourceDir / "templates" / "bash-template" - val scriptBits = - if (defaultTemplateLocation.exists) JavaAppBashScript.generateScript(defines, defaultTemplateLocation.toURI.toURL) - else JavaAppBashScript.generateScript(defines) + val defaultTemplateLocation = sourceDir / "templates" / bashTemplate + val defaultTemplateSource = getClass.getResource(bashTemplate) + + val template = if (defaultTemplateLocation.exists) + defaultTemplateLocation.toURI.toURL + else defaultTemplateSource + + val scriptBits = JavaAppBashScript.generateScript(defines, template) val script = tmpDir / "tmp" / "bin" / name IO.write(script, scriptBits) // TODO - Better control over this! @@ -99,10 +110,13 @@ object JavaAppPackaging { def makeUniversalBatScript(replacements: Seq[(String, String)], tmpDir: File, name: String, sourceDir: File): Option[File] = if (replacements.isEmpty) None else { - val defaultTemplateLocation = sourceDir / "templates" / "bat-template" - val scriptBits = - if (defaultTemplateLocation.exists) JavaAppBatScript.generateScript(replacements, defaultTemplateLocation.toURI.toURL) - else JavaAppBatScript.generateScript(replacements) + val defaultTemplateLocation = sourceDir / "templates" / batTemplate + val defaultTemplateSource = getClass.getResource(batTemplate) + val template = if (defaultTemplateLocation.exists) + defaultTemplateLocation.toURI.toURL + else defaultTemplateSource + + val scriptBits = JavaAppBatScript.generateScript(replacements, template) val script = tmpDir / "tmp" / "bin" / (name + ".bat") IO.write(script, scriptBits) Some(script) diff --git a/src/sbt-test/universal/test-akka/build.sbt b/src/sbt-test/universal/test-akka/build.sbt new file mode 100644 index 000000000..dbf3afefd --- /dev/null +++ b/src/sbt-test/universal/test-akka/build.sbt @@ -0,0 +1,15 @@ +import NativePackagerKeys._ + +packageArchetype.akka_application + +name := """test-akka""" + +mainClass in Compile := Some("HelloKernel") + +version := "1.0" + +libraryDependencies ++= Seq( + "com.typesafe.akka" %% "akka-kernel" % "2.3.4", + "com.typesafe.akka" %% "akka-actor" % "2.3.4", + "com.typesafe.akka" %% "akka-testkit" % "2.3.4" +) diff --git a/src/sbt-test/universal/test-akka/project/plugins.sbt b/src/sbt-test/universal/test-akka/project/plugins.sbt new file mode 100644 index 000000000..b53de154c --- /dev/null +++ b/src/sbt-test/universal/test-akka/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version")) diff --git a/src/sbt-test/universal/test-akka/src/main/scala/HelloKernel.scala b/src/sbt-test/universal/test-akka/src/main/scala/HelloKernel.scala new file mode 100644 index 000000000..5bf2a0691 --- /dev/null +++ b/src/sbt-test/universal/test-akka/src/main/scala/HelloKernel.scala @@ -0,0 +1,32 @@ +import akka.actor.{ Actor, ActorSystem, Props } +import akka.kernel.Bootable + +case object Start + +class HelloActor extends Actor { + val worldActor = context.actorOf(Props[WorldActor]) + + def receive = { + case Start => worldActor ! "Hello" + case message: String => + println("Received message '%s'" format message) + } +} + +class WorldActor extends Actor { + def receive = { + case message: String => sender() ! (message.toUpperCase + " world!") + } +} + +class HelloKernel extends Bootable { + val system = ActorSystem("hellokernel") + + def startup = { + system.actorOf(Props[HelloActor]) ! Start + } + + def shutdown = { + system.shutdown() + } +} \ No newline at end of file diff --git a/src/sbt-test/universal/test-akka/test b/src/sbt-test/universal/test-akka/test new file mode 100644 index 000000000..98905b2d8 --- /dev/null +++ b/src/sbt-test/universal/test-akka/test @@ -0,0 +1,3 @@ +# generate Akka startup script +> stage +$ exists target/universal/stage/bin/test-akka diff --git a/src/sphinx/DetailedTopics/archetypes.rst b/src/sphinx/DetailedTopics/archetypes.rst index 03d224fa3..075a12528 100644 --- a/src/sphinx/DetailedTopics/archetypes.rst +++ b/src/sphinx/DetailedTopics/archetypes.rst @@ -123,6 +123,18 @@ to your packaging for Debian. *Note:* All specified users are **deleted** on an *Note:* It is not a good idea to use **root** as the ``appUser`` for services as it represents a security risk. +Akka Microkernel Application +---------------------------- + +Akka microkerneal application is simlar to a Java Command Line application. Instead to run the ``mainClass``, akka microkernel application need run java with main class ``akka.kernel.Main``. The bash/bat script that starts up a Akka application is copied from Akka distribution. To use this archetype in your build, do the following in your ``build.sbt``: + +.. code-block:: scala + + packageArchetype.akka_application + + name := "A-package-friendly-name" + + mainClass in Compile := Some("HelloKernel") Overriding Templates