有没有办法告诉 sbt 将所有需要的库(scala-library.jar)打包到主包中,所以它是独立的?(静止的?)
5 回答
2011 年编辑:
从那时起,retronym(早在 2010 年就在此页面上发布了答案)制作了这个sbt-plugin "sbt-onejar",现在位于GitHub 上的新地址中,并针对 SBT 0.12 更新了文档。
使用 One-JAR™ 打包您的项目</a>
onejar-sbt
是一个简单的构建工具插件,用于构建一个包含所有代码和依赖项作为嵌套 JAR 的单个可执行 JAR。
目前使用的是 One-JAR 版本 0.9.7。这包含在插件中,不需要单独下载。
原答案:
直接而言,如果不扩展 sbt ( “包” sbt action模型之后的自定义操作) ,这是不可能的。
GitHub 提到了一个为码头部署定制的组装任务。不过,您可以根据需要对其进行调整。
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)
}
这需要一些工作,但您也可以在 SBT 中使用Proguard创建一个独立的 JAR。
根据上面@retronym 提供的内容,我构建了一个简单的示例,该示例使用Proguard 和sbt 构建了一个包含Scala 库(即scala-library.jar)的独立jar。谢谢,回溯。
使用文件 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)
}
}
最简单的方法就是从命令行创建 jar。如果您不知道如何执行此操作,我强烈建议您这样做。自动化是有用的,但如果你知道自动化在做什么,它会更好。
自动创建可运行 jar 的最简单方法是在 windows 中使用 bash 脚本或批处理脚本。
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.