Trang này mô tả cách di chuyển từ Maven sang Bazel, bao gồm các điều kiện tiên quyết và các bước cài đặt. Trang này mô tả sự khác biệt giữa Maven và Bazel, đồng thời cung cấp một ví dụ về quy trình di chuyển bằng dự án Guava.
Khi di chuyển từ bất kỳ công cụ xây dựng nào sang Bazel, tốt nhất là bạn nên chạy song song cả hai công cụ xây dựng cho đến khi di chuyển hoàn toàn nhóm phát triển, hệ thống CI và mọi hệ thống có liên quan khác. Bạn có thể chạy Maven và Bazel trong cùng một kho lưu trữ.
Trước khi bắt đầu
- Cài đặt Bazel nếu bạn chưa cài đặt.
- Nếu bạn mới sử dụng Bazel, hãy xem hướng dẫn Giới thiệu về Bazel: Xây dựng Java trước khi bắt đầu di chuyển. Hướng dẫn này giải thích các khái niệm, cấu trúc và cú pháp nhãn của Bazel.
Sự khác biệt giữa Maven và Bazel
- Maven sử dụng(các) tệp cấp cao nhất
pom.xml. Bazel hỗ trợ nhiều tệp bản dựng và nhiều mục tiêu cho mỗi tệpBUILD, cho phép tạo các bản dựng tăng dần hơn so với Maven's. - Maven chịu trách nhiệm về các bước trong quy trình triển khai. Bazel không tự động hoá quy trình triển khai.
- Bazel cho phép bạn thể hiện các phần phụ thuộc giữa các ngôn ngữ.
- Khi bạn thêm các phần mới vào dự án, với Bazel, bạn có thể cần thêm các tệp mới
BUILD. Phương pháp hay nhất là thêm tệpBUILDvào mỗi gói Java mới.
Di chuyển từ Maven sang Bazel
Các bước bên dưới mô tả cách di chuyển dự án sang Bazel:
Các ví dụ bên dưới được lấy từ quá trình di chuyển dự án Guava từ Maven sang Bazel. Dự án
Guava được sử dụng là bản phát hành v31.1. Các ví dụ sử dụng Guava không trình bày chi tiết từng bước trong quá trình di chuyển, nhưng cho thấy các tệp và nội dung được tạo hoặc thêm theo cách thủ công cho quá trình di chuyển.
$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1
1. Tạo tệp MODULE.bazel
Tạo một tệp có tên là MODULE.bazel ở thư mục gốc của dự án. Nếu dự án của bạn
không có phần phụ thuộc bên ngoài, thì tệp này có thể trống.
Nếu dự án của bạn phụ thuộc vào các tệp hoặc gói không có trong một trong các
thư mục của dự án, hãy chỉ định các phần phụ thuộc bên ngoài này trong tệp MODULE.bazel. Bạn có thể sử dụng rules_jvm_external để quản lý các phần phụ thuộc từ Maven. Để biết
hướng dẫn về cách sử dụng bộ quy tắc này, hãy xem tệp
README
.
Ví dụ về dự án Guava: phần phụ thuộc bên ngoài
Bạn có thể liệt kê các phần phụ thuộc bên ngoài của Guava
dự án bằng
rules_jvm_external
bộ quy tắc.
Thêm đoạn mã sau vào tệp 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. Tạo một tệp BUILD
Giờ đây, bạn đã xác định không gian làm việc và liệt kê các phần phụ thuộc bên ngoài (nếu
có), bạn cần tạo các tệp BUILD để mô tả cách xây dựng dự án. Không giống như Maven chỉ có một tệp pom.xml Bazel có thể sử dụng
nhiều BUILD để xây dựng một dự án. Các tệp này chỉ định nhiều mục tiêu xây dựng, cho phép Bazel tạo các bản dựng tăng dần.
Thêm tệp BUILD theo từng giai đoạn. Bắt đầu bằng cách thêm một tệp BUILD ở thư mục gốc của
dự án và sử dụng tệp đó để thực hiện bản dựng ban đầu bằng Bazel. Sau đó, bạn tinh chỉnh
bản dựng bằng cách thêm nhiều BUILD tệp với các mục tiêu chi tiết hơn.
Trong cùng một thư mục với tệp
MODULE.bazel, hãy tạo một tệp văn bản và đặt tên làBUILD.Trong tệp
BUILDnày, hãy sử dụng quy tắc thích hợp để tạo một mục tiêu nhằm xây dựng dự án. Dưới đây là một số mẹo hay:Sử dụng quy tắc thích hợp:
Để xây dựng các dự án có một mô-đun Maven, hãy sử dụng quy tắc
java_librarynhư sau:java_library( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], )Để xây dựng các dự án có nhiều mô-đun Maven, hãy sử dụng quy tắc
java_librarynhư sau: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"], )Để xây dựng tệp nhị phân, hãy sử dụng quy tắc
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" )Chỉ định các thuộc tính:
name: Đặt tên có ý nghĩa cho mục tiêu. Trong các ví dụ ở trên, mục tiêu được gọi là "everything."srcs: Sử dụng tính năng khớp mẫu để liệt kê tất cả các tệp .java trong dự án.resources: Sử dụng tính năng khớp mẫu để liệt kê tất cả các tài nguyên trong dự án.deps: Bạn cần xác định những phần phụ thuộc bên ngoài mà dự án của bạn cần.
Hãy xem ví dụ bên dưới về tệp BUILD cấp cao nhất này từ quá trình di chuyển dự án Guava.
Giờ đây, bạn đã có tệp
BUILDở thư mục gốc của dự án, hãy xây dựng dự án để đảm bảo dự án hoạt động. Trên dòng lệnh, từ thư mục không gian làm việc, hãy sử dụngbazel build //:everythingđể xây dựng dự án bằng Bazel.Dự án hiện đã được xây dựng thành công bằng Bazel. Bạn cần thêm nhiều
BUILDtệp để cho phép xây dựng tăng dần dự án.
Ví dụ về dự án Guava: bắt đầu bằng một tệp BUILD
Khi di chuyển dự án Guava sang Bazel, ban đầu, một tệp BUILD được dùng để
xây dựng toàn bộ dự án. Dưới đây là nội dung của tệp BUILD ban đầu này trong
thư mục không gian làm việc:
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. Tạo thêm tệp BUILD (không bắt buộc)
Bazel hoạt động chỉ với một BUILD file, như bạn đã thấy sau khi hoàn tất bản dựng
đầu tiên. Bạn vẫn nên cân nhắc việc chia bản dựng thành các phần nhỏ hơn bằng cách
thêm nhiều BUILD tệp với các mục tiêu chi tiết.
Nhiều tệp BUILD với nhiều mục tiêu sẽ giúp bản dựng có độ chi tiết cao hơn, cho phép:
- tăng số lượng bản dựng tăng dần của dự án,
- tăng khả năng thực thi song song của bản dựng,
- cải thiện khả năng duy trì bản dựng cho người dùng trong tương lai và
- kiểm soát khả năng hiển thị của các mục tiêu giữa các gói, có thể ngăn chặn các vấn đề như thư viện chứa thông tin chi tiết về việc triển khai bị rò rỉ vào các API công khai.
Mẹo thêm nhiều tệp BUILD
- Bạn có thể bắt đầu bằng cách thêm tệp
BUILDvào mỗi gói Java. Bắt đầu với các gói Java có ít phần phụ thuộc nhất và tăng dần lên các gói có nhiều phần phụ thuộc nhất. - Khi bạn thêm tệp
BUILDvà chỉ định các mục tiêu, hãy thêm các mục tiêu mới này vào các phầndepscủa các mục tiêu phụ thuộc vào chúng. Lưu ý rằngglob()hàm không vượt qua ranh giới gói, vì vậy, khi số lượng gói tăng lên, các tệp đượcglob()khớp sẽ giảm. - Bất cứ khi nào bạn thêm tệp
BUILDvào thư mụcmain, hãy đảm bảo rằng bạn thêm tệpBUILDvào thư mụctesttương ứng. - Hãy cẩn thận để giới hạn khả năng hiển thị đúng cách giữa các gói.
- Để đơn giản hoá việc khắc phục lỗi trong quá trình thiết lập tệp
BUILD, hãy đảm bảo rằng dự án tiếp tục xây dựng bằng Bazel khi bạn thêm từng tệp bản dựng. Chạybazel build //...để đảm bảo tất cả các mục tiêu của bạn vẫn được xây dựng.
4. Xây dựng bằng Bazel
Bạn đã xây dựng bằng Bazel khi thêm tệp BUILD để xác thực quá trình thiết lập
bản dựng.
Khi có tệp BUILD ở độ chi tiết mong muốn, bạn có thể sử dụng Bazel để
tạo tất cả các bản dựng.