ชวาและบาเซล

รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

การทำงานกับ Bazel

ทรัพยากรต่อไปนี้จะช่วยให้คุณทำงานกับ Bazel ในโปรเจ็กต์ Java ได้

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

หากปัจจุบันคุณสร้างโปรเจ็กต์ Java ด้วย Maven ให้ทำตามขั้นตอนในคำแนะนำการย้ายข้อมูลเพื่อเริ่มสร้างโปรเจ็กต์ Maven ด้วย Bazel

เวอร์ชัน Java

Java ที่เกี่ยวข้องมี 2 เวอร์ชันซึ่งมีการตั้งค่าแฟล็กการกำหนดค่า ดังนี้

  • เวอร์ชันของไฟล์ต้นฉบับในที่เก็บ
  • เวอร์ชันรันไทม์ Java ที่ใช้เรียกใช้โค้ดและทดสอบ

การกำหนดค่าเวอร์ชันของซอร์สโค้ดในที่เก็บของคุณ

โดยไม่มีการกำหนดค่าเพิ่มเติม Bazel จะถือว่าไฟล์ซอร์สของ Java ทั้งหมดใน จะเขียนด้วย Java เวอร์ชันเดียว หากต้องการระบุเวอร์ชันของแหล่งที่มาในที่เก็บ ให้เพิ่ม build --java_language_version={ver} ลงในไฟล์ .bazelrc โดยที่ {ver} จะเป็นค่าอย่างเช่น 11 เจ้าของที่เก็บ Bazel ควรตั้งค่า Flag นี้เพื่อให้ Bazel และผู้ใช้อ้างอิงหมายเลขเวอร์ชัน Java ของซอร์สโค้ดได้ ดูรายละเอียดเพิ่มเติมได้ที่ แฟล็กเวอร์ชันภาษา Java

การกำหนดค่า JVM ที่ใช้เพื่อเรียกใช้และทดสอบโค้ด

Bazel ใช้ JDK 1 ตัวสำหรับการคอมไพล์ และอีก JVM ตัวหนึ่งเพื่อเรียกใช้และทดสอบโค้ด

โดยค่าเริ่มต้น Bazel จะคอมไพล์โค้ดโดยใช้ JDK ที่ดาวน์โหลดมา จากนั้นจะเรียกใช้และทดสอบโค้ดด้วย JVM ที่ติดตั้งในเครื่อง Bazel ค้นหา JVM โดยใช้ JAVA_HOME หรือเส้นทาง

ไบนารีที่ได้จะเข้ากันได้กับ JVM ที่ติดตั้งไว้ภายในระบบ ซึ่งหมายความว่าไบนารีที่ได้จะขึ้นอยู่กับสิ่งที่ติดตั้งใน อุปกรณ์

หากต้องการกำหนดค่า JVM ที่ใช้สำหรับการดำเนินการและการทดสอบ ให้ใช้--java_runtime_version flag ค่าเริ่มต้นคือ local_jdk

การทดสอบและการรวบรวมเนื้อหาแบบสัญชาตญาณ

ในการสร้างคอมไพล์แบบสัญชาติญาณ คุณสามารถใช้แฟล็กบรรทัดคำสั่ง --java_runtime_version=remotejdk_11 ระบบจะคอมไพล์โค้ด ดำเนินการ และ ที่ทดสอบกับ JVM ที่ดาวน์โหลดจากที่เก็บระยะไกล ดูรายละเอียดเพิ่มเติมได้ที่ แฟล็กเวอร์ชันรันไทม์ของ Java

การกำหนดค่าการคอมไพล์และการดำเนินการของเครื่องมือบิลด์ใน Java

มี JDK และ JVM คู่ที่ 2 ที่ใช้สร้างและเรียกใช้เครื่องมือ ซึ่งใช้ในกระบวนการสร้าง แต่ไม่อยู่ในผลลัพธ์การสร้าง JDK และ JVM นั้น ควบคุมโดยใช้ --tool_java_language_version และ --tool_java_runtime_version ค่าเริ่มต้นคือ 11 และ remotejdk_11 ตามลำดับ

การคอมไพล์โดยใช้ JDK ที่ติดตั้งไว้ในเครื่อง

โดยค่าเริ่มต้น Bazel คอมไพล์โดยใช้ JDK ระยะไกล เนื่องจากโค้ดที่มาลบล้าง JDK ภายในองค์กร มีการกำหนดค่า Toolchain สำหรับการคอมไพล์โดยใช้ JDK ที่ติดตั้งไว้ในเครื่องแล้ว แต่ไม่ได้ใช้งาน

