جاوا و بازل

این صفحه حاوی منابعی است که به شما در استفاده از Bazel با پروژه های جاوا کمک می کند. این به یک آموزش، قوانین ساخت و سایر اطلاعات مربوط به ساخت پروژه های جاوا با Bazel پیوند دارد.

کار با بازل

منابع زیر به شما کمک می کند تا با Bazel در پروژه های جاوا کار کنید:

مهاجرت به بازل

اگر در حال حاضر پروژه‌های جاوا خود را با Maven می‌سازید، مراحل راهنمای مهاجرت را دنبال کنید تا پروژه‌های Maven خود را با Bazel شروع کنید:

نسخه های جاوا

دو نسخه مرتبط جاوا وجود دارد که با پرچم های پیکربندی تنظیم شده اند:

  • نسخه فایل های منبع موجود در مخزن
  • نسخه ای از زمان اجرا جاوا که برای اجرای کد و آزمایش آن استفاده می شود

پیکربندی نسخه کد منبع در مخزن شما

بدون پیکربندی اضافی، Bazel فرض می‌کند که تمام فایل‌های منبع جاوا در مخزن در یک نسخه جاوا نوشته شده‌اند. برای تعیین نسخه منابع موجود در مخزن، build --java_language_version={ver} را به فایل .bazelrc . اضافه کنید، جایی که {ver} برای مثال 11 است. صاحبان مخزن Bazel باید این پرچم را طوری تنظیم کنند که Bazel و کاربران آن بتوانند به شماره نسخه جاوا کد منبع مراجعه کنند. برای جزئیات بیشتر، پرچم نسخه زبان جاوا را ببینید.

پیکربندی JVM مورد استفاده برای اجرا و تست کد

Bazel از یک JDK برای کامپایل و دیگری JVM برای اجرا و تست کد استفاده می کند.

به طور پیش فرض Bazel کد را با استفاده از JDK که دانلود می کند کامپایل می کند و کد را با JVM نصب شده بر روی ماشین محلی اجرا و آزمایش می کند. Bazel JVM را با استفاده از JAVA_HOME یا مسیر جستجو می کند.

باینری‌های به‌دست‌آمده با JVM نصب‌شده محلی در کتابخانه‌های سیستم سازگار هستند، به این معنی که باینری‌های حاصل به آنچه روی دستگاه نصب شده است بستگی دارد.

برای پیکربندی JVM مورد استفاده برای اجرا و آزمایش از --java_runtime_version flag استفاده کنید. مقدار پیش فرض local_jdk است.

تست هرمتیک و تدوین

برای ایجاد یک کامپایل هرمتیک، می توانید از پرچم خط فرمان --java_runtime_version=remotejdk_11 استفاده کنید. کد برای JVM دانلود شده از یک مخزن راه دور کامپایل شده، اجرا و آزمایش می شود. برای جزئیات بیشتر، پرچم نسخه زمان اجرا جاوا را ببینید.

پیکربندی کامپایل و اجرای ابزارهای ساخت در جاوا

جفت دوم JDK و JVM برای ساخت و اجرای ابزارها استفاده می شود که در فرآیند ساخت استفاده می شود، اما در نتایج ساخت وجود ندارد. که JDK و JVM با استفاده از --tool_java_language_version و --tool_java_runtime_version کنترل می شوند. مقادیر پیش‌فرض به ترتیب 11 و remotejdk_11 هستند.

کامپایل با استفاده از JDK نصب شده محلی

Bazel به‌طور پیش‌فرض با استفاده از JDK راه دور کامپایل می‌کند، زیرا در حال غلبه بر داخلی‌های JDK است. زنجیره‌های ابزار کامپایل با استفاده از JDK نصب‌شده محلی پیکربندی شده‌اند، اما استفاده نمی‌شوند.

برای کامپایل با استفاده از JDK نصب شده به صورت محلی، یعنی استفاده از زنجیره ابزار کامپایل برای JDK محلی، از پرچم اضافی --extra_toolchains=@local_jdk//:all استفاده کنید، با این حال، توجه داشته باشید که این ممکن است در JDK فروشندگان دلخواه کار نکند.

برای جزئیات بیشتر، پیکربندی زنجیره ابزار جاوا را ببینید.

بهترین شیوه ها

علاوه بر بهترین روش‌های عمومی Bazel ، در زیر بهترین روش‌های مختص پروژه‌های جاوا آمده است.

ساختار دایرکتوری

طرح دایرکتوری استاندارد Maven را ترجیح دهید (منابع تحت src/main/java ، تست ها در زیر src/test/java ).

فایل ها را بسازید

هنگام ایجاد فایل های BUILD خود، این دستورالعمل ها را دنبال کنید:

  • از یک فایل BUILD در هر دایرکتوری حاوی منابع جاوا استفاده کنید، زیرا این کار عملکرد ساخت را بهبود می بخشد.

  • هر فایل BUILD باید حاوی یک قانون java_library که به شکل زیر است:

    java_library(
        name = "directory-name",
        srcs = glob(["*.java"]),
        deps = [...],
    )
    
  • نام کتابخانه باید نام دایرکتوری حاوی فایل BUILD باشد. این باعث می شود برچسب کتابخانه کوتاهتر شود، یعنی از "//package" به جای "//package:package" استفاده کنید.

  • منابع باید یک glob غیر بازگشتی از تمام فایل های جاوا در دایرکتوری باشند.

  • تست ها باید در یک فهرست منطبق تحت src/test باشند و به این کتابخانه بستگی دارند.

ایجاد قوانین جدید برای ساخت های پیشرفته جاوا

