A sbt plugin for creating distributable Scala packages.
A sbt plugin for creating distributable Scala packages that include dependent jars and launch scripts.
sbt packcreates a distributable package in
target/packfolder.
target/pack/libfolder. This process is much faster than creating a single-jar as in
sbt-assemblyor
proguardplugins.
sbt packArchivegenerates
tar.gzarchive that is ready to distribute.
target/{project name}-{version}.tar.gz
sbt packgenerates program launch scripts
target/pack/bin/{program name}
.batlaunch scripts for Windows users.
cd target/pack; make install. Then you can run your program with
~/local/bin/{program name}
~/local/{project name}/{project version}).
~/local/{project name}/current
src/packfolder.
target/pack.
Check duplicated classes in dependencies.
Add
sbt-packplugin to your sbt configuration:
project/plugins.sbt
// for sbt-0.13.x, sbt-1.x addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "(version)")
Repository URL: http://repo1.maven.org/maven2/org/xerial/sbt/
build.sbt ``` // [Required] Enable plugin and automatically find def main(args:Array[String]) methods from the classpath enablePlugins(PackPlugin)
// [Optional] Specify main classes manually // This example creates
hellocommand (target/pack/bin/hello) that calls org.mydomain.Hello#main(Array[String]) packMain := Map("hello" -> "org.mydomain.Hello") ```
Now you can use
sbt packcommand in your project.
sbt-pack will generate launcher scripts for calling
def main(args:Array[String]): Unitmethod. You can manually set the
packMainvariable to specify mappings from launcher scripts to their corresponding main classes (for example
packMain := Map("hello" -> "myprog.Hello")) will create
target/pack/bin/helloscript and it will call
myprog.Hellomethod.
If
packMainsetting is missing, sbt-pack will find main classes in your code and generates launcher scripts for them. The main classes must be Scala objects that define
def main(args:Array[])method. The program names will be the main classes names, hyphenized. (For example, main class
myprog.ExampleProggives program name
example-prog.)
build.sbt
// [Required] Enable plugin and automatically find def main(args:Array[String]) methods from the classpath enablePlugins(PackPlugin)name := "myprog" base := file(".")
// [Optional] Specify mappings from program name -> Main class (full package path). If no value is set, it will find main classes automatically packMain := Map("hello" -> "myprog.Hello")
// [Optional] JVM options of scripts (program name -> Seq(JVM option, ...)) packJvmOpts := Map("hello" -> Seq("-Xmx512m"))
// [Optional] Extra class paths to look when launching a program. You can use ${PROG_HOME} to specify the base directory packExtraClasspath := Map("hello" -> Seq("${PROG_HOME}/etc"))
// [Optional] (Generate .bat files for Windows. The default is true) packGenerateWindowsBatFile := true
// [Optional] jar file name format in pack/lib folder // "default" (project name)-(version).jar // "full" (organization name).(project name)-(version).jar // "no-version" (organization name).(project name).jar // "original" (Preserve original jar file names) packJarNameConvention := "default",
// [Optional] Patterns of jar file names to exclude in pack packExcludeJars := Seq("scala-.*\.jar")
// [Optional] Generate a text file containing the list of copied jars. packJarListFile := Some("lib/jars.mf")
// [Optional] List full class paths in the launch scripts (default is false) (since 0.5.1) packExpandedClasspath := false // [Optional] Resource directory mapping to be copied within target/pack. Default is Map("{projectRoot}/src/pack" -> "") packResourceDir += (baseDirectory.value / "web" -> "web-content")
// To publish tar.gz, zip archives to the repository, add the following lines: import xerial.sbt.pack.PackPlugin._ publishPackArchives
// Publish only tar.gz archive. To publish another type of archive, use publishPackArchive(xxx) instead //publishPackArchiveTgz
src/main/scala/Hello.scala
package myprogobject Hello { def main(args:Array[String]) = { println("Hello World!!") } }
Create a package
$ sbt pack
Your program package will be generated in
target/packfolder.
Launch a command
$ target/pack/bin/hello Hello World!!
Install the command
Install the command to
$(HOME)/local/bin:
$ sbt packInstall
or
$ cd target/pack; make install
To launch the command:
$ ~/local/bin/hello Hello World!
Add the following configuration to your .bashprofile, .zshprofile, etc. for the usability:
export PATH=$(HOME)/local/bin:$PATH
Install the command to the system
$ cd target/pack $ sudo make install PREFIX="/usr/local" $ /usr/local/bin/hello Hello World!
Create a tar.gz archive of your Scala program package
$ sbt packArchive
The
packCopyDependenciestask copies all the dependencies to the folder specified through the
packCopyDependenciesTargetsetting.
By default, a symbolic link will be created. By setting
packCopyDependenciesUseSymbolicLinksto
false, the files will be copied instead of symlinking. A symbolic link is faster and uses less disk space.
It can be used e.g. for copying dependencies of a webapp to
WEB-INF/lib
See an example project.
See also examples folder in the source code. It contains several Scala project examples using sbt-pack.
Building a docker image of Scala application becomes easier with sbt-pack:
build.sbt
scala enablePlugins(PackPlugin) name := "myapp" packMain := Map("myapp"->"org.yourdomain.MyApp")
Dockerfile ```
FROM anapsix/alpine-java:8u131b11_jdk
COPY target/pack /srv/myapp
USER nobody WORKDIR /srv/myapp
ENTRYPOINT ["sh", "./bin/myapp"] ```
Then you can build a docker image of your project: ``` $ sbt pack $ docker build -t your_org/myapp:latest .
$ docker run -it --rm your_org/myapp:latest (command line arg...) ```
To test sbt-pack plugin, run
$ ./sbt scripted
Run a single test project, e.g.,
src/sbt-test/sbt-pack/multi-module:
$ ./sbt "scripted sbt-pack/multi-module"
For releasing:
$ ./sbt # cross tests for sbt 0.13 and 1.1 > ^ scripted > ^ publishSigned > sonatypeReleaseAll