42

My project has dependency on an external jar. I have created a directory lib and have copied the jar file into it. This is my build.sbt:

name := "approxstrmatch"

version := "1.0"

scalaVersion := "2.10.4"

unmanagedJars in Compile += file("lib/secondstring-20140729.jar")

libraryDependencies+="org.apache.spark"%%"spark-core"%"1.0.0"

resolvers += "AkkaRepository" at "http://repo.akka.io/releases/"

When I run clean and package, the external jar file does not get included in the generated jar file. Why?

This is the project layout:

project/build.sbt
lib/
src/.....
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
user3803714
  • 5,269
  • 10
  • 42
  • 61

7 Answers7

44

Try this

libraryDependencies += "com.acme.common" % "commonclass" % "1.0" from "file:///Users/bwong/git/perf-tools/commonclass/target/scala-2.11/commonclass_2.11-1.0.jar"

I "sbt package" the common classproject and then just add that library dependency in my build.sbt in the dependent projects.

Thanks to http://flummox-engineering.blogspot.com/2014/06/sbt-use-jar-file-for-librarydependencies.html for this hack.

Bernie Wong
  • 681
  • 5
  • 13
38

First of all, there is no need to specify unmanagedJars explicitly unless you have more complex configuration. Simply put your JAR files into the lib directory and they will be added to the classpath (docs).

To package an executable JAR with all the necessary dependencies use one of the SBT plugins: sbt-onejar or sbt-assembly. package simply packages your classes into a jar and doesn't bother with including dependencies whatsoever.

The instructions in the docs of the plugins should be easy to guide you how to use them.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
yǝsʞǝla
  • 16,272
  • 2
  • 44
  • 65
  • Thank you for your answer! Do you know how may I add only specified JAR file(s) to the target JAR file (not ALL dependent ones)? – MaxU - stand with Ukraine Jan 14 '19 at 19:07
  • 1
    @MaxU if you use sbt assembly you can exclude files as described here: https://github.com/sbt/sbt-assembly#assemblyexcludedjars. Example: `assemblyExcludedJars in assembly := { val cp = (fullClasspath in assembly).value cp filter {_.data.getName == "compile-0.1.0.jar"} }` – yǝsʞǝla Jan 15 '19 at 06:19
  • 1
    Thanks a lot! I believe this nice example should be part of your valuable answer ;) – MaxU - stand with Ukraine Jan 15 '19 at 06:24
21

The trick is to figure out which lib directory to put your JAR in. You can do this by running the following in your sbt console: show unmanagedBase.

If you don't see your project there, you can run show YOURPROJECT/unmanagedBase to find the correct lib path.

png
  • 5,990
  • 2
  • 25
  • 16
3

Add this line to your build.sbt and clean & compile your project.

project/libs, where the project is the root directory of your project, put your jars in the libs folder.

unmanagedBase := baseDirectory.value / "libs"
Mohit Gupta
  • 33
  • 1
  • 5
Sivailango
  • 544
  • 1
  • 6
  • 15
2

I was racking my brain with resolvers and settingKey vars, but it seems this is the most straight-forward way (https://www.scala-sbt.org/release/docs/Library-Dependencies.html):

resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"

then just add to libraryDependencies as you normally would

libraryDependencies += "<group>" % "<artifact>" % "<version>"

esca2791
  • 41
  • 4
1

tl;dr Move project/build.sbt one level up where lib directory is and use sbt-assembly plugin (as described in the other answer by Aleksey).

If the project directory layout is as you use for your project, it's incorrect since build.sbt does not belong to the same build where lib does.

Since sbt is recursive this project/build.sbt describes the project's build that governs the main one. Quoting the docs:

The project directory is another project inside your project which knows how to build your project. The project inside project can (in theory) do anything any other project can do. Your build definition is an sbt project.

And the turtles go all the way down. If you like, you can tweak the build definition of the build definition project, by creating a project/project/ directory.

Community
  • 1
  • 1
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
0

one of the solutions is, when you build that jar in sbt, do sbt publish-local

Vlad Patryshev
  • 1,379
  • 1
  • 10
  • 16
  • 1
    this is my preferred approach too, easier than copying files around; reference here: http://www.scala-sbt.org/0.13/docs/Publishing.html – kmh May 17 '17 at 17:43