توجه : ایجاد قوانین جدید برای ساخت و سناریوهای آزمایشی پیشرفته است. هنگام شروع کار با Bazel به آن نیازی ندارید.

ماژول‌ها، قطعات پیکربندی و ارائه‌دهندگان زیر به شما کمک می‌کنند قابلیت‌های Bazel را هنگام ساخت پروژه‌های جاوا خود گسترش دهید:

پیکربندی زنجیره ابزار جاوا

Bazel از دو نوع زنجیره ابزار جاوا استفاده می کند: - اجرا، برای اجرا و آزمایش باینری های جاوا، کنترل شده با پرچم --java_runtime_version - کامپایل، برای کامپایل منابع جاوا، کنترل شده با پرچم --java_language_version

پیکربندی زنجیره‌های ابزار اجرایی اضافی

زنجیره ابزار اجرایی JVM است، چه محلی یا از یک مخزن، با برخی اطلاعات اضافی در مورد نسخه، سیستم عامل و معماری CPU آن.

زنجیره‌های ابزار اجرای جاوا ممکن است با استفاده از قوانین local_java_repository یا remote_java_repository در فایل WORKSPACE اضافه شوند. افزودن قانون، JVM را با استفاده از یک پرچم در دسترس قرار می دهد. هنگامی که تعاریف متعددی برای یک سیستم عامل و معماری 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 در طول کامپایل از آنها استفاده می‌کند و ویژگی‌های اضافی را ارائه می‌کند، مانند: مستعد خطا، وابستگی‌های سخت جاوا، کامپایل هدر، شیرین‌سازی اندروید، ابزار دقیق پوشش، و دسته‌بندی دسته‌بندی برای IDE‌ها.

JavaBuilder یک ابزار بسته Bazel است که کامپایل را اجرا می کند و ویژگی های فوق را ارائه می دهد. کامپایل واقعی با استفاده از کامپایلر داخلی توسط JDK اجرا می شود. JDK مورد استفاده برای کامپایل با ویژگی java_runtime زنجیره ابزار مشخص می شود.

Bazel برخی موارد داخلی JDK را لغو می کند. در مورد نسخه JDK > 9، ماژول های java.compiler و jdk.compiler با استفاده از پرچم JDK --patch_module وصله می شوند. در مورد JDK نسخه 8، کامپایلر جاوا با استفاده از پرچم -Xbootclasspath وصله شده است.

VanillaJavaBuilder دومین پیاده سازی JavaBuilder است که کامپایلر داخلی JDK را تغییر نمی دهد و هیچ یک از ویژگی های اضافی را ندارد. VanillaJavaBuilder توسط هیچ یک از زنجیره های ابزار داخلی استفاده نمی شود.

علاوه بر جاوا بیلدر، Bazel از چندین ابزار دیگر در طول کامپایل استفاده می کند.

ابزار ijar فایل های jar را پردازش می کند تا همه چیز را به جز امضای تماس حذف کند. شیشه های حاصل را هدر jar می نامند. آنها برای بهبود افزایش کامپایل تنها با کامپایل مجدد وابستگان پایین دست زمانی که بدنه یک تابع تغییر می کند استفاده می شوند.

ابزار singlejar چندین فایل jar را در یک فایل جمع می کند.

ابزار genclass خروجی یک کامپایل جاوا را پس پردازش می کند و یک jar تولید می کند که فقط حاوی فایل های کلاس برای منابعی است که توسط پردازنده های حاشیه نویسی تولید شده اند.

ابزار JacocoRunner Jacoco را روی فایل‌های ابزاردار اجرا می‌کند و نتایج را در قالب LCOV خروجی می‌دهد.

ابزار TestRunner تست های JUnit 4 را در یک محیط کنترل شده اجرا می کند.

می‌توانید با افزودن ماکرو default_java_toolchain به فایل BUILD و ثبت آن با افزودن قانون register_toolchains به فایل WORKSPACE یا با استفاده از پرچم --extra_toolchains ، کامپایل را دوباره پیکربندی کنید.

زنجیره ابزار فقط زمانی استفاده می شود که ویژگی source_version با مقدار مشخص شده توسط flag --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 و جاوا

می‌توانید پرچم‌های JVM و javac را با پرچم‌ها یا با ویژگی‌های default_java_toolchain پیکربندی کنید.

پرچم های مربوطه --jvmopt , --host_jvmopt , --javacopt و --host_javacopt هستند .

ویژگی های default_java_toolchain مربوطه عبارتند از javacopts ، jvm_opts ، javabuilder_jvm_opts ، و turbine_jvm_opts .

بسته بندی خاص پیکربندی پرچم کامپایلر جاوا

شما می توانید پرچم های مختلف کامپایلر جاوا را برای فایل های منبع خاص با استفاده از ویژگی 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
    ],
)

چندین نسخه از کد منبع جاوا در یک مخزن واحد

Bazel تنها از کامپایل یک نسخه از منابع جاوا در یک بیلد پشتیبانی می کند. ساختن. این بدان معنی است که هنگام ساخت یک تست جاوا یا یک برنامه، همه وابستگی ها بر اساس یک نسخه جاوا ساخته می شوند.

با این حال، ساخت‌های جداگانه ممکن است با استفاده از پرچم‌های مختلف اجرا شوند.

برای آسان‌تر کردن کار استفاده از پرچم‌های مختلف، مجموعه‌هایی از پرچم‌ها برای یک نسخه خاص ممکن است با .bazelrc گروه‌بندی شوند:

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

این تنظیمات را می توان با پرچم --config ، به عنوان مثال bazel test --config=java11 //:java11_test استفاده کرد.