Reputation: 1374
I'm writing a library which depends on code (let's call it foo.jar
) which is only available as a binary jar. As is standard, I'm putting this in the lib/
directory so SBT will treat is as an unmanaged dependency. This is fine so far.
However, since this is a library, I'd like to be able to publish it so that other projects which depend on it to also have access to the unmanaged code in foo.jar
without having to manually locate it. I originally thought I could use a fat jar plugin such as SBT Assembly to create a jar with the dependencies, but that doesn't affect what is actually published using sbt publish-local
– it only creates a fat jar when you run sbt assembly
. Is there some standard simple way to handle this? It seems like a bad idea for every library which uses unmanaged dependencies to break when used by other projects downstream so I wonder if I'm missing something obvious.
Upvotes: 5
Views: 1222
Reputation: 2488
You might be able to get the result you want by manipulating the mappings in (Compile, packageBin)
to include the files you want your packaged jar to have (publish
uses the output from packageBin
). This technique will allow you to include absolutely any file you want within the jar. The official sbt doc is here: http://www.scala-sbt.org/0.12.3/docs/Howto/package.html#contents
As an example, consider the common case of including a .properties file within your jar. Lets say you need to include "messages.properties" under the path "com/bigco/messages.properties" in your packaged jar. And lets say that this file is under src/main/scala/ ... You can add the following to your build.sbt:
mappings in (Compile, packageBin) <+= baseDirectory map { base =>
(base / "src" / "main" / "scala" / "com" / "bigco" / "messages.properties") -> "com/bigco/messages.properties"
}
To attempt to answer your original question, you could unzip foo.jar
and add each one of the class
files within to the packaged jar, according to their correct package paths. So something similar to
mappings in (Compile, packageBin) <+= baseDirectory map { base =>
(base / path / to / unzipped / file.class) -> "path.to.unzipped.file.class"
...
}
Or you might be able to get away with simply including foo.jar
at the root of the packaged jar like so:
mappings in (Compile, packageBin) <+= baseDirectory map { base =>
(base / "lib" / "foo.jar") -> "foo.jar"
}
Upvotes: 2
Reputation: 95624
I don't know if that's a good use of sbt-assembly, since other libraries could depend on a different version of foo.jar
etc.
One way to work around it is to publish foo.jar
in a Maven repository yourself. Some people in Scala and/or sbt community have been talking about bintray. It's still in beta, but looks promising if you want some jars published.
Upvotes: 4