從 Maven 遷移至 Bazel

回報問題 查看來源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

本頁面說明如何從 Maven 遷移至 Bazel,包括先決條件和安裝步驟。說明 Maven 和 Bazel 的差異,並提供使用 Guava 專案的遷移範例。

從任何建構工具遷移至 Bazel 時,最好讓這兩種建構工具並行運作,直到開發團隊、CI 系統和任何其他相關系統完全遷移為止。您可以在同一個存放區中執行 Maven 和 Bazel。

事前準備

  • 如果尚未安裝 Bazel,請安裝
  • 如果您是 Bazel 新手,請先完成「Bazel 簡介:建構 Java」教學課程,再開始遷移。本教學課程說明 Bazel 的概念、結構和標籤語法。

Maven 和 Bazel 的差異

  • Maven 會使用頂層 pom.xml 檔案。Bazel 支援多個建構檔案,以及每個 BUILD 檔案的多個目標,因此建構作業比 Maven 更能以累加方式進行。
  • Maven 會負責部署程序的步驟。Bazel 不會自動部署。
  • 您可以使用 Bazel 表示語言之間的依附元件。
  • 在專案中新增區段時,您可能需要使用 Bazel 新增 BUILD 檔案。最佳做法是在每個新的 Java 套件中新增 BUILD 檔案。

從 Maven 遷移至 Bazel

以下說明如何將專案遷移至 Bazel:

  1. 建立 MODULE.bazel 檔案
  2. 建立一個 BUILD 檔案
  3. 建立更多 BUILD 檔案
  4. 使用 Bazel 建構

以下範例來自 Guava 專案從 Maven 遷移至 Bazel 的過程。使用的 Guava 專案是 v31.1 版。使用 Guava 的範例不會逐步說明遷移作業,但會顯示為遷移作業產生或手動新增的檔案和內容。

$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1

1. 建立 MODULE.bazel 檔案

在專案的根目錄中建立名為 MODULE.bazel 的檔案。如果專案沒有外部依附元件,這個檔案可以空白。

如果專案依附於專案目錄以外的檔案或套件,請在 MODULE.bazel 檔案中指定這些外部依附元件。您可以使用 rules_jvm_external 管理 Maven 的依附元件。如需使用這組規則的操作說明,請參閱 README

Guava 專案範例:外部依附元件

您可以使用 rules_jvm_external 規則集,列出 Guava 專案的外部依附元件。

MODULE.bazel 檔案中新增下列程式碼片段:

bazel_dep(name = "rules_jvm_external", version = "6.2")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
    artifacts = [
        "com.google.code.findbugs:jsr305:3.0.2",
        "com.google.errorprone:error_prone_annotations:2.11.0",
        "com.google.j2objc:j2objc-annotations:1.3",
        "org.codehaus.mojo:animal-sniffer-annotations:1.20",
        "org.checkerframework:checker-qual:3.12.0",
    ],
    repositories = [
        "https://repo1.maven.org/maven2",
    ],
)
use_repo(maven, "maven")

2. 建立一個 BUILD 檔案

定義工作區並列出外部依附元件 (如適用) 後,您需要建立 BUILD 檔案,說明專案的建構方式。與只有一個 pom.xml 檔案的 Maven 不同,Bazel 可以使用多個 BUILD 檔案建構專案。這些檔案會指定多個建構目標,讓 Bazel 產生累加建構。

