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

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

หน้านี้จะอธิบายวิธีย้ายข้อมูลจาก 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. สร้างไฟล์ MODULE.bazel
  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. สร้างไฟล์ MODULE.bazel

สร้างไฟล์ชื่อ MODULE.bazel ที่รูทของโปรเจ็กต์ หากโปรเจ็กต์ไม่มีทรัพยากร Dependency ภายนอก คุณก็เว้นว่างในไฟล์นี้ได้

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

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

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

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

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

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

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

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

    • ใช้กฎที่เหมาะสม

      • หากต้องการสร้างโปรเจ็กต์ที่มีโมดูล 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: ใช้ Globbing เพื่อแสดงทรัพยากรทั้งหมดในโปรเจ็กต์
        • deps: คุณต้องพิจารณาว่าโปรเจ็กต์ของคุณต้องพึ่งพาอะไรจากภายนอก
      • ดูตัวอย่างด้านล่างของไฟล์ BUILD ระดับบนสุดนี้จากการย้ายข้อมูลโปรเจ็กต์ Guava

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

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

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

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

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

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

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

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

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

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

4. สร้างโดยใช้ Bazel

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

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