• Stars
    star
    496
  • Rank 88,807 (Top 2 %)
  • Language
    Scala
  • Created about 12 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A sbt plugin for creating distributable Scala packages.

sbt-pack plugin Maven Central

A sbt plugin for creating distributable Scala packages that include dependent jars and launch scripts.

Features

  • sbt pack creates a distributable package in target/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 in sbt-assembly or proguard plugins.
    • Supporting multi-module projects.
    • Useful for creating runnable Docker images of Scala programs
  • sbt packArchive generates tar.gz archive that is ready to distribute.
    • The archive name is target/{project name}-{version}.tar.gz
  • sbt pack generates program launch scripts target/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}
  • 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
  • You can add other resources in src/pack folder.
    • All resources in this folder will be copied to target/pack.
  • Check duplicated classes in dependencies.

Usage

Add sbt-pack plugin to your sbt configuration:

project/plugins.sbt

Maven Central

// for sbt-0.13.x, sbt-1.x
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "(version)")  

Repository URL: https://repo1.maven.org/maven2/org/xerial/sbt/

Minimum configuration

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 `hello` command (target/pack/bin/hello) that calls org.mydomain.Hello#main(Array[String]) 
packMain := Map("hello" -> "org.mydomain.Hello")

Now you can use sbt pack command in your project.

Full build configuration

sbt-pack will generate launcher scripts for calling def main(args:Array[String]): Unit method. You can manually set the packMain variable to specify mappings from launcher scripts to their corresponding main classes (for example packMain := Map("hello" -> "myprog.Hello")) will create target/pack/bin/hello script and it will call myprog.Hello method.

If packMain setting 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.ExampleProg gives 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")

// [Optional] Environment variables
packEnvVars := Map("hello" -> Map("key1" -> "value1", "key2" -> "value2"))

// 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

// [Optional] Set a root folder name of archive contents. (defualt is (project-name)-(version). Setting this to an empty string is useful for packaging projects for AWS lambda. 
packArchiveStem := ""

src/main/scala/Hello.scala

package myprog
    
object Hello {
  def main(args:Array[String]) = {
    println("Hello World!!")
  }
}

Command Examples

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

Copy dependencies

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.

Example projects

See also examples folder in the source code. It contains several Scala project examples using sbt-pack.

Use case

Building A Docker image file with sbt-pack

Building a docker image of Scala application becomes easier with sbt-pack:

build.sbt

enablePlugins(PackPlugin)
name := "myapp"
packMain := Map("myapp"->"org.yourdomain.MyApp")

Dockerfile

# Using JDK17 from Amazon Corretto
FROM amazoncorretto:17

COPY target/pack /srv/myapp

# Using a non-privileged user:
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 .


# Run your application with Docker
$ docker run -it --rm your_org/myapp:latest (command line arg...)

For developers

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
> scripted
> publishSigned
> sonatypeBundleRelease

More Repositories

1

sqlite-jdbc

SQLite JDBC Driver
Java
2,828
star
2

snappy-java

Snappy compressor/decompressor for Java
Java
1,035
star
3

larray

Large off-heap arrays and mmap files for Scala and Java
Scala
400
star
4

sbt-sonatype

A sbt plugin for publishing Scala/Java projects to the Maven central.
Scala
335
star
5

streamdb-readings

Readings in Stream Processing
120
star
6

silk

Simplify SQL Workflows with Scala
CSS
38
star
7

scala-cookbook

Tutorial of the Scala Programming Language
CSS
29
star
8

sbt-sql

A sbt plugin for generating useful Scala case classes from SQL files
Scala
29
star
9

presto-metrics

Presto metric collection library for Ruby
Ruby
26
star
10

xerial

Data management utilities for Scala
Scala
19
star
11

jnuma

A Java library for accessing NUMA (Non Uniform Memory Access) API
C
17
star
12

dp-readings

Readings in Differential Privacy
14
star
13

scala-min

A minimal project template to start programming with Scala
Shell
13
star
14

sbt-jcheckstyle

A sbt plugin for checking Java code styles
Shell
6
star
15

chroniker

Simplify your batch job pipelines with Scala
Scala
4
star
16

fluentd-standalone

Standalone fluentd server for Java/Scala
Shell
4
star
17

genome-weaver-align

Toolkit for genome sciences
Java
3
star
18

xerial-java

Xerial library for Java
Java
3
star
19

scalajs-selenium

Scala.js + Selenium setup example
Shell
1
star
20

msgframe

A framework for SQL-based message processing sql
Scala
1
star
21

xerial.github.com

Xerial Web Site
HTML
1
star
22

zstd-java

Zstandard (zstd) compressor/decompressor for Java
Makefile
1
star
23

scala-steward-repos

My repository list maintained with Scala Steward
1
star