Trang này chứa các tài nguyên giúp bạn sử dụng Bazel cho các dự án Java. Tài liệu này liên kết đến thông tin hướng dẫn, các quy tắc lập trình và thông tin khác dành riêng cho việc xây dựng các dự án Java bằng Bazel.
Làm việc trên Bazel
Các tài nguyên sau đây sẽ giúp bạn sử dụng Bazel hiệu quả cho các dự án Java:
Di chuyển sang Bazel
Nếu hiện đang xây dựng các dự án Java bằng Maven, hãy làm theo các bước trong hướng dẫn di chuyển để bắt đầu xây dựng các dự án Maven bằng Bazel:
Phiên bản Java
Có 2 phiên bản Java có liên quan được thiết lập bằng các cờ cấu hình:
- phiên bản của các tệp nguồn trong kho lưu trữ
- phiên bản của thời gian chạy Java được dùng để thực thi mã và kiểm thử mã đó
Định cấu hình phiên bản của mã nguồn trong kho lưu trữ
Nếu không có cấu hình bổ sung, Bazel sẽ giả định rằng tất cả các tệp nguồn Java trong kho lưu trữ
đều được viết bằng một phiên bản Java. Để chỉ định phiên bản của các
nguồn trong kho lưu trữ, hãy thêm build --java_language_version={ver} vào
.bazelrc tệp, trong đó {ver} là ví dụ: 11. Chủ sở hữu kho lưu trữ Bazel
nên đặt cờ này để Bazel và người dùng có thể tham chiếu đến số phiên bản Java của mã nguồn. Để biết thêm thông tin, hãy xem
Cờ phiên bản ngôn ngữ Java.
Định cấu hình JVM dùng để thực thi và kiểm thử mã
Bazel sử dụng một JDK để biên dịch và một JVM khác để thực thi và kiểm thử mã.
Theo mặc định, Bazel biên dịch mã bằng một JDK mà nó tải xuống, đồng thời thực thi và
kiểm thử mã bằng JVM được cài đặt trên máy cục bộ. Bazel tìm kiếm
JVM bằng JAVA_HOME hoặc đường dẫn.
Các tệp nhị phân kết quả tương thích với JVM được cài đặt cục bộ trong các thư viện hệ thống, tức là các tệp nhị phân kết quả phụ thuộc vào những gì được cài đặt trên máy.
Để định cấu hình JVM dùng cho quá trình thực thi và kiểm thử, hãy sử dụng --java_runtime_version
cờ. Giá trị mặc định là local_jdk.
Kiểm thử và biên dịch khép kín
Để tạo bản biên dịch khép kín, bạn có thể sử dụng cờ dòng lệnh
--java_runtime_version=remotejdk_11. Mã được biên dịch, thực thi và
kiểm thử trên JVM được tải xuống từ một kho lưu trữ từ xa. Để biết thêm thông tin, hãy xem
Cờ phiên bản thời gian chạy Java.
Định cấu hình quá trình biên dịch và thực thi các công cụ xây dựng trong Java
Có một cặp JDK và JVM thứ hai được dùng để xây dựng và thực thi các công cụ được
dùng trong quá trình xây dựng, nhưng không có trong kết quả xây dựng. JDK và JVM đó
được kiểm soát bằng --tool_java_language_version và
--tool_java_runtime_version. Giá trị mặc định lần lượt là 11 và remotejdk_11,
.
Biên dịch bằng JDK được cài đặt cục bộ
Theo mặc định, Bazel biên dịch bằng JDK từ xa vì nó đang ghi đè các thành phần bên trong của JDK. Các chuỗi công cụ biên dịch sử dụng JDK được cài đặt cục bộ được định cấu hình, nhưng không được sử dụng.
Để biên dịch bằng JDK được cài đặt cục bộ, tức là sử dụng các chuỗi công cụ biên dịch
cho JDK cục bộ, hãy sử dụng cờ bổ sung --extra_toolchains=@local_jdk//:all,
tuy nhiên, hãy lưu ý rằng thao tác này có thể không hoạt động trên JDK của các nhà cung cấp tuỳ ý.
Để biết thêm thông tin, hãy xem phần định cấu hình chuỗi công cụ Java.
Các phương pháp hay nhất
Ngoài các nguyên tắc khuyến nghị chung cho Bazel, dưới đây là các phương pháp hay nhất dành riêng cho dự án Java.
Cấu trúc thư mục
Ưu tiên bố cục thư mục tiêu chuẩn của Maven (các nguồn trong src/main/java, các kiểm thử
trong src/test/java).
Tệp BUILD
Hãy làm theo các nguyên tắc sau khi tạo tệp BUILD của bạn:
Sử dụng một tệp
BUILDcho mỗi thư mục chứa các nguồn Java vì điều này giúp cải thiện hiệu suất xây dựng.Mỗi tệp
BUILDphải chứa một quy tắcjava_librarycó dạng như sau:java_library( name = "directory-name", srcs = glob(["*.java"]), deps = [...], )Tên của thư viện phải là tên của thư mục chứa tệp
BUILD. Điều này giúp nhãn của thư viện ngắn hơn, tức là sử dụng"//package"thay vì"//package:package".Các nguồn phải là
globkhông đệ quy của tất cả các tệp Java trong thư mục.Các kiểm thử phải nằm trong một thư mục phù hợp trong
src/testvà phụ thuộc vào thư viện này.
Tạo quy tắc mới cho các bản dựng Java nâng cao
Lưu ý: Việc tạo quy tắc mới dành cho các tình huống kiểm thử và xây dựng nâng cao. Bạn không cần quy tắc này khi bắt đầu sử dụng Bazel.
Các mô-đun, mảnh cấu hình và nhà cung cấp sau đây sẽ giúp bạn mở rộng khả năng của Bazel khi xây dựng các dự án Java của mình:
- Mô-đun Java chính:
java_common - Nhà cung cấp Java chính:
JavaInfo - Mảnh cấu hình:
java Các mô-đun khác:
Định cấu hình chuỗi công cụ Java
Bazel sử dụng 2 loại chuỗi công cụ Java:
- thực thi, dùng để thực thi và kiểm thử các tệp nhị phân Java, được kiểm soát bằng
--java_runtime_version cờ
- biên dịch, dùng để biên dịch các nguồn Java, được kiểm soát bằng
--java_language_version cờ
Định cấu hình chuỗi công cụ thực thi bổ sung
Chuỗi công cụ thực thi là JVM, cục bộ hoặc từ một kho lưu trữ, với một số thông tin bổ sung về phiên bản, hệ điều hành và kiến trúc CPU.
Bạn có thể thêm chuỗi công cụ thực thi Java bằng các quy tắc kho lưu trữ local_java_repository hoặc
remote_java_repository trong một tiện ích mô-đun. Việc thêm quy tắc sẽ giúp
JVM có sẵn bằng một cờ. Khi cung cấp nhiều định nghĩa cho cùng một hệ điều hành
và kiến trúc CPU, định nghĩa đầu tiên sẽ được sử dụng.
Cấu hình mẫu của JVM cục bộ:
load("@rules_java//toolchains: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
)
Cấu hình mẫu của JVM từ xa:
load("@rules_java//toolchains: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 = ...
)
Định cấu hình chuỗi công cụ biên dịch bổ sung
Chuỗi công cụ biên dịch bao gồm JDK và nhiều công cụ mà Bazel sử dụng trong quá trình biên dịch và cung cấp các tính năng bổ sung, chẳng hạn như: Error Prone, các phần phụ thuộc Java nghiêm ngặt, biên dịch tiêu đề, loại bỏ đường dẫn Android, đo lường mức độ bao phủ và xử lý genclass cho IDE.
JavaBuilder là một công cụ đi kèm Bazel thực thi quá trình biên dịch và cung cấp các tính năng
nêu trên. Quá trình biên dịch thực tế được thực thi bằng trình biên dịch nội bộ của JDK. JDK dùng để biên dịch được chỉ định bằng java_runtime
thuộc tính của chuỗi công cụ.
Bazel ghi đè một số thành phần bên trong của JDK. Trong trường hợp phiên bản JDK > 9,
java.compiler và jdk.compiler các mô-đun được vá bằng cờ của JDK
--patch_module. Trong trường hợp phiên bản JDK 8, trình biên dịch Java được vá bằng cờ
-Xbootclasspath.
VanillaJavaBuilder là một phương thức triển khai thứ hai của JavaBuilder, không sửa đổi trình biên dịch nội bộ của JDK và không có bất kỳ tính năng bổ sung nào. Không có chuỗi công cụ tích hợp nào sử dụng VanillaJavaBuilder.
Ngoài JavaBuilder, Bazel còn sử dụng một số công cụ khác trong quá trình biên dịch.
Công cụ ijar xử lý các tệp jar để xoá mọi thứ ngoại trừ chữ ký lệnh gọi. Các tệp jar kết quả được gọi là tệp jar tiêu đề. Các tệp này được dùng để cải thiện tính
tăng dần của quá trình biên dịch bằng cách chỉ biên dịch lại các phần phụ thuộc ở hạ nguồn khi
nội dung của một hàm thay đổi.
Công cụ singlejar đóng gói nhiều tệp jar thành một tệp duy nhất.
Công cụ genclass xử lý sau đầu ra của quá trình biên dịch Java và tạo ra
một jar chỉ chứa các tệp lớp cho các nguồn được tạo bởi
bộ xử lý chú thích.
Công cụ JacocoRunner chạy Jacoco trên các tệp được đo lường và xuất kết quả ở định dạng
LCOV.
Công cụ TestRunner thực thi các kiểm thử JUnit 4 trong một môi trường có kiểm soát.
Bạn có thể định cấu hình lại quá trình biên dịch bằng cách thêm default_java_toolchain macro vào
tệp BUILD và đăng ký macro đó bằng cách thêm quy tắc register_toolchains vào
tệp MODULE.bazel hoặc bằng cách sử dụng
--extra_toolchains cờ.
Chuỗi công cụ chỉ được sử dụng khi thuộc tính source_version khớp với giá trị được chỉ định bằng --java_language_version cờ.
Cấu hình chuỗi công cụ mẫu:
load(
"@rules_java//toolchains: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 = "@rules_java//toolchains: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",
)
có thể được sử dụng bằng --extra_toolchains=//:repository_default_toolchain_definition
hoặc bằng cách thêm register_toolchains("//:repository_default_toolchain_definition")
vào không gian làm việc.
Cấu hình được xác định trước:
DEFAULT_TOOLCHAIN_CONFIGURATION: tất cả các tính năng, hỗ trợ các phiên bản JDK >= 9VANILLA_TOOLCHAIN_CONFIGURATION: không có tính năng bổ sung, hỗ trợ JDK của các nhà cung cấp tuỳ ý.PREBUILT_TOOLCHAIN_CONFIGURATION: giống như mặc định, nhưng chỉ sử dụng các công cụ dựng sẵn (ijar,singlejar)NONPREBUILT_TOOLCHAIN_CONFIGURATION: giống như mặc định, nhưng tất cả các công cụ đều được xây dựng từ các nguồn (điều này có thể hữu ích trên hệ điều hành có libc khác)
Định cấu hình cờ trình biên dịch JVM và Java
Bạn có thể định cấu hình cờ JVM và javac bằng cờ hoặc bằng
default_java_toolchain thuộc tính.
Các cờ có liên quan là --jvmopt, --host_jvmopt, --javacopt, và
--host_javacopt.
Các thuộc tính default_java_toolchain có liên quan là javacopts, jvm_opts,
javabuilder_jvm_opts và turbine_jvm_opts.
Định cấu hình cờ trình biên dịch Java dành riêng cho gói
Bạn có thể định cấu hình các cờ trình biên dịch Java khác nhau cho các tệp nguồn cụ thể bằng thuộc tính package_configuration của default_java_toolchain.
Vui lòng tham khảo ví dụ bên dưới.
load("@rules_java//toolchains: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
],
)
Nhiều phiên bản mã nguồn Java trong một kho lưu trữ
Bazel chỉ hỗ trợ biên dịch một phiên bản nguồn Java trong một bản dựng. bản dựng. Điều này có nghĩa là khi xây dựng một kiểm thử Java hoặc một ứng dụng, tất cả các phần phụ thuộc đều được xây dựng dựa trên cùng một phiên bản Java.
Tuy nhiên, bạn có thể thực thi các bản dựng riêng biệt bằng các cờ khác nhau.
Để giúp bạn dễ dàng sử dụng các cờ khác nhau, các tập hợp cờ cho một phiên bản cụ thể có thể được nhóm bằng cấu hình .bazelrc configs":
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
Bạn có thể sử dụng các cấu hình này với cờ --config, ví dụ
bazel test --config=java11 //:java11_test.