52

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?

Yves M.
  • 29,855
  • 23
  • 108
  • 144
joesan
  • 13,963
  • 27
  • 95
  • 232
  • 4
    Take a look at sbt-onejar: https://github.com/sbt/sbt-onejar. See also [Aggregation and Classpath dependencies](http://www.scala-sbt.org/release/docs/Getting-Started/Multi-Project.html) – FoggyDay Jan 05 '14 at 19:40
  • How do I create a new sbt project using sbt-onejar? For example., with Maven, there is a command line that would generate the project structure for me. Any ideas on how I could do this with sbt and sbt-onejar? – joesan Jan 05 '14 at 19:51
  • If u have lots of dependencies you can also use https://github.com/sbt/sbt-assembly after making some instructions just call `sbt assembly` as for me I use it. – DaunnC Jan 05 '14 at 20:39
  • Would sbt assembly create a project skeleton for me that I can later build as a standalone jar? – joesan Jan 05 '14 at 20:47
  • possible duplicate of [Why doesn't sbt create project files?](http://stackoverflow.com/questions/6395070/why-doesnt-sbt-create-project-files) – Jacek Laskowski Jan 05 '14 at 23:25
  • After the comments of the OP I believe it's a potential duplicate of http://stackoverflow.com/q/6395070/1305344 – Jacek Laskowski Jan 05 '14 at 23:25

5 Answers5

83

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.

0__
  • 66,707
  • 21
  • 171
  • 266
35

'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")
Channing Walton
  • 3,977
  • 1
  • 30
  • 59
  • 2
    Where does the JAR file end up? – Dylan Knowles May 01 '14 at 17:52
  • 6
    its written to target/scala-2.xx/ – Channing Walton May 02 '14 at 20:00
  • 1
    Any idea how to create an executable jar file using that? The last time I checked the jar file created by package command is not executable. – Chetan Bhasin Oct 30 '14 at 16:36
  • I added what you need to make the jar executable – Channing Walton Jul 23 '15 at 21:47
  • 2
    old topic but I recommend this plugin for SBT - https://github.com/sbt/sbt-assembly it is excellent, I also recommend you follow up with java service wrapper - http://wrapper.tanukisoftware.com/doc/english/integrate-jar-nix.html, you can reliably restart, run, monitor you jar executable and integrate this into your CI process. – AntonB Dec 11 '15 at 16:47
8

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

maxmalakhov
  • 81
  • 1
  • 2
6
publishLocal

builds the artifact and publish in the local Ivy repository making it available for your local project dependencies.

publishM2

same as above, but the artifact is published in local Maven repo instead of Ivy repo.

Marco
  • 1,642
  • 3
  • 16
  • 29
2

I think the easiest way to produce a stand-alone jar with your project in it, is sadly not lying inside sbt.

I personally use my IDE: Intellij to make the jar (through the 'build artifact' feature).

Thanks to Intellij I can easily choose which library I want to include in the jar or not, (for instance the scala stl).

IMHO, this is by far the simplest method to get an executable jar for your project.

If you put the scala stl you can run your jar with the "java -jar" command, if you don't you have to run it somewhere with the correct version of scala installed with "scala".

gwenzek
  • 2,816
  • 21
  • 21
  • 1
    That is an option, however, most projects of significant build their artefacts with continuous integration tools like TeamCity, for which you will need something like SBT. – Channing Walton Dec 11 '15 at 17:20
  • Agreed. My use case was a small utility, that I wanted to deploy on remote machine without installing scala – gwenzek Dec 12 '15 at 00:22