w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
Bundle dependency jars into output jar

This is how you could achieve what you want with pure SBT 0.13.x (the example should work for older versions in general, but maybe you'd have to use different operators).

build.sbt

import Path.flat

libraryDependencies ++= Seq(
  "com.fasterxml.jackson.core" % "jackson-core" % "2.3.1",
  "com.netflix.rxjava" % "rxjava-core" % "0.16.1"
  // maybe more dpendencies
)

packageOptions in (Compile, packageBin) +=
        Package.ManifestAttributes("PluginMainClass" ->
"com.xxx.xxx.Class")

// this will copy all managed jars to the ./lib in your jar
mappings in (Compile, packageBin) ++= {
  val cp = (managedClasspath in Compile).value.files
  cp pair flatRebase("/lib")
}

// this will move all your compiled classes to folder ./com.xxx.xxx in your
jar
mappings in (Compile, packageBin) ++= {
  val compiledClasses = (products in Compile).value ** "*.class"
  val classDirectoryBase = (classDirectory in Compile).value
  compiledClasses pair rebase(classDirectoryBase, "com.xxx.xxx")
}

You can then use package to build the jar. In the example as above the jar will look like this:

  Length      Date    Time    Name
---------  ---------- -----   ----
      301  2014-05-09 20:13   META-INF/MANIFEST.MF
        0  2014-05-09 20:13   /lib/
  7126003  2013-09-27 11:44   /lib/scala-library.jar
   197986  2013-12-28 02:01   /lib/jackson-core-2.3.1.jar
   663553  2014-01-15 08:17   /lib/rxjava-core-0.16.1.jar
---------                     -------
  7987843                     5 files

And the manifest will look like this

Manifest-Version: 1.0
Implementation-Vendor: default
Implementation-Title: q-23553321
Implementation-Version: 0.1-SNAPSHOT
Implementation-Vendor-Id: default
PluginMainClass: com.xxx.xxx.Class // MAIN CLASS OF THE PLUGIN
Specification-Vendor: default
Specification-Title: q-23553321
Specification-Version: 0.1-SNAPSHOT

Edit

Is it possible to get the compiled classes in a multi module build though? IE if I have /modules/X,Y,Z and I want the compiled classes from those projects bundled under "com.xxx.xxx" in the artifact?

The general answer is yes, if the classes are unique. To do that you can use Scopes. In the build.sbt, replace the mappings for classes with the following:

// define the configuration axis
val anyProjectsCompile = ScopeFilter(inAnyProject,
inConfigurations(Compile))

// we want to have class directory and products together to use rebase in
the next step
val classDirectoryProducts = Def.task {
  (classDirectory.value, products.value)
}

mappings in (Compile, packageBin) ++= {
  classDirectoryProducts.all(anyProjectsCompile).value.flatMap { case
(classDir, prods) =>
    val compiledClasses = (prods ** "*.class").get
    compiledClasses pair rebase(classDir, "com.xxx.xxx")
  }
}




© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.