我刚刚偶然发现了sbt-pack插件.开发流似乎很稳定.令我惊讶的是,我认为(引用sbt-pack的标题)"创建可分发的Scala包"的唯一插件.是sbt-assembly(在其他功能中).
插件之间的主要区别是什么?我什么时候应该使用另一个?
Eug*_*ota 68
(免责声明:我维持sbt-assembly)
sbt-assembly创建一个胖JAR - 一个包含代码和库中所有类文件的JAR文件.通过演化,它还包含在多个JAR提供相同文件路径(如config或README文件)时解决冲突的方法.它涉及解压缩所有库JAR,因此它有点慢,但这些都是高度缓存的.
sbt-pack使所有库JAR保持不变,将它们移动到target/pack目录中(而不是通常存在的常春藤缓存),并为您创建一个shell脚本来运行它们.
sbt-native-packager类似于sbt-pack,但它是由一位sbt提交者Josh Suereth创建的,现在由功能强大的Nepomuk Seiler(也称为muuki88)维护.该插件支持多种格式,如Windows msi文件和Debian deb文件.最近增加的是对Docker镜像的支持.
所有这些都是创建部署映像的可行方法.在某些情况下,例如将您的应用程序部署到Web框架等,如果您处理的是一个文件而不是十几个文件,则可能会使事情变得更容易.
荣誉奖:sbt-progard和sbt-onejar.
Jae*_*Lee 12
尽管Eugene Yokota的解释已经完成,但我想在使用方面解释所提到的带有package命令的插件以及如何生成不同的结果.
lazy val commonSettings = Seq(
organization := "stackOverFlow",
scalaVersion := "2.11.12",
version := "1.0",
)
lazy val app = (project in file ("app")).
enablePlugins(PackPlugin).
settings(commonSettings)
Run Code Online (Sandbox Code Playgroud)
上面的build.sbt文件声明了一个名为app的项目,并包含app目录中的所有源文件.要启用Pack插件,enablePlugins(PackPlugin)应该包含在sbt文件中.
另外,我将下面的行放在project/plugins.sbt文件中,以便在我们的项目中使用pack plugins
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.9.3")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
Run Code Online (Sandbox Code Playgroud)
默认情况下,该包已经集成到sbt中,因此您不必使用addSbtPlugins显式指定插件.但是,sbt-pack和sbt-assembly插件默认情况下不包含在sbt中,因此您必须指定要使用它们.addSbtPlugin是一种表达"我想在我的项目中使用xxx,yyy插件"的方式给你的sbt.
另外,我在./app/src/main/scala中实现了两个人为设计的scala文件:
AppBar.scala
class AppBar {
def printDescription() = println(AppBar.getDescription)
}
object AppBar {
private val getDescription: String = "Hello World, I am AppBar"
def main (args: Array[String]): Unit = {
val appBar = new AppBar
appBar.printDescription()
}
}
Run Code Online (Sandbox Code Playgroud)
AppFoo.scala
class AppFoo {
def printDescription() = println(AppFoo.getDescription)
}
object AppFoo {
private val getDescription: String = "Hello World, I am AppFoo"
def main (args: Array[String]): Unit = {
val appFoo = new AppFoo
appFoo.printDescription()
}
}
Run Code Online (Sandbox Code Playgroud)
这是sbt中包含的非常基本的sbt命令,可帮助您通过jar文件分发项目.package命令生成的jar文件位于projectDirectoy/target/scala-2.11/app_2.11-1.0.jar中(这里,build.sbt文件中包含的指定scalaVersion和版本设置键用于生成jar文件名).
当您查看jar时,您可以看到sbt工具生成的类文件,这是编译app/src/main/scala中的源代码的结果.此外,它还包含一个MANIFEST文件.
$vi projectDirectoy/target/scala-2.11/app_2.11-1.0.jar
META-INF/MANIFEST.MF
AppBar$.class
AppBar.class
AppFoo.class
AppFoo$.class
Run Code Online (Sandbox Code Playgroud)
请注意,它仅包含从位于app/src/main/scala目录中的scala文件生成的类文件.package命令生成的jar文件不包含任何scala相关库,例如scala库中的集合(例如,collection.mutable.Map.class).因此,要执行该程序,您可能需要scala库,因为生成jar文件仅包含从我实现的scala源生成的最小类.这就是为什么jar文件包含AppBar.class,AppBar $ .class用于伴随对象等的原因.
正如Eugene Yokota所提到的,sbt-assembly还可以帮助您通过生成jar文件来分发项目; 但是生成的jar文件不仅包括源代码生成的类文件,还包括执行程序所需的所有库.例如,要执行AppFoo对象中定义的main函数,您可能需要scala库.此外,在项目中添加外部库时,可以通过将依赖项添加到libraryDependencies键来包含外部库.
libraryDependencies ++= Seq("org.json4s" %% "json4s-jackson" % "3.5.3")
Run Code Online (Sandbox Code Playgroud)
例如,您可以在项目中包含json4s库,并且与项目中支持json4相关的jar文件也将添加到sbt-assembly生成的最终jar文件中.换句话说,当你在sbt中调用程序集时,它会生成一个包含执行程序所有需求的jar文件,这样你就不需要另外一个依赖来执行你的程序了.
当您在sbt shell中提示汇编命令时,它将在目标目录中生成一个jar文件.在这种情况下,您可以在app/target/scala-2.11目录中找到app-assembly-1.0.jar.当您查看jar文件时,您会发现它包含许多类.
$vi projectDirectoy/target/scala-2.11/app_2.11-1.0.jar
ETA-INF/MANIFEST.MF
scala/
scala/annotation/
scala/annotation/meta/
scala/annotation/unchecked/
scala/beans/
scala/collection/
scala/collection/concurrent/
scala/collection/convert/
scala/collection/generic/
scala/collection/immutable/
scala/collection/mutable/
scala/collection/parallel/
scala/collection/parallel/immutable/
scala/collection/parallel/mutable/
scala/collection/script/
scala/compat/
scala/concurrent/
scala/concurrent/duration/
scala/concurrent/forkjoin/
scala/concurrent/impl/
scala/concurrent/util/
scala/io/
scala/math/
scala/ref/
scala/reflect/
scala/reflect/macros/
scala/reflect/macros/internal/
scala/runtime/
scala/sys/
scala/sys/process/
scala/text/
scala/util/
scala/util/control/
scala/util/hashing/
scala/util/matching/
AppBar$.class
AppBar.class
AppFoo$.class
AppFoo.class
......
Run Code Online (Sandbox Code Playgroud)
如前所述,由于程序集生成的jar文件包含所有依赖项(如scala和外部库)以在jar中执行程序,因此您可能认为可以调用AppFoo对象和AppBar对象中定义的主要函数.
jaehyuk@ubuntu:~/work/sbt/app/target/scala-2.11$ java -cp './*' AppFoo
Hello World, I am AppFoo
jaehyuk@ubuntu:~/work/sbt/app/target/scala-2.11$ java -cp './*' AppBar
Hello World, I am AppBar
Run Code Online (Sandbox Code Playgroud)
是的〜你可以使用生成的jar文件执行main函数.
sbt-pack与sbt-assembly几乎相同; 它将项目所依赖的所有库保存为执行程序所需的jar文件.但是,sbt-pack没有将所有依赖项集成到一个jar文件中,而是生成多个jar文件,这些文件对应于一个库依赖项和您的类(例如,AppFoo.class).
另外,有趣的是它会自动生成脚本,用于调用scala源文件和Makefile中定义的所有主要函数来安装程序.让我们看一下在sbt shell上提示打包命令后创建的pack目录.
jaehyuk@ubuntu:~/work/sbt/app/target/pack$ ls
bin lib Makefile VERSION
jaehyuk@ubuntu:~/work/sbt/app/target/pack$ ls bin/
app-bar app-bar.bat app-foo app-foo.bat
jaehyuk@ubuntu:~/work/sbt/app/target/pack$ ls lib/
app_2.11-1.0.jar sbt_2.12-0.1.0-SNAPSHOT.jar scala-library-2.11.12.jar
jaehyuk@ubuntu:~/work/sbt/app/target/pack$
Run Code Online (Sandbox Code Playgroud)
如上所示,创建了两个目录和两个文件; bin包含执行源中定义的函数的所有脚本文件(每个文件都是一个脚本,可以帮助您执行scala文件中定义的main方法); lib包含执行程序所需的所有jar文件; 最后,Makefile可用于在系统中安装程序和依赖库.
有关详细信息,请参阅每个插件的github页面.
| 归档时间: |
|
| 查看次数: |
14553 次 |
| 最近记录: |