I have an sbt project with a multitude of subprojects and external library dependencies. build.sbt
goes like this:
val extlib1 = "xy.xxx" % "lib1" % "1.0+"
val extlib2 = "xy.yyy" % "lib2" % "1.0+"
val extlib3 = "xy.zzz" % "lib3" % "1.0+"
lazy val core=project settings (
name:="cor",
libraryDependencies++=Seq(extlib1)
)
lazy val servercore=project settings (
name:="srvcore",
libraryDependencies++=Seq(extlib1,extlib2)
) dependsOn(core)
lazy val masterserver=project settings (
name:="mastersrv",
mainClass:=Some("masterserver")
) dependsOn(servercore)
lazy val otherserver=project settings (
name:="othersrv",
libraryDependencies++=Seq(extlib3),
mainClass:=Some("otherserver")
) dependsOn(servercore)
// Only for aggregating the builds of the subprojects
lazy val root=project in file(".") settings(name:="proj") aggregate(
core,servercore,masterserver,otherserver
)
So actually the project creates several programs ("masterserver", "otherserver") which depend on external libraries and a subset of the subprojects of this project itself.
What I want to have is a complete set of JARs needed to start the master server or the other server, seperated for each. So, I'd like to have e.g. masterserver/target/<whatever>
containing
mastersrv.jar
srvcore.jar (needed by mastersrv.jar)
cor.jar (needed by srvcore.jar)
lib1.jar (needed by mastersrv and srvcore)
lib2.jar (needed by srvcore)
<whatever>.jar (further libs needed by lib1 or lib2)
and a otherserver/target/<whatever>
with similar content (it would have to add lib3.jar
also, as that is needed by othersrv.jar
.
How to do that? Can I perform this with the native packager? Issuing stage
in the root project does nothing (because there is no mailClass
?). Issuing masterserver/state
gives an error message
> masterserver/stage
[error] No such setting/task
[error] masterserver/stage
[error] ^
I must admit that I do not get a real clue out of the native packager plugin documentation. How can I archive what I want to have?
Edit: Of course, I am not bound to the directory stuff. If I get multiple ZIP files in the main target
directory, it's o.k., too. I only want to have all dependencies of a subproject at one location.
Edit 2: Ok, I learned that the Play! framework does exactly what I want. And it uses the sbt native packager for it. How can I archieve a recursive universal packaging of subprojects in non-Play sbt-handled projects which use Java as programming language?
Well, the answer was quite straight-forward once I tested a bit around. First, put the native packager in the project-global project/plugins.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.6.4")
Then, put the configuration for the native packager in the build.sbt
in the subproject. In the example above, put the following into masterserver/build.sbt
:
// Setup the packager
packageArchetype.java_application
// Enable JAR export for staging
exportJars := true
The set of needed JAR files will be put into the subproject's target
directory, in this example into masterserver/target/universal/stage/lib
The rest of the subproject's configuration can stay in the global build.sbt
, but I found no way of configuring the native packager that way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With