Di chuyển từ Maven sang Bazel

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Báo cáo vấn đề Xem nguồn

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. Công cụ này mô tả sự khác biệt giữa Maven và Bazel, đồng thời cung cấp ví dụ về 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 bạn nên chạy song song cả hai công cụ xây dựng cho đến khi hoàn toàn di chuyể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

  • Cài đặt Bazel nếu 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: Tạo Java trước khi bắt đầu di chuyển. Phần hướng dẫn 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 pom.xml tệp cấp cao nhất. Bazel hỗ trợ nhiều tệp bản dựng và nhiều mục tiêu trong mỗi tệp BUILD, cho phép các bản dựng có khả năng tăng dần hơn so với Maven.
  • Maven chịu trách nhiệm về các bước trong quá trình triển khai. Bazel không tự động hoá quá trình triển khai.
  • Bazel giú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, với Bazel, bạn có thể cần thêm các tệp BUILD mới. Cách tốt nhất là thêm tệp BUILD vào mỗi gói Java mới.

Di chuyển từ Maven sang Bazel

Các bước dưới đây mô tả cách di chuyển dự án của bạn sang Bazel:

  1. Tạo tệp WORKSPACE
  2. Tạo một tệp BUILD
  3. Tạo thêm tệp BUILD
  4. Xây dựng bằng Bazel

Dưới đây là ví dụ về việc di chuyển Dự án Guava từ Maven sang Bazel. Dự án Guava được sử dụng đã 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 các ví dụ này sẽ 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 WORKSPACE

Tạo một tệp có tên là WORKSPACE ở gốc dự án của bạn. Nếu dự án của bạn không có phần phụ thuộc bên ngoài, thì tệp không gian làm việc 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 nằm 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 không gian làm việc. Để tự động liệt kê các phần phụ thuộc bên ngoài cho tệp không gian làm việc, hãy sử dụng rules_jvm_external. Để 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: các 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 với bộ quy tắc rules_jvm_external.

Thêm đoạn mã sau vào tệp WORKSPACE:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

RULES_JVM_EXTERNAL_TAG = "4.3"
RULES_JVM_EXTERNAL_SHA = "6274687f6fc5783b589f56a2f1ed60de3ce1f99bc4e8f9edef3de43bdf7c6e74"

http_archive(
    name = "rules_jvm_external",
    sha256 = RULES_JVM_EXTERNAL_SHA,
    strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
    url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)

load("@rules_jvm_external//:defs.bzl", "maven_install")

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",
    ],
)

2. Tạo một tệp BUILD

Sau khi đã xác định được không gian làm việc và các phần phụ thuộc bên ngoài (nếu có), bạn cần tạo 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 tệp BUILD để tạo dự án. Các tệp này chỉ định nhiều mục tiêu bản dựng, cho phép Bazel tạo các bản dựng gia tăng.

Thêm tệp BUILD theo giai đoạn. Bắt đầu bằng cách thêm một tệp BUILD ở gốc dự án và sử dụng tệp đó để tạo bản dựng ban đầu bằng Bazel. Sau đó, bạn sẽ tinh chỉnh bản dựng bằng cách thêm các tệp BUILD với mục tiêu chi tiết hơn.

  1. Trong cùng thư mục với tệp WORKSPACE, hãy tạo một tệp văn bản và đặt tên tệp đó 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 xây dựng dự án. Dưới đây là một số mẹo:

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

      • Để tạo dự án bằng một mô-đun Maven, 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"],
        )
        
      • Để xây dựng các dự án bằng 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 mộ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à "mọi thứ".
      • srcs: Sử dụng tính năng truy cập nhanh để 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 xem nhanh để 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 các phần phụ thuộc bên ngoài mà dự án cần. Ví dụ: nếu bạn đã tạo danh sách các phần phụ thuộc bên ngoài bằng công cụ generate_workspace, thì các phần phụ thuộc cho java_library sẽ là các thư viện được liệt kê trong macro generated_java_libraries.
    • 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 của dự án Guava.

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

    Dự án hiện đã được xây dựng thành công với Bazel. Bạn sẽ cần thêm nhiều tệp BUILD hơn để cho phép các bản dựng của dự án tăng 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 sẽ được dùng để tạo 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",
    ]),
    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 chỉ hoạt động 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 chia nhỏ bản dựng thành các phần nhỏ hơn bằng cách thêm nhiều tệp BUILD có mục tiêu chi tiết hơn.

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

  • số lượng bản dựng tăng dần của dự án.
  • tăng cường thực thi song song bản dựng,
  • khả năng bảo 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 các vấn đề như thư viện chứa thông tin triển khai bị rò rỉ vào API công khai.

Mẹo thêm tệp BUILD khác:

  • Bạn có thể bắt đầu bằng cách thêm tệp BUILD vào mỗi gói Java. Hãy bắt đầu với các gói Java có ít phần phụ thuộc nhất rồi làm theo các gói có nhiều phần phụ thuộc nhất.
  • Khi bạn thêm các tệp BUILD và chỉ định mục tiêu, hãy thêm các mục tiêu mới này vào phần deps của các mục tiêu phụ thuộc vào những mục tiêu đó. Xin lưu ý rằng hàm glob() không vượt qua ranh giới của gói. Do đó, khi số lượng gói tăng lên, các tệp do glob() so khớp sẽ thu nhỏ.
  • Bất cứ khi nào bạn thêm một tệp BUILD vào thư mục main, hãy đảm bảo rằng bạn thêm tệp BUILD vào thư mục test tương ứng.
  • Hãy chú ý giới hạn mức độ hiển thị đúng cách giữa các gói.
  • Để đơn giản hoá các lỗi khắc phục sự cố trong quá trình thiết lập tệp BUILD, hãy đảm bảo 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. Hãy chạy bazel build //... để đảm bảo tất cả mục tiêu của bạn vẫn được tạo.

4. Xây dựng bằng Bazel

Bạn đang xây dựng bằng cách sử dụng Bazel khi thêm các tệp BUILD để xác thực quá trình thiết lập bản dựng.

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