分階段新增 BUILD 檔案。首先,請在專案根目錄中新增一個 BUILD 檔案,並使用該檔案透過 Bazel 進行初始建構。接著,您會新增更多具有更精細目標的 BUILD 檔案,進一步調整建構作業。

  1. MODULE.bazel 檔案所在的目錄中,建立文字檔案並將其命名為 BUILD

  2. 在這個 BUILD 檔案中,請使用適當的規則建立一個目標,以建構專案。以下提供幾項訣竅:

    • 請使用適當的規則:

      • 如要使用單一 Maven 模組建構專案,請使用 java_library 規則,如下所示:

        java_library(
           name = "everything",
           srcs = glob(["src/main/java/**/*.java"]),
           resources = glob(["src/main/resources/**"]),
           deps = ["//:all-external-targets"],
        )
        
      • 如要使用多個 Maven 模組建構專案,請使用 java_library 規則,如下所示:

        java_library(
           name = "everything",
           srcs = glob([
                 "Module1/src/main/java/**/*.java",
                 "Module2/src/main/java/**/*.java",
                 ...
           ]),
           resources = glob([
                 "Module1/src/main/resources/**",
                 "Module2/src/main/resources/**",
                 ...
           ]),
           deps = ["//:all-external-targets"],
        )
        
      • 如要建構二進位檔,請使用 java_binary 規則:

        java_binary(
           name = "everything",
           srcs = glob(["src/main/java/**/*.java"]),
           resources = glob(["src/main/resources/**"]),
           deps = ["//:all-external-targets"],
           main_class = "com.example.Main"
        )
        
      • 指定屬性:

        • name:為目標命名,在上述範例中,目標稱為「everything」。
        • srcs:使用 globbing 列出專案中的所有 .java 檔案。
        • resources:使用 globbing 列出專案中的所有資源。
        • deps:您需要判斷專案需要哪些外部依附元件。
      • 請參閱下方範例,瞭解 Guava 專案遷移作業的頂層 BUILD 檔案

  3. 專案根目錄中已有 BUILD 檔案,請建構專案,確保專案正常運作。在指令列中,從工作區目錄使用 bazel build //:everything 建構專案。

    專案現在已使用 Bazel 成功建構。您需要新增更多 BUILD 檔案,才能逐步建構專案。

Guava 專案範例:從一個 BUILD 檔案開始

將 Guava 專案遷移至 Bazel 時,一開始會使用一個 BUILD 檔案建構整個專案。以下是工作區目錄中這個初始 BUILD 檔案的內容:

java_library(
    name = "everything",
    srcs = glob([
        "guava/src/**/*.java",
        "futures/failureaccess/src/**/*.java",
    ]),
    javacopts = ["-XepDisableAllChecks"],
    deps = [
        "@maven//:com_google_code_findbugs_jsr305",
        "@maven//:com_google_errorprone_error_prone_annotations",
        "@maven//:com_google_j2objc_j2objc_annotations",
        "@maven//:org_checkerframework_checker_qual",
        "@maven//:org_codehaus_mojo_animal_sniffer_annotations",
    ],
)

3. 建立更多 BUILD 檔案 (選用)

如您在完成第一次建構後所見,Bazel 只要一個 BUILD file 即可運作。您仍應考慮新增更多具有細微目標的 BUILD 檔案,將建構作業分成較小的區塊。

如果有多個 BUILD 檔案和多個目標,建構作業的精細度就會提高,因此可以:

  • 增加專案的累加建構作業,
  • 增加建構的平行執行次數,
  • 為日後使用者提供更易於維護的建構版本,以及
  • 控管套件間目標的可見度,避免程式庫含有實作詳細資料,導致資訊洩漏至公開 API 等問題。

新增更多 BUILD 檔案的提示:

  • 您可以先為每個 Java 套件新增 BUILD 檔案。先從依附元件最少的 Java 套件開始,再逐步處理依附元件最多的套件。
  • 加入 BUILD 檔案並指定目標後,請將這些新目標新增至依附於這些目標的目標 deps 區段。請注意,glob() 函式不會跨越套件界線,因此隨著套件數量增加,glob() 比對的檔案會減少。
  • 每當您將 BUILD 檔案新增至 main 目錄時,請務必將 BUILD 檔案新增至對應的 test 目錄。
  • 請務必適當限制套件之間的瀏覽權限。
  • 為簡化 BUILD 檔案設定中的錯誤疑難排解程序,請確保在新增每個建構檔案時,專案仍可透過 Bazel 建構。執行 bazel build //...,確保所有目標仍可建構。

4. 使用 Bazel 建構

您已使用 Bazel 建構,並將  檔案新增至驗證建構設定。BUILD

當您擁有所需精細程度的 BUILD 檔案時,可以使用 Bazel 產生所有建構作業。