Skip to content

header_compiler_direct (TurbineDirect) emits protobuf sun.misc.Unsafe warnings on JDK 24+ that no toolchain option can silence #374

Description

@davido

Description

When header compilation runs on a JDK 24+ runtime, every direct-header compilation prints:

WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::arrayBaseOffset has been called by com.google.protobuf.UnsafeUtil
         (.../java_tools/turbine_direct_binary_deploy.jar)
WARNING: Please consider reporting this to the maintainers of class com.google.protobuf.UnsafeUtil
WARNING: sun.misc.Unsafe::arrayBaseOffset will be removed in a future release

TurbineDirect bundles protobuf, whose UnsafeUtil calls the terminally deprecated sun.misc.Unsafe memory-access methods; on JDK 24+ (JEP 498) the JVM warns by default (mode warn). Root cause of the Unsafe usage is protocolbuffers/protobuf#20760.

Why it can't be silenced today

The obvious fix — --sun-misc-unsafe-memory-access=allow — cannot be routed to the TurbineDirect JVM from a toolchain:

  • turbine_jvm_opts is passed only to the Turbine worker
    (header_compiler), not to header_compiler_direct
    (java/common/rules/java_toolchain.bzl: header_compiler gets
    turbine_jvm_opts; header_compiler_direct gets a separately-computed
    header_compiler_direct_jvm_opts that is hardcoded to
    ["-Dturbine.ctSymPath=…"]).
  • --jvmopt applies to java_binary/java_test execution, not to
    header-compilation actions (verified with aquery: the flag does not appear
    in the TurbineDirect command line).
  • header_compiler_direct_jvm_opts is not exposed as a java_toolchain /
    default_java_toolchain attribute, and header_compiler_direct cannot be
    dropped (rules_java fail()s when header compilation is requested without it).

So a downstream project on JDK 24+ (e.g. Gerrit Code Review) has no supported way to quiet the warning.

Bazel itself tracks protobuf#20760 per-tool (its root BUILD adds the flag to turbine_jvm_opts;

import_deps_checker adds it to jvm_flags; commit a121ec75d2 narrowed a global --jvmopt down to import_deps_checker), but none of those cover the header_compiler_direct header-compilation path — so the warning surfaces for every rules_java consumer building Java on JDK 24+.

Reproduction

Any java_library built with a toolchain whose java_runtime is JDK 24+.

bazel aquery 'mnemonic("Turbine", //your:lib)' shows the TurbineDirect command carries only -Dturbine.ctSymPath=… and a fixed set of --add-opens — no way to add --sun-misc-unsafe-memory-access=allow.

Proposed fix (see the PR)

Add --sun-misc-unsafe-memory-access=allow to header_compiler_direct_jvm_opts in _java_toolchain_impl, gated on the runtime feature version (the flag is rejected on JDK ≤ 22, so it must be version-guarded; java_runtime.version is 0 when unknown):

if java_runtime and java_runtime.version >= 24:
    header_compiler_direct_jvm_opts = header_compiler_direct_jvm_opts + [
        "--sun-misc-unsafe-memory-access=allow",
    ]

Verified with aquery against a JDK-25 toolchain (the flag now appears in the TurbineDirect command) and a JDK-21 toolchain (the flag is correctly omitted, so the JVM still starts). This fixes it once for all consumers instead of requiring each project to work around it — and the obvious per-project workaround (turbine_jvm_opts) does not even reach the direct header compiler.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions