Java 封存或 JAR 檔案格式是以熱門的 ZIP 檔格式為基礎,並用來將許多 Java 或 Scala 檔案匯總成一個。 使用 JAR 工作,您可以在 Lakeflow 作業中確保 Java 或 Scala 程式代碼的快速且可靠安裝。 本文提供建立 JAR 的範例,以及執行在 JAR 中封裝之應用程式的作業。 在此範例中,您將會:
- 建立定義範例應用程式的 JAR 專案。
- 將範例檔案統合成 JAR。
- 建立執行 JAR 的任務。
- 執行作業並檢視結果。
開始之前
若要完成此範例,您需要下列各項:
- 針對 Java JAR,Java 開發工具套件 (JDK)。
- 針對 Scala JAR、JDK 和 sbt。
步驟 1:建立範例的本機目錄
建立本機目錄以儲存範例程式碼和生成的檔案,例如 databricks_jar_test
。
步驟 2:建立 JAR
完成下列指示,以使用Java或 Scala 來建立 JAR。
建立 Java JAR
在
databricks_jar_test
資料夾中,使用下列內容來建立名為PrintArgs.java
檔案:import java.util.Arrays; public class PrintArgs { public static void main(String[] args) { System.out.println(Arrays.toString(args)); } }
編譯檔案
PrintArgs.java
,這會建立 檔案PrintArgs.class
:javac PrintArgs.java
(選擇性) 執行編譯的程式:
java PrintArgs Hello World! # [Hello, World!]
在與
PrintArgs.java
和PrintArgs.class
檔案相同的資料夾中,建立名為META-INF
的資料夾。在
META-INF
資料夾中,使用下列內容來建立名為MANIFEST.MF
檔案。 請務必在此檔案結尾加入新行:Main-Class: PrintArgs
從
databricks_jar_test
資料夾的根目錄中,建立名為PrintArgs.jar
的 JAR:jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
(選擇性) 若要測試,請從資料夾的
databricks_jar_test
根目錄執行 JAR:java -jar PrintArgs.jar Hello World! # [Hello, World!]
注意
如果您收到錯誤
no main manifest attribute, in PrintArgs.jar
,請務必將換行符新增至MANIFEST.MF
檔案的結尾,然後再嘗試建立並執行 JAR。上傳
PrintArgs.jar
至磁碟區。 請參閱 將檔案上傳至 Unity 目錄磁碟區。
建立 Scala JAR
在
databricks_jar_test
資料夾中,使用下列內容來建立名為build.sbt
的空白檔案:ThisBuild / scalaVersion := "2.12.14" ThisBuild / organization := "com.example" lazy val PrintArgs = (project in file(".")) .settings( name := "PrintArgs" )
從
databricks_jar_test
資料夾建立資料夾結構src/main/scala/example
。在
example
資料夾中,使用下列內容來建立名為PrintArgs.scala
檔案:package example object PrintArgs { def main(args: Array[String]): Unit = { println(args.mkString(", ")) } }
編譯該程式:
sbt compile
(選擇性) 執行編譯的程式:
sbt "run Hello World\!" # Hello, World!
在
databricks_jar_test/project
資料夾中,使用下列內容來建立名為assembly.sbt
檔案:addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
從根目錄的
databricks_jar_test
資料夾執行assembly
命令,這會在target
資料夾下產生 JAR:sbt assembly
(選擇性) 若要測試,請從資料夾的
databricks_jar_test
根目錄執行 JAR:java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World! # Hello, World!
上傳
PrintArgs-assembly-0.1.0-SNAPSHOT.jar
至磁碟區。 請參閱 將檔案上傳至 Unity 目錄磁碟區。
步驟 3. 建立任務以執行 JAR
- 移至您的 Azure Databricks 登陸頁面,並執行下列其中一項:
- 在側邊欄中,點擊
作業和管線,然後點擊 建立 和 作業。
- 在側欄中,點擊
新增,然後從選單中選取 作業。
- 在側邊欄中,點擊
- 在 [工作] 索引標籤上出現的 [工作] 對話方塊中,以您的作業名稱取代 [新增工作名稱...],例如
JAR example
。 - 針對 [工作名稱],輸入工作的名稱,例如 Java 的
java_jar_task
或 Scala 的scala_jar_task
。 - 針對 [類型],選取 [JAR]。
- 針對 [主類別],在此範例中,輸入 Java 的
PrintArgs
或 Scala 的example.PrintArgs
。 - 針對 叢集,選取相容的叢集。 請參閱 Java 和 Scala 程式庫支援。
- 針對 [相依程式庫],按下 [+ 新增]。
- 在 「新增相依連結庫」對話框中,選取「磁碟區」,然後輸入您在上一個步驟中上傳 JAR 的位置(
PrintArgs.jar
或PrintArgs-assembly-0.1.0-SNAPSHOT.jar
)到 「磁碟區檔案路徑」,或篩選或瀏覽以尋找 JAR。 選取它。 - 按一下新增。
- 針對 參數,在此範例中,輸入
["Hello", "World!"]
。 - 按一下新增。
步驟 4:執行作業並檢視作業執行詳細資料
按下 以執行工作流程。 若要檢視執行的
執行完成時,輸出會顯示在 [輸出] 面板中,包括傳遞至工作的引數。
JAR 作業的輸出大小限制
作業輸出,例如發出至 stdout 的記錄輸出,受限於 20 MB 的大小限制。 如果總輸出的大小較大,將會取消執行,並標示為失敗。
若要避免遇到此限制,您可以將 spark.databricks.driver.disableScalaOutput
Spark 組態設定設定為 true
,防止 stdout 從驅動程式傳回至 Azure Databricks。 根據預設,此值為 false
。 旗標可控制 Scala JAR 作業和 Scala 筆記本的儲存格輸出。 如果已啟用旗標,Spark 不會將作業執行結果傳回用戶端。 旗標不會影響在叢集記錄檔中寫入的數據。 Databricks 建議只針對 JAR 作業的作業叢集設定此旗標,因為那會停用筆記本結果。
建議:使用共用的 SparkContext
因為 Azure Databricks 是受管理的服務,因此可能需要一些程式碼變更,以確保 Apache Spark 作業能夠正確執行。 JAR 作業程式必須使用共用 SparkContext
API 來取得 SparkContext
。 因為 Azure Databricks 會初始化 SparkContext
,因此叫用 new SparkContext()
的程式將會失敗。 若要取得 SparkContext
,請只使用 Azure Databricks 所建立的共用 SparkContext
:
val goodSparkContext = SparkContext.getOrCreate()
val goodSparkSession = SparkSession.builder().getOrCreate()
使用共用的 SparkContext
時,您也應該避免使用數種方法。
- 不要呼叫
SparkContext.stop()
。 - 請勿在
System.exit(0)
應用程式結尾呼叫sc.stop()
或Main
。 這可能會導致未定義的行為。
建議:使用 try-finally
區塊進行作業清除
請考慮包含兩個部分的 JAR:
-
jobBody()
,其中包含作業的主要部分。 -
jobCleanup()
必須在jobBody()
之後執行,不論該函式成功或傳回例外狀況。
例如,jobBody()
建立數據表,jobCleanup()
卸除這些數據表。
確保呼叫清除方法的安全方法是在程式碼中放置 try-finally
區塊:
try {
jobBody()
} finally {
jobCleanup()
}
您 不應該 嘗試使用 sys.addShutdownHook(jobCleanup)
或下列程式碼清除:
val cleanupThread = new Thread { override def run = jobCleanup() }
Runtime.getRuntime.addShutdownHook(cleanupThread)
由於 Spark 容器的存留期在 Azure Databricks 中管理的方式,因此無法可靠地執行關機攔截。
設定 JAR 作業參數
您使用 JSON 字串陣列將參數傳遞至 JAR 任務。 請參閱作業 API 中的「建立新作業」操作之要求本文中的 spark_jar_task
物件 ()。 若要存取這些參數,請檢查傳遞至 String
函式的 main
陣列。
管理程式庫相依性
Spark 驅動程式具有無法覆寫的特定程式庫相依性。 如果您的作業新增衝突的程式庫,Spark 驅動程式程式庫相依性優先。
若要取得驅動程式函式庫相依性的完整清單,請在連接到配置了相同 Spark 版本的叢集的筆記本中執行下列命令(或具有您要檢查的驅動程式的叢集):
%sh
ls /databricks/jars
當您定義 JAR 的程式庫相依性時,Databricks 建議將 Spark 和 Hadoop 列為 provided
相依性。 在 Maven 中,新增 Spark 和 Hadoop 做為提供的相依性:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
<scope>provided</scope>
</dependency>
在 sbt
中,新增 Spark 和 Hadoop 做為提供的相依性:
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0" % "provided"
libraryDependencies += "org.apache.hadoop" %% "hadoop-core" % "1.2.1" % "provided"
提示
根據您執行的版本,為您的相依性指定正確的 Scala 版本。
後續步驟
若要深入瞭解如何建立和執行作業,請參閱 Lakeflow 作業。