ในการคอมไพล์โดยใช้ JDK ที่ติดตั้งไว้ในเครื่อง ให้ใช้เครื่องมือเชนการคอมไพล์ สำหรับ JDK ในเครื่อง ให้ใช้ Flag เพิ่มเติม --extra_toolchains=@local_jdk//:all อย่างไรก็ตาม โปรดทราบว่าวิธีนี้อาจใช้ไม่ได้กับ JDK ของผู้ให้บริการที่กำหนดเอง

ดูรายละเอียดเพิ่มเติมได้ที่ การกำหนดค่า Java Toolchains

แนวทางปฏิบัติแนะนำ

นอกเหนือจากแนวทางปฏิบัติแนะนำทั่วไปของ Bazel แล้ว ยังมีข้อมูลต่อไปนี้ แนวทางปฏิบัติที่ดีที่สุดสำหรับโปรเจ็กต์ Java โดยเฉพาะ

โครงสร้างไดเรกทอรี

โปรดใช้เลย์เอาต์ไดเรกทอรีมาตรฐานของ Maven (sources อยู่ภายใต้ src/main/java, tests อยู่ภายใต้ src/test/java)

สร้างไฟล์

ปฏิบัติตามหลักเกณฑ์ต่อไปนี้เมื่อสร้างไฟล์ BUILD

  • ใช้ไฟล์ BUILD 1 ไฟล์ต่อไดเรกทอรีที่มีแหล่งที่มา Java เนื่องจาก จะช่วยปรับปรุงประสิทธิภาพบิลด์

  • ทุกไฟล์ BUILD ควรมีกฎ java_library 1 รายการที่มีลักษณะดังนี้ ดังนี้

    java_library(
        name = "directory-name",
        srcs = glob(["*.java"]),
        deps = [...],
    )
    
  • ชื่อของไลบรารีควรเป็นชื่อของไดเรกทอรีที่มีส่วน BUILD ไฟล์ ซึ่งทำให้ป้ายกำกับของไลบรารีสั้นลง โดยใช้ "//package" จากราคาเต็ม "//package:package"

  • แหล่งที่มาควรเป็น glob แบบไม่เกิดซ้ำของ ไฟล์ Java ทั้งหมดในไดเรกทอรี

  • การทดสอบควรอยู่ในไดเรกทอรีที่ตรงกันภายใน src/test และใช้ไลบรารีนี้

การสร้างกฎใหม่สำหรับบิลด์ Java ขั้นสูง

หมายเหตุ: การสร้างกฎใหม่มีไว้สําหรับสถานการณ์บิลด์และทดสอบขั้นสูง คุณไม่จำเป็นต้องใช้เมื่อเริ่มต้นใช้งาน Bazel

โมดูล เศษการกำหนดค่า และผู้ให้บริการต่อไปนี้จะช่วยคุณขยายความสามารถของ Bazel เมื่อสร้างโปรเจ็กต์ Java

การกําหนดค่าชุดเครื่องมือ Java

Bazel ใช้เครื่องมือทางภาษา Java 2 ประเภท ได้แก่ - การดำเนินการ ซึ่งใช้เพื่อเรียกใช้และทดสอบไบนารี Java โดยควบคุมด้วยตัวเลือก --java_runtime_version - การคอมไพล์ ซึ่งใช้เพื่อคอมไพล์ซอร์สโค้ด Java โดยควบคุมด้วยตัวเลือก --java_language_version

การกำหนดค่าเครื่องมือเชนการดําเนินการเพิ่มเติม

เครื่องมือเชนการดำเนินการคือ JVM (ในเครื่องหรือจากที่เก็บ) โดย ข้อมูลเพิ่มเติมเกี่ยวกับเวอร์ชัน ระบบปฏิบัติการ และ CPU สถาปัตยกรรม

อาจเพิ่ม Toolchain การดำเนินการของ Java โดยใช้ local_java_repository หรือ กฎที่เก็บ remote_java_repository รายการในส่วนขยายโมดูล การเพิ่มกฎจะทำให้ JVM พร้อมใช้งานโดยใช้ Flag เมื่อมีหลายคำจำกัดความสำหรับการดำเนินการเดียวกัน ระบบและสถาปัตยกรรม CPU ให้ ส่วนแรกจะใช้

ตัวอย่างการกําหนดค่า JVM ในพื้นที่

load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")

local_java_repository(
  name = "additionaljdk",          # Can be used with --java_runtime_version=additionaljdk, --java_runtime_version=11 or --java_runtime_version=additionaljdk_11
  version = 11,                    # Optional, if not set it is autodetected
  java_home = "/usr/lib/jdk-15/",  # Path to directory containing bin/java
)

ตัวอย่างการกำหนดค่าของ JVM ระยะไกล

