ชวาและบาเซล

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 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 แจ้ง ค่าเริ่มต้นคือ 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 (แหล่งที่มาภายใต้ src/main/java, การทดสอบ ภายใต้ 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 Toolchain

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

การกำหนดค่า Toolchain สำหรับการดำเนินการเพิ่มเติม

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

อาจเพิ่ม Toolchain ของ Java Execution โดยใช้ local_java_repository หรือ กฎ remote_java_repository ข้อในไฟล์ WORKSPACE การเพิ่มกฎจะทำให้ 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 = ...
)

การกำหนดค่า Toolchain การคอมไพล์เพิ่มเติม

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

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

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

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

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

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

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

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

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

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

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

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

ตัวอย่างการกำหนดค่า Toolchain

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

การกำหนดค่าแฟล็ก 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

การกำหนดค่าเหล่านี้ใช้ได้กับแฟล็ก --config เช่น bazel test --config=java11 //:java11_test