Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple executable jar files with different external dependencies from a single project with sbt-assembly

Tags:

I have a single scala project built with sbt using a build.scala file. I can use sbt-assembly to generate a single executable jar file from this project without problem. Now I want to generate multiple executable jar files, where each file includes a common set of internal and external base dependencies along with different external dependencies.

Is this possible with the current version of sbt-assembly? In maven this is easy, as one can define multiple profiles in the pom, each generating a separate jar, but in sbt-assembly you pass the assembly settings to your project and I haven't figured out a way to modify the settings to generate multiple jar files.

like image 997
Oscar Täckström Avatar asked Sep 04 '13 10:09

Oscar Täckström


1 Answers

The concept of Maven profile translates in sbt/Ivy as configuration. You can define settings within a configuration and have sbt-assembly generate two jars. You can add libraryDependency to a specific configuration by adding % "config". This, however requires the project to be aware of the configuration(s) upfront.

In build.sbt (requires sbt 0.13.0 or above):

import AssemblyKeys._  val Dispatch10 = config("dispatch10") extend(Compile) val TestDispatch10 = config("testdispatch10") extend(Test) val Dispatch11 = config("dispatch11") extend(Compile) val TestDispatch11 = config("testdispatch11") extend(Test)  val root = project.in(file(".")).   configs(Dispatch10, TestDispatch10, Dispatch11, TestDispatch11).   settings(      name := "helloworld",     organization := "com.eed3si9n",     scalaVersion := "2.10.2",     compile in Test := inc.Analysis.Empty,     compile in Compile := inc.Analysis.Empty,     libraryDependencies ++= Seq(       "net.databinder.dispatch" %% "dispatch-core" % "0.10.0" % "dispatch10,testdispatch10",        "net.databinder.dispatch" %% "dispatch-core" % "0.11.0" % "dispatch11,testdispatch11",       "org.specs2" %% "specs2" % "2.2" % "test",       "com.github.scopt" %% "scopt" % "3.0.0"     )   ).   settings(inConfig(Dispatch10)(Classpaths.configSettings ++ Defaults.configTasks ++ baseAssemblySettings ++ Seq(     test := (test in TestDispatch10).value,     test in assembly := test.value,     assemblyDirectory in assembly := cacheDirectory.value / "assembly-dispatch10",     jarName in assembly := name.value + "-assembly-dispatch10_" + version.value + ".jar"   )): _*).   settings(inConfig(TestDispatch10)(Classpaths.configSettings ++ Defaults.configTasks ++ Defaults.testTasks ++ Seq(     internalDependencyClasspath := Seq((classDirectory in Dispatch10).value).classpath   )): _*).   settings(inConfig(Dispatch11)(Classpaths.configSettings ++ Defaults.configTasks ++ baseAssemblySettings ++ Seq(     test := (test in TestDispatch11).value,     test in assembly := test.value,     assemblyDirectory in assembly := cacheDirectory.value / "assembly-dispatch11",     jarName in assembly := name.value + "-assembly-dispatch11_" + version.value + ".jar"   )): _*).   settings(inConfig(TestDispatch11)(Classpaths.configSettings ++ Defaults.configTasks ++ Defaults.testTasks ++ Seq(     internalDependencyClasspath := Seq((classDirectory in Dispatch11).value).classpath   )): _*) 

To run assembly task within the configuration, you'd say:

> dispatch11:assembly [info] HelloWorldSpec [info]  [info] The 'Hello world' string should [info] + contain 11 characters [info]  [info] Total for specification HelloWorldSpec [info] Finished in 17 ms [info] 1 examples, 0 failure, 0 error [info] Passed: Total 1, Failed 0, Errors 0, Passed 4 [info] Including: scopt_2.10-3.0.0.jar [info] Including: slf4j-api-1.6.2.jar [info] Including: netty-3.6.3.Final.jar [info] Including: scala-library.jar [info] Including: async-http-client-1.7.16.jar [info] Including: dispatch-core_2.10-0.11.0.jar [warn] Merging 'META-INF/NOTICE.txt' with strategy 'rename' [warn] Merging 'META-INF/license' with strategy 'rename' [warn] Merging 'META-INF/LICENSE.txt' with strategy 'rename' [warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard' [warn] Strategy 'discard' was applied to a file [warn] Strategy 'rename' was applied to 3 files [info] Checking every *.class/*.jar file's SHA-1. [info] SHA-1: xxxxxxxxxxxx [info] Packaging /Users/foo/helloworld/target/scala-2.10/helloworld-assembly-dispatch11_0.1-SNAPSHOT.jar ... [info] Done packaging. 
like image 164
Eugene Yokota Avatar answered Sep 25 '22 09:09

Eugene Yokota