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、不同版本的應用程式或不同的引數重新載入應用程式。
設定還有一些其他選項,例如將組態檔案放入啟動器 jar 中並將其作為單一下載散布。此文件的其餘部分描述如何設定、撰寫、散布和執行應用程式的詳細資訊。
本節說明如何建立由此啟動器啟動的應用程式。首先,宣告 launcher-interface
的相依性。不要宣告啟動器本身的相依性。啟動器介面完全由 Java 介面組成,以避免用於編譯啟動器的 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 的殼層中 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
方法的返回值決定了應用程式執行後會做什麼。它可以指定啟動器應該重新啟動應用程式,或者應該以提供的退出碼退出。