scala 使用 Simple Build Tool 制作独立 jar
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2887655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making stand-alone jar with Simple Build Tool
提问by ?ukasz Lew
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?)
有没有办法告诉 sbt 将所有需要的库(scala-library.jar)打包到主包中,所以它是独立的?(静止的?)
采纳答案by VonC
Edit 2011:
Since then, retronym(which posted an answer in this page back in 2010), made this sbt-plugin "sbt-onejar", now in its new address on GitHub, with docs updated for SBT 0.12.
2011 年编辑:
从那时起,retronym(在 2010 年在此页面中发布了一个答案)制作了这个sbt-plugin "sbt-onejar",现在在GitHub 上的新地址中,并为 SBT 0.12 更新了文档。
Packages your project using One-JAR?
onejar-sbtis a simple-build-tool plugin for building a single executable JAR containing all your code and dependencies as nested JARs.
Currently One-JAR version 0.9.7 is used. This is included with the plugin, and need not be separately downloaded.
onejar-sbt是一个简单的构建工具插件,用于构建单个可执行 JAR,其中包含作为嵌套 JAR 的所有代码和依赖项。
当前使用 One-JAR 版本 0.9.7。这是包含在插件中的,不需要单独下载。
Original answer:
原答案:
Directly, this is not possible without extending sbt (a custom actionafter the model of the "package" sbt action).
直接地,如果不扩展 sbt(“包” sbt 操作模型之后的自定义操作),这是不可能的。
GitHub mentions an assembly task, custom made for jetty deployment. You could adapt it for your need though.
GitHub 提到了一个为 jetty 部署定制的组装任务。不过,您可以根据自己的需要调整它。
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)
}
回答by retronym
回答by Leif Wickland
Working off of what @retronym offered above, I built a simple examplethat builds a stand alone jar which includes the Scala libraries (i.e. scala-library.jar) using Proguard with sbt. Thanks, retronym.
根据上面@retronym 提供的内容,我构建了一个简单的示例,该示例构建了一个独立的 jar,其中包含使用 Proguard 和 sbt 的 Scala 库(即 scala-library.jar)。谢谢,回名。
回答by Arkadiusz Bicz
The simplest example using sbt-assembly
使用sbt-assembly的最简单示例
Create directory project in your home project dir with file assembly.sbt including
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
In file build.sbt
import AssemblyKeys._ // put this at the top of the file
assemblySettings
jarName += "Mmyjarnameall.jar"
libraryDependencies ++= Seq( "exmpleofmydependency % "mydep" % "0.1" )
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case s if s.endsWith(".class") => MergeStrategy.last
case s if s.endsWith("pom.xml") => MergeStrategy.last
case s if s.endsWith("pom.properties") => MergeStrategy.last
case x => old(x)
}
}
使用文件 assembly.sbt 在您的主项目目录中创建目录项目,包括
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
在文件 build.sbt
import AssemblyKeys._ // 把它放在文件的顶部
装配设置
jarName += "Mmyjarnameall.jar"
libraryDependencies ++= Seq( "exmpleofmydependency % "mydep" % "0.1" )
程序集中的合并策略<<=(程序集中的合并策略){(旧)=>
{
case s if s.endsWith(".class") => MergeStrategy.last
case s if s.endsWith("pom.xml") => MergeStrategy.last
case s if s.endsWith("pom.properties") => MergeStrategy.last
案例 x => 旧(x)
}
}
回答by Rich Oliver
The simplest method is just to create the jar from the command line. If you don't know how to do this I would highly recommend that you do so. Automation is useful, but its much better if you know what the automation is doing.
最简单的方法是从命令行创建 jar。如果您不知道如何执行此操作,我强烈建议您这样做。自动化很有用,但如果您知道自动化在做什么,那就更好了。
The easiest way to automate the creation of a runnable jar is to use a bash script or batch script in windows.
自动创建可运行 jar 的最简单方法是在 Windows 中使用 bash 脚本或批处理脚本。
The simplest way in sbt is just to add the Scala libraries you need to the resource directories:
sbt 中最简单的方法就是将你需要的 Scala 库添加到资源目录中:
unmanagedResourceDirectories in Compile := Seq(file("/sdat/bins/ScalaCurrent/lib/scalaClasses"))
So in my environment ScalaCurrent is a link to the current Scala library. 2.11.4 at the time of writing. The key point is that I extract the Scala library but place it inside a ScalaClassses directory. Each extracted library needs to go into its top level directory.
所以在我的环境中 ScalaCurrent 是当前 Scala 库的链接。2.11.4 在撰写本文时。关键是我提取了 Scala 库,但将其放在 ScalaClassses 目录中。每个提取的库都需要进入其顶级目录。

