A sbt plugin for creating distributable Scala packages that include dependent jars and launch scripts.
sbt pack
creates a distributable package intarget/pack
folder.- All dependent jars including scala-library.jar are collected in
target/pack/lib
folder. This process is much faster than creating a single-jar as insbt-assembly
orproguard
plugins. - Supporting multi-module projects.
- All dependent jars including scala-library.jar are collected in
sbt pack-archive
generatestar.gz
archive that is ready to distribute.- The archive name is
target/{project name}-{version}.tar.gz
- The archive name is
sbt pack
generates program launch scriptstarget/pack/bin/{program name}
- To run the program no need exists to install Scala, since it is included in the lib folder. Only java command needs to be found in the system.
- It also generates
.bat
launch scripts for Windows users.
- Generates a Makefile for program installation.
- Do
cd target/pack; make install
. Then you can run your program with~/local/bin/{program name}
- Do
- You can install multiple versions of your program in the system.
- The above Makefile script uses a separate folder for each version (e.g.,
~/local/{project name}/{project version}
). - The latest version is linked from
~/local/{project name}/current
- The above Makefile script uses a separate folder for each version (e.g.,
- You can add other resources in
src/pack
folder.- All resources in this folder will be copied to
target/pack
.
- All resources in this folder will be copied to
- Check duplicated classes in dependencies.
Add sbt-pack
plugin to your sbt configuration:
project/plugins.sbt
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.7.5") // for sbt-0.13.x or higher
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.2.5") // for sbt-0.12.x (New features will not be supported in this version.)
Repository URL: http://repo1.maven.org/maven2/org/xerial/sbt/
build.sbt
// Automatically find def main(args:Array[String]) methods from classpath
packAutoSettings
or
// If you need to specify main classes manually, use packSettings and packMain
packSettings
// [Optional] Creating `hello` command that calls org.mydomain.Hello#main(Array[String])
packMain := Map("hello" -> "org.mydomain.Hello")
Now you can use sbt pack
command in your project.
Import xerial.sbt.Pack.packAutoSettings
into your project settings (Since version 0.6.2). sbt-pack finds main classes in your code and generates programs for them accordingly. The main classes must be Scala objects that define def main(args:Array[])
method. The program names are the main classes names, hyphenized. (For example, main class myprog.ExampleProg
gives program name example-prog
.)
Alternatively, import xerial.sbt.Pack.packSettings
instead of xerial.sbt.Pack.packAutoSettings
. The main classes in your program will then not be guessed. Manually set the packMain
variable, a mapping from your program names to their corresponding main classes (for example packMain := Map("hello" -> "myprog.Hello")
).
project/Build.scala
import sbt._
import sbt.Keys._
import xerial.sbt.Pack._
object Build extends sbt.Build {
lazy val root = Project(
id = "myprog",
base = file("."),
settings = Defaults.defaultSettings
++ packAutoSettings // This settings add pack and pack-archive commands to sbt
++ Seq(
// [Optional] If you used packSettings instead of packAutoSettings,
// specify mappings from program name -> Main class (full package path)
// packMain := Map("hello" -> "myprog.Hello"),
// Add custom settings here
// [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 value 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] 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 line
// ++ publishPackArchive
// If you need to publish tar.gz (publishArchiveTgz) only, use publishPackArchive(xxx) instead
// ++ publishPackArchiveTgz
)
}
src/main/scala/Hello.scala
package myprog
object Hello {
def main(args:Array[String]) = {
println("Hello World!!")
}
}
Create a package
$ sbt pack
Your program package will be generated in target/pack
folder.
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 .bash_profile, .zsh_profile, 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 packCopyDependencies
task copies all the dependencies to the folder specified through
the packCopyDependenciesTarget
setting.
By default, a symbolic link will be created. By setting packCopyDependenciesUseSymbolicLinks
to 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.
This feature is documented in a separate page
See also examples folder in the source code. It contains several Scala project examples using sbt-pack.
- scala-min: A minimal Scala project using sbt-pack: https://github.com/xerial/scala-min
- A minimal project to start writing Scala programs.
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"