sbt 启动器提供两个部分
sbt 启动器组件是一个自包含的 jar,它可以在系统上没有 Scala 或应用程序的情况下启动 Scala 应用程序或服务器。唯一的前提条件是启动器 jar 本身、一个可选的配置文件和 Java 运行时版本 1.6 或更高版本。
用户下载启动器 jar 并创建一个脚本以运行它。在本文档中,将假定脚本名为 launch
。对于 Unix,脚本看起来像这样:java -jar sbt-launcher.jar "$@"
用户现在可以启动提供 sbt 启动器配置的服务器和应用程序。
或者,您可以将启动器与启动器配置文件重新打包。例如,sbt/sbt 拉取原始 JAR 并 为 sbt 注入相应的 boot.properties 文件.
要启动应用程序,用户然后下载应用程序的配置文件(称为 my.app.configuration
)并创建一个脚本以启动它(称为 myapp
)
launch @my.app.configuration "$@"
用户然后可以使用 myapp arg1 arg2 ...
启动应用程序。
有关启动器配置的更多信息,请参见 启动器配置
sbt 启动器可用于启动和发现系统上正在运行的服务器。启动器可以用来启动服务器,类似于应用程序。但是,如果需要,启动器也可以用来确保一次只有一个服务器实例正在运行。这是通过让客户端始终使用启动器作为服务定位器来实现的。
要发现服务器在哪里运行(或者如果它没有运行则启动它),用户下载服务器的配置文件(称为 my.server.configuration
)并创建一个脚本以发现服务器(称为 find-myserver
)
launch --locate @my.server.properties.
此命令将打印出一行字符串,即用于访问服务器的 URI,例如 sbt://127.0.0.1:65501
。客户端应使用 IP/端口连接到服务器并启动其连接。
在使用 locate
功能时,sbt 启动器对服务器做出了以下限制
xsbti.ServerMain
类与用于分发 sbt
的启动器一样,下载的启动器 jar 将根据提供的配置文件检索 Scala 和应用程序。版本可以是固定的,也可以从另一个配置文件中读取(其位置也是可配置的)。Scala 和应用程序 jar 下载到的位置也是可配置的。搜索的仓库是可配置的。启动时可选地初始化属性文件是可配置的。
启动器下载完必要的 jar 后,它将加载应用程序/服务器并调用其入口点。应用程序将接收有关其调用方式的信息:命令行参数、当前工作目录、Scala 版本和应用程序 ID(组织、名称、版本)。此外,应用程序可以请求启动器执行操作,例如获取 Scala jar 和任何版本的 Scala 的 ClassLoader
,这些 Scala 可以从配置文件中指定的仓库中检索。它可以请求下载和运行其他应用程序。当应用程序完成时,它可以告诉启动器使用特定的退出代码退出或使用不同的 Scala 版本、不同的应用程序版本或不同的参数重新加载应用程序。
还有一些其他设置选项,例如将配置文件放入启动器 jar 中并将该文件作为单个下载分发。本文档的其余部分描述了配置、编写、分发和运行应用程序的详细信息。
本节演示如何创建由该启动器启动的应用程序。首先,声明对 launcher-interface
的依赖关系。不要声明对启动器本身的依赖关系。启动器接口仅由 Java 接口组成,以避免在用于编译启动器的 Scala 版本和用于编译应用程序的 Scala 版本之间出现二进制不兼容问题。启动器接口类将由启动器提供,因此它只是一个编译时依赖项。如果您使用 sbt 构建,则依赖项定义将是
libraryDependencies += "org.scala-sbt" % "launcher-interface" % "1.0.0" % "provided"
resolvers += sbtResolver.value
使您的类的入口点实现 xsbti.AppMain
。使用部分信息的示例
package com.acme.launcherapp
class Main extends xsbti.AppMain
{
def run(configuration: xsbti.AppConfiguration) =
{
// get the version of Scala used to launch the application
val scalaVersion = configuration.provider.scalaProvider.version
// Print a message and the arguments to the application
println("Hello world! Running Scala " + scalaVersion)
configuration.arguments.foreach(println)
// demonstrate the ability to reboot the application into different versions of Scala
// and how to return the code to exit with
scalaVersion match
{
case "2.10.6" =>
new xsbti.Reboot {
def arguments = configuration.arguments
def baseDirectory = configuration.baseDirectory
def scalaVersion = "2.11.8"
def app = configuration.provider.id
}
case "2.11.8" => new Exit(1)
case _ => new Exit(0)
}
}
class Exit(val code: Int) extends xsbti.Exit
}
接下来,为启动器定义一个配置文件。对于上面的类,它可能看起来像
[scala]
version: 2.11.8
[app]
org: com.acme
name: launcherapp
version: 0.0.1
class: com.acme.launcherapp.Main
cross-versioned: true
[repositories]
local
maven-central
[boot]
directory: ${user.home}/.myapp/boot
然后,在 sbt 的 shell 中 publishLocal
或 +publishLocal
应用程序以使其可用。有关更多信息,请参见 启动器配置.
如上所述,实际上运行应用程序有几个选项。第一个涉及提供一个修改后的 jar 用于下载。后两个需要提供一个配置文件用于下载。
/sbt/sbt.boot.properties
文件并分发修改后的 jar。用户需要一个脚本运行 java -jar your-launcher.jar arg1 arg2 ....
用户下载启动器 jar,您提供配置文件。
java -Dsbt.boot.properties=your.boot.properties -jar launcher.jar
。launch @your.boot.properties your-arg-1 your-arg-2
让我们回顾一下启动器启动您的应用程序时发生了什么。
启动时,启动器搜索其配置,然后解析它。一旦最终配置得到解析,启动器将继续获取启动应用程序所需的 jar。boot.directory
属性用作检索 jar 的基本目录。在目录上进行锁定,因此它可以在系统范围内共享。启动器检索请求的 Scala 版本以
${boot.directory}/${scala.version}/lib/
如果此目录已经存在,则启动器将采用启动性能的捷径,并假设 jar 已经下载。如果目录不存在,则启动器将使用 Apache Ivy 解析并检索 jar。类似的流程也发生在应用程序本身。它及其依赖项将被检索到
${boot.directory}/${scala.version}/${app.org}/${app.name}/.
一旦所有必需的代码下载完毕,类加载器就会被设置。启动器为请求的 Scala 版本创建一个类加载器。然后,它创建一个子类加载器,其中包含请求的 app.components
的 jar,以及 app.resources
中指定的路径。不使用组件的应用程序将把所有 jar 放入此类加载器中。
应用程序的主类随后被实例化。它必须是一个公共类,具有一个公共无参构造函数,并且必须符合xsbti.AppMain
。run
方法被调用,执行传递给应用程序。'run'方法的参数提供配置信息和一个回调,用于获取来自[repositories]中存储库的任何版本的Scala的类加载器。run方法的返回值决定了应用程序执行后会发生什么。它可以指定启动器应该重新启动应用程序,或者它应该使用提供的退出代码退出。