使用SBT创建独立的Jar包

52

我曾是 Maven 的重度用户,现在逐渐将其应用于我的一些项目中。

我想知道如何使用 SBT 创建一个独立的 Java 项目?这个项目应该被打包成一个 JAR 文件,并且这个 JAR 文件将被用作另一个 SBT 项目的依赖。

在 Maven 中,我可以在我的 pom.xml 中告诉它在构建时应该生成什么类型的 artifact。在 SBT 中是否有类似的功能?


4
请查看sbt-onejar:https://github.com/sbt/sbt-onejar。还可以参考“聚合和类路径依赖项”(http://www.scala-sbt.org/release/docs/Getting-Started/Multi-Project.html)。 - FoggyDay
我该如何使用sbt-onejar创建一个新的sbt项目呢?例如,使用Maven时,有一条命令行可以为我生成项目结构。您有任何关于如何使用sbt和sbt-onejar实现这一点的想法吗? - joesan
如果您有很多依赖项,您也可以使用 https://github.com/sbt/sbt-assembly,在执行一些指令后,只需调用`sbt assembly`即可。对我来说,我也使用它。 - DaunnC
sbt assembly 会为我创建一个项目框架,以便我稍后可以构建成独立的 jar 包吗? - joesan
可能是为什么sbt不创建项目文件?的重复问题。 - Jacek Laskowski
根据楼主的评论,我认为这可能是https://dev59.com/eWw15IYBdhLWcg3wy-zO的重复问题。 - Jacek Laskowski
5个回答

83

独立运行和将项目作为依赖项或另一个项目使用有所不同。在第一种情况下,您可以使用像sbt-assembly这样的插件。它会创建一个包含项目类文件及其所有依赖项的单个JAR文件。如果您编写应用程序,您将获得一个可双击执行的JAR文件,可以从任何地方执行。

如果您想将项目A用作另一个项目B的依赖项,则有不同的选项。您可以使用sbt package(回答者@Channing Walton的答案)打包A的类文件。然后,您可以将生成的.jar文件放入项目B的lib目录中。但是,如果A还需要库,则必须确保它们也出现在项目B的库中。

更好的方法是发布您的项目。您可以在本地机器上纯粹地做到这一点,使用sbt publish-local。这将把由package生成的JAR存储在特殊的本地目录中,可以从另一个项目的sbt中访问,以及包含A的依赖项的POM文件。它将使用组ID(组织)、artifact-ID(名称)和您的项目A的版本。例如,在build.sbt中:

name              := "projecta"

version           := "0.1.0-SNAPSHOT"

organization      := "com.github.myname"

scalaVersion      := "2.10.3"

publishMavenStyle := true

在使用 sbt publish-local 发布后,您可以将以下依赖项添加到项目 B 中:
libraryDependencies += "com.github.myname" %% "projecta" % "0.1.0-SNAPSHOT"

如果您有一个纯Java项目,可以省略Scala版本后缀,例如在A项目中:

crossPaths       := false

autoScalaLibrary := false

然后在 B 项目中:

libraryDependencies += "com.github.myname" % "projecta" % "0.1.0-SNAPSHOT"

(在group ID和artifact ID之间仅使用一个%字符)。

更多发布信息请参见sbt文档


35
'

'sbt package'将生成一个jar文件。

如果您想要使其可执行,则需要将以下内容添加到您的.sbt配置文件中:

'
mainClass in Compile := Some("your.main.Class")

2
JAR文件最终会被放置在哪里? - Dylan Knowles
6
它被写入到target/scala-2.xx/。 - Channing Walton
1
有没有想法如何使用它创建可执行的jar文件?上次我检查package命令创建的jar文件是不可执行的。 - Chetan Bhasin
我添加了你需要的内容以使JAR文件可执行。 - Channing Walton
2
这可能是一个老话题,但我强烈推荐使用这个插件来构建SBT项目 - https://github.com/sbt/sbt-assembly。它非常出色!另外,我还推荐你跟进一下Java Service Wrapper - http://wrapper.tanukisoftware.com/doc/english/integrate-jar-nix.html,你可以通过它可靠地重新启动、运行和监控你的JAR可执行文件,并将其整合到你的CI流程中。 - AntonB

8
当然,您可以使用“sbt package”命令,它会创建一个jar文件,但是这个jar没有任何依赖项。要运行它,需要指定“classpath”参数到库文件。
在您的情况下,您希望有一个独立可运行的文件。您需要添加依赖项。为此,您可以使用SBT的“assembly”插件,请参见https://github.com/sbt/sbt-assembly/ 之后,您只需运行“sbt assembly”命令,它将提供一个包含所有依赖项的fat jar文件,您可以在任何地方随时部署和运行。
详情请参阅article

2
文章链接已失效。 - Thilo

6
publishLocal

构建工件并发布到本地Ivy存储库中,以使其可用于本地项目依赖项。
publishM2

与上述相同,不同之处在于构件发布到本地Maven仓库而不是Ivy仓库。


2

我认为最简单的方法是使用IDE(如Intellij)生成包含项目的独立jar文件,而不是使用sbt。

我个人使用Intellij的“构建工件”功能来制作jar文件。通过Intellij,我可以轻松选择要包含在jar文件中的库(例如scala stl)。

在我看来,这是获得可执行jar文件的最简单方法。

如果你将scala stl放入jar文件中,你可以使用“java -jar”命令运行它;否则,你需要在安装了正确版本的scala的某个地方运行它。


1
那是一个选项,然而大多数重要的项目都使用像TeamCity这样的持续集成工具构建它们的构件,对此你将需要像SBT这样的东西。 - Channing Walton
同意。我的使用情况是一个小型实用程序,我想在远程机器上部署它,而不必安装Scala。 - gwenzek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接