tags:

views:

342

answers:

2

Is there a way to tell sbt to package all needed libraries (scala-library.jar) into the main package, so it is stand-alone? (static?)

+6  A: 

Directly, this is not possible without extending sbt (a custom action after the model of the "package" sbt action).

GitHub mentions an assembly task, custom made for jetty deployment. You could adapt it for your need though.

The code is pretty generic (from this post, and user Rio):

 project / build / AssemblyProject.scala

 import sbt._

 trait AssemblyProject extends BasicScalaProject
 {
         def assemblyExclude(base: PathFinder) = base / "META-INF" ** "*"
         def assemblyOutputPath = outputPath / assemblyJarName
         def assemblyJarName = artifactID + "-assembly-" + version + ".jar"
         def assemblyTemporaryPath = outputPath / "assembly-libs"
         def assemblyClasspath = runClasspath
         def assemblyExtraJars = mainDependencies.scalaJars

         def assemblyPaths(tempDir: Path, classpath: PathFinder, extraJars: PathFinder, exclude: PathFinder => PathFinder) =
         {
                 val (libs, directories) = classpath.get.toList.partition(ClasspathUtilities.isArchive)
                 for(jar <- extraJars.get ++ libs) FileUtilities.unzip(jar, tempDir, log).left.foreach(error)
                 val base = (Path.lazyPathFinder(tempDir :: directories) ##)
                 (descendents(base, "*") --- exclude(base)).get
         }

         lazy val assembly = assemblyTask(assemblyTemporaryPath, assemblyClasspath, assemblyExtraJars, assemblyExclude) dependsOn(compile)
         def assemblyTask(tempDir: Path, classpath: PathFinder, extraJars: PathFinder, exclude: PathFinder => PathFinder) =
                 packageTask(Path.lazyPathFinder(assemblyPaths(tempDir, classpath, extraJars, exclude)), assemblyOutputPath, packageOptions)
 }
VonC
It works. But shouldn't it be build in into SBT?
Łukasz Lew
imho it should be. I've successfully used a slightly modified version of this AssemblyProject for a few months now. It will fail on duplicate files (something to watch for if you have a complex project with sub-projects), and will fail with the latest build of hibernate (hibernate includes some weird zip entries that cause it grief).
Michael
+3  A: 

It takes a bit of work, but you can also use Proguard from within SBT to create a standalone JAR.

I did this recently in the SBT build for Scalala.

retronym