Di chuyển từ Maven sang Bazel

Báo cáo vấn đề Xem nguồn Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Trang này mô tả cách di chuyển từ Maven sang Bazel, bao gồm cả các điều kiện tiên quyết và các bước cài đặt. Bài viết 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ề việc di chuyển bằng cách sử dụng dự án Guava.

Khi di chuyển từ bất kỳ công cụ nào để tạo bản dựng sang Bazel, tốt nhất là bạn nên chạy song song cả hai công cụ tạo bản dựng cho đến khi bạn di chuyển hoàn toàn nhóm phát triển, hệ thống CI và mọi hệ thống 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

Sự khác biệt giữa Maven và Bazel

  • Maven sử dụng(các) tệp pom.xml cấp cao nhất. Bazel hỗ trợ nhiều tệp bản dựng và nhiều mục tiêu cho mỗi tệp BUILD, cho phép các bản dựng gia tăng hơn so với Maven.
  • 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 thêm các phần mới vào dự án, bạn có thể cần thêm các tệp BUILD mới bằng Bazel. Tốt nhất là bạn nên thêm một tệp BUILD và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 của bạn sang Bazel:

  1. Tạo tệp MODULE.bazel
  2. Tạo một tệp BUILD
  3. Tạo thêm tệp BUILD
  4. Tạo bằng Bazel

Các ví dụ dưới đây là từ quá trình di chuyển dự án Guava từ Maven sang Bazel. Dự án Guava được dùng là bản phát hành v31.1. Các ví dụ sử dụng Guava không hướng dẫn từng bước trong quá trình di chuyển, nhưng chú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 ở gốc 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ể 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 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 dự án Guava bằng quy tắc rules_jvm_external.

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, khi đã 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 dự án của bạn sẽ được tạo. Không giống như Maven chỉ có một tệp pom.xml, Bazel có thể dùng nhiều tệp BUILD để tạo 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 ra các bản dựng gia tăng.

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 vào gốc dự án và 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 tệp BUILD hơn với các mục tiêu chi tiết hơn.

  1. Trong cùng 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.

  2. Trong tệp BUILD này, hãy sử dụng quy tắc thích hợp để tạo một mục tiêu nhằm tạo dự án của bạn. Dưới đây là một số mẹo:

    • Sử dụng quy tắc phù hợp:

      • Để tạo các dự án bằng một mô-đun Maven duy nhất, hãy sử dụng quy tắc java_library như sau:

        java_library(
           name = "everything",
           srcs = glob(["src/main/java/**/*.java"]),
           resources = glob(["src/main/resources/**"]),
           deps = ["//:all-external-targets"],
        )
        
      • Để tạo các dự án có nhiều mô-đun Maven, hãy sử dụng quy tắc java_library như 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"],
        )
        
      • Để tạo 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 globbing để liệt kê tất cả các tệp .java trong dự án của bạn.
        • resources: Sử dụng tính năng globbing để liệt kê tất cả tài nguyên trong dự án của bạ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.

  3. Giờ đây, bạn đã có một tệp BUILD ở gốc dự án, hãy tạo dự án để đảm bảo dự án hoạt động. Trên dòng lệnh, trong thư mục không gian làm việc, hãy dùng bazel build //:everything để tạo dự án bằng Bazel.

    Giờ đây, dự án đã được tạo thành công bằng Bazel. Bạn sẽ cần thêm nhiều tệp BUILD hơn để cho phép các bản dựng gia tăng của 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 để tạo toàn bộ dự án. Sau đâ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 tệp BUILD hơn với các mục tiêu chi tiết.

Nhiều tệp BUILD có nhiều mục tiêu sẽ giúp bản dựng tăng độ chi tiết, cho phép:

  • tăng số lượng bản dựng gia tăng của dự án,
  • tăng khả năng thực thi song song của bản dựng,
  • khả năng duy trì bản dựng tốt hơn 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, điều này 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 một tệp BUILD và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 BUILD và chỉ định mục tiêu, hãy thêm những mục tiêu mới này vào các mục tiêu deps phụ thuộc vào chúng. Xin lưu ý rằng hàm glob() 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 do glob() khớp sẽ giảm xuống.
  • Bất cứ khi nào bạn thêm tệp BUILD vào thư mục main, hãy nhớ thêm tệp BUILD vào thư mục test tương ứng.
  • Hãy cẩn thận để hạn chế chế độ hiển thị một cách thích hợp 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 được tạo bằng Bazel khi bạn thêm từng tệp bản dựng. Chạy bazel build //... để đảm bảo tất cả các mục tiêu của bạn vẫn được tạo.

4. Tạo bằng Bazel

Bạn đã tạo bằng Bazel khi thêm các tệp BUILD để xác thực chế độ thiết lập của bản dựng.

Khi có các tệp BUILD ở mức độ chi tiết mong muốn, bạn có thể dùng Bazel để tạo tất cả các bản dựng.