Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use sbt native packager with subprojects (sbt 0.13)

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?

like image 234
Dirk Hillbrecht Avatar asked Dec 11 '13 17:12

Dirk Hillbrecht


1 Answers

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.

like image 118
Dirk Hillbrecht Avatar answered Sep 22 '22 00:09

Dirk Hillbrecht