load("@bazel_tools//tools/jdk:remote_java_repository.bzl", "remote_java_repository")

remote_java_repository(
  name = "openjdk_canary_linux_arm",
  prefix = "openjdk_canary", # Can be used with --java_runtime_version=openjdk_canary_11
  version = "11",            # or --java_runtime_version=11
  target_compatible_with = [ # Specifies constraints this JVM is compatible with
    "@platforms//cpu:arm",
    "@platforms//os:linux",
  ],
  urls = ...,               # Other parameters are from http_repository rule.
  sha256 = ...,
  strip_prefix = ...
)

การกำหนดค่าเครื่องมือรวบรวมเพิ่มเติม

เครื่องมือการคอมไพล์ประกอบด้วย JDK และเครื่องมือมากมายที่ Bazel ใช้ ระหว่างการคอมไพล์และให้ฟีเจอร์เพิ่มเติม เช่น ข้อผิดพลาด ทรัพยากร Dependency ของ Java อย่างเข้มงวด, การคอมไพล์ส่วนหัว, การนำน้ำตาลออกของ Android, การวัดความครอบคลุม และการจัดการ Genclass สำหรับ IDE

JavaBuilder เป็นเครื่องมือที่มากับ Bazel ซึ่งจะดำเนินการคอมไพล์และให้ คุณลักษณะที่กล่าวไปแล้ว การรวบรวมจริงจะดำเนินการโดยใช้แท็กภายใน ผู้เรียบเรียงโดย JDK java_runtime ระบุ JDK ที่ใช้ในการคอมไพล์ ของ Toolchain

Bazel จะลบล้างข้อมูลภายในของ JDK บางรายการ ในกรณีที่ JDK เป็นเวอร์ชันที่มากกว่า 9 ระบบจะแพตช์โมดูล java.compiler และ jdk.compiler โดยใช้ Flag ของ JDK --patch_module ในกรณีที่เป็น JDK เวอร์ชัน 8 ระบบจะแพตช์คอมไพเลอร์ Java โดยใช้ Flag -Xbootclasspath

VanillaJavaBuilder เป็นการติดตั้งใช้งาน JavaBuilder ครั้งที่สอง ซึ่งไม่ได้ปรับเปลี่ยนคอมไพเลอร์ภายในของ JDK และไม่มีองค์ประกอบ ฟีเจอร์เพิ่มเติม บัญชีที่มีในตัวไม่ได้ใช้ VanillaJavaBuilder Toolchain

นอกจาก JavaBuilder แล้ว Bazel ยังใช้เครื่องมืออื่นๆ อีกหลายอย่างในระหว่างการคอมไพล์

เครื่องมือ ijar จะประมวลผลไฟล์ jar เพื่อนำทุกอย่างออก ยกเว้นลายเซ็นการเรียก โหลที่ได้จะเรียกว่าไจส่วนหัว ไฟล์เหล่านี้ใช้เพื่อปรับปรุงการคอมไพล์แบบเพิ่มทีละขั้นโดยจะคอมไพล์ไฟล์ที่ต้องอาศัย downstream อีกครั้งเฉพาะเมื่อเนื้อหาของฟังก์ชันมีการเปลี่ยนแปลง

เครื่องมือ singlejar จะรวมไฟล์ jar หลายไฟล์เข้าด้วยกันเป็นไฟล์เดียว

เครื่องมือ genclass จะประมวลผลเอาต์พุตของการคอมไพล์ Java ในภายหลังและสร้าง jar ที่มีเฉพาะไฟล์ชั้นเรียนสำหรับแหล่งที่มาที่ โปรเซสเซอร์สำหรับคำอธิบายประกอบ

เครื่องมือ JacocoRunner จะเรียกใช้ Jacoco บนไฟล์ที่มีเครื่องมือและเอาต์พุตผลลัพธ์ รูปแบบ LCOV

เครื่องมือ TestRunner จะทำการทดสอบ JUnit 4 ในสภาพแวดล้อมที่มีการควบคุม

คุณสามารถกำหนดค่าการคอมไพล์ใหม่ได้โดยเพิ่มมาโคร default_java_toolchain ลงในไฟล์ BUILD และลงทะเบียนโดยเพิ่มกฎ register_toolchains ลงในไฟล์ MODULE.bazel หรือใช้แฟล็ก --extra_toolchains

ระบบจะใช้ Toolchain เฉพาะเมื่อแอตทริบิวต์ source_version ตรงกับ ค่าที่แฟล็ก --java_language_version ระบุไว้

ตัวอย่างการกำหนดค่าเครื่องมือมีดังนี้

