การย้ายข้อมูลจาก Maven ไปยัง Bazel

รายงานปัญหา ดูซอร์สโค้ด รุ่น Nightly · 8.0 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

หน้านี้จะอธิบายวิธีย้ายข้อมูลจาก Maven ไปยัง Bazel รวมถึงข้อกําหนดเบื้องต้นและขั้นตอนการติดตั้ง ซึ่งอธิบายความแตกต่างระหว่าง Maven กับ Bazel และแสดงตัวอย่างการย้ายข้อมูลโดยใช้โปรเจ็กต์ Guava

เมื่อย้ายข้อมูลจากเครื่องมือสร้างไปยัง Bazel จะเป็นการดีที่สุดที่จะให้ทั้ง 2 เครื่องมือสร้างทำงานควบคู่กันจนกว่าคุณจะย้ายข้อมูลทีมพัฒนา ระบบ CI และระบบอื่นๆ ที่เกี่ยวข้องทั้งหมดแล้ว คุณเรียกใช้ Maven และ Bazel ในที่เก็บข้อมูลเดียวกันได้

ก่อนเริ่มต้น

ความแตกต่างระหว่าง Maven กับ Bazel

  • Maven ใช้ไฟล์ pom.xml ระดับบนสุด Bazel รองรับไฟล์บิลด์หลายไฟล์และเป้าหมายหลายรายการต่อไฟล์ BUILD ซึ่งช่วยให้บิลด์มีจำนวนเพิ่มขึ้นมากกว่า Maven
  • Maven จะเป็นผู้รับผิดชอบขั้นตอนต่างๆ ของกระบวนการทำให้ใช้งานได้ Bazel ไม่ได้ทําให้การติดตั้งใช้งานเป็นไปโดยอัตโนมัติ
  • Bazel ช่วยให้คุณระบุความสัมพันธ์ระหว่างภาษาได้
  • เมื่อเพิ่มส่วนใหม่ลงในโปรเจ็กต์ คุณอาจต้องเพิ่มไฟล์ BUILD ใหม่ด้วย Bazel แนวทางปฏิบัติแนะนำคือเพิ่มไฟล์ BUILD ลงในแพ็กเกจ Java ใหม่แต่ละรายการ

ย้ายข้อมูลจาก Maven ไปยัง Bazel

ขั้นตอนด้านล่างจะอธิบายวิธีย้ายข้อมูลโปรเจ็กต์ไปยัง Bazel

  1. สร้างไฟล์ WORKSPACE
  2. สร้างไฟล์ BUILD 1 ไฟล์
  3. สร้างไฟล์ BUILD เพิ่มเติม
  4. สร้างโดยใช้ Bazel

ตัวอย่างด้านล่างมาจากการย้ายข้อมูลโปรเจ็กต์ Guava จาก Maven ไปยัง Bazel โปรเจ็กต์ Guava ที่ใช้คือรุ่น v31.1 ตัวอย่างที่ใช้ Guava จะไม่อธิบายขั้นตอนการย้ายข้อมูลแต่ละขั้นตอน แต่แสดงไฟล์และเนื้อหาที่สร้างขึ้นหรือเพิ่มด้วยตนเองสำหรับการย้ายข้อมูล

$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1

1. สร้างไฟล์ WORKSPACE

สร้างไฟล์ชื่อ WORKSPACE ที่รูทของโปรเจ็กต์ หากโปรเจ็กต์ไม่มีทรัพยากรภายนอก ไฟล์เวิร์กスペースจะว่างเปล่าได้

หากโปรเจ็กต์ใช้ไฟล์หรือแพ็กเกจที่ไม่ได้อยู่ในไดเรกทอรีของโปรเจ็กต์ ให้ระบุการพึ่งพาภายนอกเหล่านี้ในไฟล์เวิร์กสเปซ หากต้องการทำให้รายการของทรัพยากรภายนอกสำหรับไฟล์เวิร์กสเปซทำงานอัตโนมัติ ให้ใช้ rules_jvm_external ดูวิธีการใช้ชุดกฎนี้ได้ในREADME

ตัวอย่างโปรเจ็กต์ Guava: Dependency ภายนอก

คุณสามารถแสดงรายการการพึ่งพาภายนอกของโปรเจ็กต์ Guava ด้วยชุดกฎ rules_jvm_external

