本頁面含有可協助您搭配 Java 專案使用 Bazel 的資源。這項服務 教學課程、建構規則,以及有關建構的其他資訊 使用 Bazel 建立 Java 專案
使用 Bazel
下列資源可協助您在 Java 專案中使用 Bazel:
遷移至 Bazel
如果您目前使用 Maven 建構 Java 專案,請按照遷移指南中的步驟,開始使用 Bazel 建構 Maven 專案:
Java 版本
有兩個相關的 Java 版本都使用設定標記:
- 存放區中來源檔案的版本
- 想要用來執行程式碼及測試 該資料來源
設定存放區中的原始碼版本
如未額外設定,Bazel 會假設
存放區是以單一 Java 版本編寫。如何指定
將 build --java_language_version={ver}
新增至存放區的來源
.bazelrc
檔案,其中 {ver}
為 11
。Bazel 存放區擁有者應設定這個標記,讓 Bazel 及其使用者能夠參照原始碼的 Java 版本號碼。詳情請參閱「Java 語言版本標記」。
設定用於執行及測試程式碼的 JVM
Bazel 會使用一個 JDK 進行編譯,並使用另一個 JVM 執行及測試程式碼。
根據預設,Bazel 會使用 JDK 下載並執行程式碼
使用本機電腦上安裝的 JVM 測試程式碼。Bazel 會搜尋
使用 JAVA_HOME
或路徑建構 JVM
產生的二進位檔與系統中安裝在本機的 JVM 相容 程式庫,也就是說,產生的二進位檔取決於 這類機制更為快速
如要設定用於執行及測試的 JVM,請使用 --java_runtime_version
旗標。預設值為 local_jdk
。
密封測試和編譯
如要建立隱密的編譯作業,您可以使用指令列標記
--java_runtime_version=remotejdk_11
。程式碼為編譯、執行且
從遠端存放區中下載的 JVM 執行測試詳情請參閱「Java 執行階段版本標記」。
在 Java 中設定建構工具的編譯和執行作業
還有第二組 JDK 和 JVM,用於建構及執行工具,這些工具會用於建構程序,但不會用於建構結果。使用 --tool_java_language_version
和 --tool_java_runtime_version
控管 JDK 和 JVM。預設值為 11
和 remotejdk_11
。
。
使用本機安裝的 JDK 進行編譯
根據預設,Bazel 會使用遠端 JDK 進行編譯,因為它會覆寫 JDK 的內部元件。使用本機安裝 JDK 的編譯工具鏈已設定,但未使用。
如要使用在本機安裝的 JDK 進行編譯,則使用編譯工具鍊
如果是本機 JDK,請使用其他標記 --extra_toolchains=@local_jdk//:all
但請注意,這個做法可能不適用於任意供應商的 JDK。
詳情請參閱 設定 Java 工具鍊。
最佳做法
除了一般 Bazel 最佳做法以外,你還可以參閱下文 最佳做法。
目錄結構
偏好 Maven 的標準目錄版面配置 (src/main/java
下的來源、測試
低於 src/test/java
)。
BUILD 檔案
建立 BUILD
檔案時,請遵守下列規範:
每個包含 Java 來源的資料夾都使用一個
BUILD
檔案,這樣可改善建構效能。每個
BUILD
檔案都應包含一個java_library
規則,如下所示:java_library( name = "directory-name", srcs = glob(["*.java"]), deps = [...], )
程式庫的名稱應為包含
BUILD
檔案。如此一來,程式庫的標籤就會變短"//package"
取代"//package:package"
。來源應為目錄中所有 Java 檔案的非遞迴
glob
。測試應位於
src/test
下的相符目錄,並以此為基礎 資源庫。
為進階 Java 版本建立新規則
注意:建立新規則適用於進階建構和測試情境。您自己 不必使用這個電子郵件地址。
以下模組、設定片段和供應器將能助您一臂之力 在建構 Java 時擴充 Bazel 的功能 專案:
- 主要 Java 模組:
java_common
- 主要 Java 供應器:
JavaInfo
- 設定片段:
java
其他模組:
設定 Java 工具鏈
Bazel 使用兩種類型的 Java 工具鍊:
- 用來執行及測試 Java 二進位檔的執行,
--java_runtime_version
標記
- 編譯,用來編譯 Java 來源,以
--java_language_version
標記
設定其他執行工具鍊
執行工具鍊是 JVM,可以是本機或存放區中的 有關其版本、作業系統和 CPU 的其他資訊 這個架構的簡短總覽
Java 執行工具鍊可使用 local_java_repository
或
模組擴充功能中的 remote_java_repository
存放區規則。新增規則後,即可使用標記提供 JVM。當同一營運業務有多個定義時
並採用第一個架構
本機 JVM 的設定範例:
load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
local_java_repository(
name = "additionaljdk", # Can be used with --java_runtime_version=additionaljdk, --java_runtime_version=11 or --java_runtime_version=additionaljdk_11
version = 11, # Optional, if not set it is autodetected
java_home = "/usr/lib/jdk-15/", # Path to directory containing bin/java
)
遠端 JVM 的設定範例:
load("@bazel_tools//tools/jdk:remote_java_repository.bzl", "remote_java_repository")
remote_java_repository(
name = "openjdk_canary_linux_arm",
prefix = "openjdk_canary", # Can be used with --java_runtime_version=openjdk_canary_11
version = "11", # or --java_runtime_version=11
target_compatible_with = [ # Specifies constraints this JVM is compatible with
"@platforms//cpu:arm",
"@platforms//os:linux",
],
urls = ..., # Other parameters are from http_repository rule.
sha256 = ...,
strip_prefix = ...
)
設定其他編譯工具鏈
編譯工具鍊包含 JDK 和 Bazel 使用的多項工具 且提供其他功能,例如: 容易取得、嚴謹的 Java 依附元件、標頭編譯、Android 脫糖、 涵蓋範圍檢測和 IDE 的基因類別處理。
JavaBuilder 是 Bazel 封裝工具,可執行編譯作業
上述功能實際編譯作業會由 JDK 使用內部編譯器執行。工具鏈的 java_runtime
屬性會指定用於編譯的 JDK。
Bazel 會覆寫部分 JDK 內部。若是 JDK 版本 >9、
已使用 JDK 標記來修補 java.compiler
和 jdk.compiler
模組
--patch_module
。如果是 JDK 8 版,Java 編譯器是以
-Xbootclasspath
標記。
VanillaJavaBuilder 是 JavaBuilder 的第二個實作項目,不會修改 JDK 的內部編譯器,也沒有任何額外功能。任何內建都沒有使用 VanillaJavaBuilder 工具鍊。
除了 JavaBuilder 之外,Bazel 會在編譯時使用幾項其他工具。
ijar
工具會處理 jar
檔案,移除呼叫以外的所有內容
簽章。產生的 jar 則稱為標頭 jar。這類模型能用來
並只在
函式的主體變更
singlejar
工具會將多個 jar
檔案合併為單一檔案。
genclass
工具會對 Java 編譯的輸出內容進行後續處理,然後產生
jar
只包含以下來源所產生來源的類別檔案:
註解處理工具
JacocoRunner
工具會在檢測過的檔案上執行 Jacoco,並以 LCOV 格式輸出結果。
TestRunner
工具會在受控管的環境中執行 JUnit 4 測試。
如要重新設定編譯作業,請將 default_java_toolchain
巨集新增至
建立 BUILD
檔案,然後將 register_toolchains
規則新增至
MODULE.bazel
檔案或使用
--extra_toolchains
旗標。
只有在 source_version
屬性與 --java_language_version
標記指定的值相符時,才會使用工具鏈。
工具鍊設定範例:
load(
"@bazel_tools//tools/jdk:default_java_toolchain.bzl",
"default_java_toolchain", "DEFAULT_TOOLCHAIN_CONFIGURATION", "BASE_JDK9_JVM_OPTS", "DEFAULT_JAVACOPTS"
)
default_java_toolchain(
name = "repository_default_toolchain",
configuration = DEFAULT_TOOLCHAIN_CONFIGURATION, # One of predefined configurations
# Other parameters are from java_toolchain rule:
java_runtime = "@bazel_tools//tools/jdk:remote_jdk11", # JDK to use for compilation and toolchain's tools execution
jvm_opts = BASE_JDK9_JVM_OPTS + ["--enable_preview"], # Additional JDK options
javacopts = DEFAULT_JAVACOPTS + ["--enable_preview"], # Additional javac options
source_version = "9",
)
透過 --extra_toolchains=//:repository_default_toolchain_definition
或新增 register_toolchains("//:repository_default_toolchain_definition")
加入程式碼
預先定義的設定:
DEFAULT_TOOLCHAIN_CONFIGURATION
:所有功能,支援 JDK 第 9 版以上的版本VANILLA_TOOLCHAIN_CONFIGURATION
:沒有其他功能,支援任意供應商的 JDK。PREBUILT_TOOLCHAIN_CONFIGURATION
:與預設值相同,但只使用預先建構 工具 (ijar
、singlejar
)NONPREBUILT_TOOLCHAIN_CONFIGURATION
:與預設值相同,但所有工具都是從來源建構 (這可能對具有不同 libc 的作業系統有用)
設定 JVM 和 Java 編譯器標記
您可以使用旗標 或
default_java_toolchain
屬性。
相關標記為 --jvmopt
、--host_jvmopt
、--javacopt
和 --host_javacopt
。
相關的 default_java_toolchain
屬性為 javacopts
、jvm_opts
、javabuilder_jvm_opts
和 turbine_jvm_opts
。
套件專用的 Java 編譯器旗標設定
您可以為特定來源設定不同的 Java 編譯器標記
使用 default_java_toolchain
的 package_configuration
屬性的檔案。
請參考以下範例。
load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
# This is a convenience macro that inherits values from Bazel's default java_toolchain
default_java_toolchain(
name = "toolchain",
package_configuration = [
":error_prone",
],
visibility = ["//visibility:public"],
)
# This associates a set of javac flags with a set of packages
java_package_configuration(
name = "error_prone",
javacopts = [
"-Xep:MissingOverride:ERROR",
],
packages = ["error_prone_packages"],
)
# This is a regular package_group, which is used to specify a set of packages to apply flags to
package_group(
name = "error_prone_packages",
packages = [
"//foo/...",
"-//foo/bar/...", # this is an exclusion
],
)
單一存放區中有多種版本的 Java 原始碼
Bazel 僅支援在建構作業中編譯單一版本的 Java 來源。 建構應用程式也就是說,建構 Java 測試或應用程式時,所有依附元件都會針對相同的 Java 版本建構。
不過,您可以使用不同的標記執行個別版本。
為簡化使用不同標記的任務,特定版本的標記集可與 .bazelrc
設定組合:
build:java8 --java_language_version=8
build:java8 --java_runtime_version=local_jdk_8
build:java11 --java_language_version=11
build:java11 --java_runtime_version=remotejdk_11
這些設定可以與 --config
旗標搭配使用,例如
bazel test --config=java11 //:java11_test
。