load(
  "@bazel_tools//tools/jdk:default_java_toolchain.bzl",
  "default_java_toolchain", "DEFAULT_TOOLCHAIN_CONFIGURATION", "BASE_JDK9_JVM_OPTS", "DEFAULT_JAVACOPTS"
)

default_java_toolchain(
  name = "repository_default_toolchain",
  configuration = DEFAULT_TOOLCHAIN_CONFIGURATION,        # One of predefined configurations
                                                          # Other parameters are from java_toolchain rule:
  java_runtime = "@bazel_tools//tools/jdk:remote_jdk11", # JDK to use for compilation and toolchain's tools execution
  jvm_opts = BASE_JDK9_JVM_OPTS + ["--enable_preview"],   # Additional JDK options
  javacopts = DEFAULT_JAVACOPTS + ["--enable_preview"],   # Additional javac options
  source_version = "9",
)

ใช้ --extra_toolchains=//:repository_default_toolchain_definition ได้ หรือด้วยการเพิ่ม register_toolchains("//:repository_default_toolchain_definition") กับพื้นที่ทำงาน

การกำหนดค่าที่กำหนดไว้ล่วงหน้า

  • DEFAULT_TOOLCHAIN_CONFIGURATION: ฟีเจอร์ทั้งหมด รองรับ JDK เวอร์ชันตั้งแต่ 9 ขึ้นไป
  • VANILLA_TOOLCHAIN_CONFIGURATION: ไม่มีฟีเจอร์เพิ่มเติม รองรับ JDK ของ ผู้ให้บริการที่กำหนดเอง
  • PREBUILT_TOOLCHAIN_CONFIGURATION: เหมือนกับค่าเริ่มต้น แต่ใช้เฉพาะที่กำหนดไว้ล่วงหน้า เครื่องมือ (ijar, singlejar)
  • NONPREBUILT_TOOLCHAIN_CONFIGURATION: เหมือนกับค่าเริ่มต้น แต่เครื่องมือทั้งหมด สร้างขึ้นจากแหล่งที่มา (ซึ่งอาจเป็นประโยชน์ในระบบปฏิบัติการที่มี libc)

การกำหนดค่าแฟล็ก JVM และคอมไพเลอร์ Java

คุณอาจกำหนดค่าแฟล็ก JVM และ Javac ด้วยแฟล็กหรือแฟล็กด้วย default_java_toolchain

แฟล็กที่เกี่ยวข้องคือ --jvmopt, --host_jvmopt, --javacopt และ --host_javacopt

แอตทริบิวต์ default_java_toolchain ที่เกี่ยวข้องคือ javacopts, jvm_opts, javabuilder_jvm_opts และ turbine_jvm_opts

การกําหนดค่า Flag คอมไพเลอร์ Java สําหรับแพ็กเกจที่เฉพาะเจาะจง

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

load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")

# This is a convenience macro that inherits values from Bazel's default java_toolchain
default_java_toolchain(
    name = "toolchain",
    package_configuration = [
        ":error_prone",
    ],
    visibility = ["//visibility:public"],
)

# This associates a set of javac flags with a set of packages
java_package_configuration(
    name = "error_prone",
    javacopts = [
        "-Xep:MissingOverride:ERROR",
    ],
    packages = ["error_prone_packages"],
)

# This is a regular package_group, which is used to specify a set of packages to apply flags to
package_group(
    name = "error_prone_packages",
    packages = [
        "//foo/...",
        "-//foo/bar/...", # this is an exclusion
    ],
)

ซอร์สโค้ดของ Java เวอร์ชันต่างๆ ในที่เก็บเดียว

Bazel รองรับเฉพาะการคอมไพล์ซอร์สโค้ด Java เวอร์ชันเดียวในบิลด์ ซึ่งหมายความว่า เมื่อสร้างการทดสอบ Java หรือแอปพลิเคชัน ทรัพยากร Dependency สร้างขึ้นโดยเทียบกับ Java เวอร์ชันเดียวกัน

อย่างไรก็ตาม ระบบอาจดำเนินการบิลด์ที่แยกกันโดยใช้ Flag ที่ต่างกัน

เพื่อให้สามารถใช้งาน Flag ต่างๆ ได้ง่ายขึ้น ชุดของแฟล็ก สามารถจัดกลุ่มเวอร์ชันด้วยการกำหนดค่า .bazelrc รายการได้"

build:java8 --java_language_version=8
build:java8 --java_runtime_version=local_jdk_8
build:java11 --java_language_version=11
build:java11 --java_runtime_version=remotejdk_11

การกำหนดค่าเหล่านี้สามารถใช้กับ Flag --config ได้ เช่น bazel test --config=java11 //:java11_test