เพิ่มข้อมูลโค้ดต่อไปนี้ลงในไฟล์ 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. สร้างไฟล์ BUILD 1 ไฟล์

เมื่อกำหนดพื้นที่ทำงานและระบุทรัพยากรภายนอก (หากมี) แล้ว คุณจะต้องสร้างไฟล์ BUILD เพื่ออธิบายวิธีสร้างโปรเจ็กต์ ซึ่งแตกต่างจาก Maven ที่มีไฟล์ pom.xml ไฟล์เดียว แต่ Bazel สามารถใช้ไฟล์ BUILD หลายไฟล์เพื่อสร้างโปรเจ็กต์ได้ ไฟล์เหล่านี้ระบุเป้าหมายการสร้างหลายรายการ ซึ่งช่วยให้ Bazel สามารถสร้างบิลด์เพิ่มเติมได้

เพิ่มไฟล์ BUILD ทีละขั้น เริ่มต้นด้วยการเพิ่มไฟล์ BUILD 1 ไฟล์ที่รูทของโปรเจ็กต์ และใช้ไฟล์ดังกล่าวเพื่อทำการบิลด์ครั้งแรกโดยใช้ Bazel จากนั้นปรับแต่งบิลด์โดยเพิ่มไฟล์ BUILD อื่นๆ ที่มีเป้าหมายที่ละเอียดยิ่งขึ้น

  1. สร้างไฟล์ข้อความในไดเรกทอรีเดียวกับไฟล์ WORKSPACE แล้วตั้งชื่อว่า BUILD

  2. ในไฟล์ BUILD นี้ ให้ใช้กฎที่เหมาะสมเพื่อสร้างเป้าหมาย 1 รายการเพื่อสร้างโปรเจ็กต์ มาดูเคล็ดลับบางส่วนกัน

    • ใช้กฎที่เหมาะสม ดังนี้

      • หากต้องการสร้างโปรเจ็กต์ด้วยโมดูล Maven รายการเดียว ให้ใช้กฎ java_library ดังนี้

        java_library(
            name = "everything",
            srcs = glob(["src/main/java/**/*.java"]),
            resources = glob(["src/main/resources/**"]),
            deps = ["//:all-external-targets"],
        )
        
      • หากต้องการสร้างโปรเจ็กต์ที่มีโมดูล Maven หลายรายการ ให้ใช้กฎ java_library ดังนี้

        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"],
        )
        
      • หากต้องการสร้างไบนารี ให้ใช้กฎ 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"
        )
        
    • ระบุแอตทริบิวต์ต่อไปนี้

      • name: ตั้งชื่อเป้าหมายให้สื่อความหมาย ในตัวอย่างข้างต้น เป้าหมายเรียกว่า "ทุกอย่าง"
      • srcs: ใช้การรวมกลุ่มเพื่อแสดงรายการไฟล์ .java ทั้งหมดในโปรเจ็กต์
      • resources: ใช้การรวมไฟล์เพื่อแสดงรายการทรัพยากรทั้งหมดในโปรเจ็กต์
      • deps: คุณต้องระบุทรัพยากรภายนอกที่โปรเจ็กต์ของคุณต้องใช้ เช่น หากคุณสร้างรายการทรัพยากร Dependency ภายนอกโดยใช้เครื่องมือ generate_workspace ทรัพยากร Dependency ของ java_library คือไลบรารีที่แสดงในมาโคร generated_java_libraries
    • ดูตัวอย่างด้านล่างของไฟล์ BUILD ระดับบนสุดนี้จากการย้ายข้อมูลโปรเจ็กต์ Guava

  3. เมื่อคุณมีไฟล์ BUILD ที่รูทของโปรเจ็กต์แล้ว ให้สร้างโปรเจ็กต์เพื่อให้แน่ใจว่าใช้งานได้ ในบรรทัดคำสั่ง ให้ใช้ bazel build //:everything จากไดเรกทอรีเวิร์กสเปซเพื่อสร้างโปรเจ็กต์ด้วย Bazel

    ตอนนี้โปรเจ็กต์ได้รับการสร้างด้วย Bazel เรียบร้อยแล้ว คุณจะต้องเพิ่มไฟล์ BUILD เพิ่มเติมเพื่อให้สร้างโปรเจ็กต์ได้มากขึ้น

