Create standalone jar using SBT

I was a heavy Maven user and now I'm gradually using SBT for some of my projects.

I'd like to know how could I use SBT to create a standalone Java project? This project should be packaged as a JAR file and this JAR file would be used as a dependency in another SBT project.

In Maven, I could tell in my pom.xml what type of artifact it should produce when I build it. Is there something similar that I can do in SBT?


Solution 1:

There is a difference between standalone and making a project useable as a dependency or another project. In the first case, you would use a plugin such as sbt-assembly. What it will do is create one jar file containing the project class files along with all of its dependencies. If you write an application, what you get is a double-clickable jar that you can execute from anywhere.

If you want to use your project A as a dependency for another project B, you have different options. You could just package the class files of A, using sbt package (answer of @Channing Walton). Then you could drop the resulting .jar file in the lib directory of project B. However, if A also requires libraries, you must make sure that they also end up in project B's libraries.

A better approach is to publish your project. You can do that purely on your local machine, using sbt publish-local. That will store the jar as produced by package in a special local directory which can be accessed from sbt in another project, along with a POM file that contains the dependencies of A. It will use a group-ID (organization) and artifact-ID (name) and a version of your project A. For example, in build.sbt:

name              := "projecta"

version           := "0.1.0-SNAPSHOT"

organization      := "com.github.myname"

scalaVersion      := "2.10.3"

publishMavenStyle := true

After publishing with sbt publish-local, you can add the following dependency to your project B:

libraryDependencies += "com.github.myname" %% "projecta" % "0.1.0-SNAPSHOT"

If you have a pure Java project, you can omit the Scala version suffix, i.e. in Project A:

crossPaths       := false

autoScalaLibrary := false

And then in Project B:

libraryDependencies += "com.github.myname" % "projecta" % "0.1.0-SNAPSHOT"

(using only one % character between group and artifact ID).

More on publishing in the sbt documentation.

Solution 2:

'sbt package' will produce a jar file.

If you want it to be executable you need to add the following to your .sbt config:

mainClass in Compile := Some("your.main.Class")

Solution 3:

Sure, you can use 'sbt package' command, it creates a jar file but this jar will be without any dependencies. To run it necessary to specify 'classpath' arg to the libraries.

In your case you wish a standalone runnable file. And you need to add the dependencies. To do this you can use 'assembly' plugin for SBT, see https://github.com/sbt/sbt-assembly/

Afterward you can just run 'sbt assembly' command, it provides a fat jar file with all dependencies that you can deploy and run anywhere and at any time.

For details see this article