ตัวอย่างโปรเจ็กต์ Guava: เริ่มต้นด้วยไฟล์ BUILD 1 ไฟล์

เมื่อย้ายข้อมูลโปรเจ็กต์ Guava ไปยัง Bazel ในตอนแรกระบบจะใช้ไฟล์ BUILD ไฟล์เดียวเพื่อสร้างโปรเจ็กต์ทั้งหมด เนื้อหาของBUILDไฟล์แรกนี้ในไดเรกทอรีพื้นที่ทํางานมีดังนี้

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. สร้างไฟล์ BUILD เพิ่มเติม (ไม่บังคับ)

Bazel ใช้งานได้กับ BUILD file เพียงรายการเดียวเท่านั้น ดังที่คุณเห็นหลังจากการบิลด์ครั้งแรกเสร็จสมบูรณ์ คุณควรพิจารณาแบ่งบิลด์ออกเป็นส่วนเล็กๆ โดยเพิ่มไฟล์ BUILD เพิ่มเติมที่มีเป้าหมายแบบละเอียด

ไฟล์ BUILD หลายไฟล์ที่มีเป้าหมายหลายรายการจะทำให้บิลด์มีความละเอียดมากขึ้น ซึ่งจะทําสิ่งต่อไปนี้ได้

  • บิลด์ที่เพิ่มขึ้นของโปรเจ็กต์
  • เพิ่มการดําเนินการแบบขนานของบิลด์
  • ความสามารถในการดูแลรักษาบิลด์ได้ดียิ่งขึ้นสำหรับผู้ใช้ในอนาคต และ
  • ควบคุมระดับการเข้าถึงเป้าหมายระหว่างแพ็กเกจ ซึ่งช่วยป้องกันไม่ให้เกิดปัญหา เช่น ไลบรารีที่มีรายละเอียดการใช้งานรั่วไหลไปยัง API สาธารณะ

เคล็ดลับในการเพิ่มไฟล์ BUILD เพิ่มเติม

  • คุณอาจเริ่มต้นด้วยการเพิ่มไฟล์ BUILD ลงในแพ็กเกจ Java แต่ละรายการ เริ่มจากแพ็กเกจ Java ที่มีการพึ่งพาน้อยที่สุด แล้วไล่ไปจนครบแพ็กเกจที่มีการพึ่งพามากที่สุด
  • เมื่อคุณเพิ่มไฟล์ BUILD และระบุเป้าหมาย ให้เพิ่มเป้าหมายใหม่เหล่านี้ลงในส่วน deps ของเป้าหมายที่ขึ้นอยู่กับไฟล์ BUILD โปรดทราบว่าฟังก์ชัน glob() จะไม่ข้ามขอบเขตของแพ็กเกจ ดังนั้นเมื่อจํานวนแพ็กเกจเพิ่มขึ้น ไฟล์ที่ตรงกับ glob() ก็จะลดลง
  • เมื่อใดก็ตามที่คุณเพิ่มไฟล์ BUILD ลงในไดเรกทอรี main โปรดตรวจสอบว่าคุณได้เพิ่มไฟล์ BUILD ลงในไดเรกทอรี test ที่เกี่ยวข้อง
  • โปรดระมัดระวังในการจำกัดระดับการเข้าถึงระหว่างแพ็กเกจอย่างเหมาะสม
  • หากต้องการลดความซับซ้อนในการแก้ปัญหาข้อผิดพลาดในการตั้งค่าไฟล์ BUILD ให้ตรวจสอบว่าโปรเจ็กต์ยังสร้างด้วย Bazel ต่อไปขณะที่คุณเพิ่มไฟล์บิลด์แต่ละไฟล์ เรียกใช้ bazel build //... เพื่อให้แน่ใจว่าเป้าหมายทั้งหมดยังคงสร้างอยู่

4. บิลด์โดยใช้ Bazel

คุณกำลังสร้างโดยใช้ Bazel เมื่อเพิ่มไฟล์ BUILD เพื่อตรวจสอบการตั้งค่าของบิลด์

เมื่อคุณมีไฟล์ BUILD ที่ละเอียดตามที่ต้องการแล้ว คุณจะใช้ Bazel เพื่อสร้างบิลด์ทั้งหมดได้