Move (and enable) remaining java rules & providers out of `@_builtins`

PiperOrigin-RevId: 697997376
Change-Id: I1ef76949530cd89498826f2bae32b92d57c29f04
diff --git a/MODULE.bazel b/MODULE.bazel
index 857c7a3..648c2b2 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -90,7 +90,7 @@
 [register_toolchains("@" + name + "_toolchain_config_repo//:all") for name in REMOTE_JDK_REPOS]
 
 # Compatibility layer
-compat = use_extension("//java:extensions.bzl", "compatibility_proxy")
+compat = use_extension("//java:rules_java_deps.bzl", "compatibility_proxy")
 use_repo(compat, "compatibility_proxy")
 
 # Dev dependencies
diff --git a/WORKSPACE b/WORKSPACE
index f58f31c..d5e6a7e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -37,7 +37,7 @@
     ],
 )
 
-load("//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
+load("//java:rules_java_deps.bzl", "rules_java_dependencies")
 
 rules_java_dependencies()
 
@@ -45,6 +45,8 @@
 
 proto_bazel_features(name = "proto_bazel_features")
 
+load("//java:repositories.bzl", "rules_java_toolchains")
+
 rules_java_toolchains()
 
 load("@stardoc//:setup.bzl", "stardoc_repositories")
diff --git a/java/bazel/rules/bazel_java_binary.bzl b/java/bazel/rules/bazel_java_binary.bzl
index 7d0e75b..06e8421 100644
--- a/java/bazel/rules/bazel_java_binary.bzl
+++ b/java/bazel/rules/bazel_java_binary.bzl
@@ -15,7 +15,6 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 load("@rules_cc//cc:find_cc_toolchain.bzl", "use_cc_toolchain")
-load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
 load(
     "//java/common/rules:android_lint.bzl",
@@ -26,6 +25,7 @@
 load("//java/common/rules/impl:java_binary_deploy_jar.bzl", "create_deploy_archives")
 load("//java/common/rules/impl:java_binary_impl.bzl", "basic_java_binary")
 load("//java/common/rules/impl:java_helper.bzl", "helper")
+load("//java/private:java_info.bzl", "JavaInfo")
 
 def _bazel_java_binary_impl(ctx):
     return bazel_base_binary_impl(ctx, is_test_rule_class = False) + helper.executable_providers(ctx)
diff --git a/java/bazel/rules/bazel_java_binary_wrapper.bzl b/java/bazel/rules/bazel_java_binary_wrapper.bzl
index 0c61abf..517dcd6 100644
--- a/java/bazel/rules/bazel_java_binary_wrapper.bzl
+++ b/java/bazel/rules/bazel_java_binary_wrapper.bzl
@@ -18,21 +18,19 @@
 the supplied value of the `create_executable` attribute.
 """
 
-load("//java/common:java_common.bzl", "java_common")
 load(
     "//java/common/rules:java_binary_wrapper.bzl",
     "register_java_binary_rules",
     "register_legacy_java_binary_rules",
 )
+load("//java/private:native.bzl", "get_internal_java_common")
 load(":bazel_java_binary.bzl", java_bin_exec = "java_binary")
 load(":bazel_java_binary_nonexec.bzl", java_bin_nonexec = "java_binary")
 
-_java_common_internal = java_common.internal_DO_NOT_USE()
-
 # copybara: default visibility
 
 def java_binary(**kwargs):
-    if _java_common_internal.incompatible_disable_non_executable_java_binary():
+    if get_internal_java_common().incompatible_disable_non_executable_java_binary():
         register_java_binary_rules(
             java_bin_exec,
             **kwargs
diff --git a/java/bazel/rules/bazel_java_import.bzl b/java/bazel/rules/bazel_java_import.bzl
index 702dcf9..855420f 100644
--- a/java/bazel/rules/bazel_java_import.bzl
+++ b/java/bazel/rules/bazel_java_import.bzl
@@ -16,10 +16,10 @@
 Definition of java_import rule.
 """
 
-load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules:java_import.bzl", "JAVA_IMPORT_ATTRS")
 load("//java/common/rules/impl:bazel_java_import_impl.bzl", "bazel_java_import_rule")
+load("//java/private:java_info.bzl", "JavaInfo")
 
 def _proxy(ctx):
     return bazel_java_import_rule(
diff --git a/java/bazel/rules/bazel_java_library.bzl b/java/bazel/rules/bazel_java_library.bzl
index 425a91a..2c92394 100644
--- a/java/bazel/rules/bazel_java_library.bzl
+++ b/java/bazel/rules/bazel_java_library.bzl
@@ -16,11 +16,11 @@
 Definition of java_library rule.
 """
 
-load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules:android_lint.bzl", "android_lint_subrule")
 load("//java/common/rules:java_library.bzl", "JAVA_LIBRARY_ATTRS")
 load("//java/common/rules/impl:bazel_java_library_impl.bzl", "bazel_java_library_rule")
+load("//java/private:java_info.bzl", "JavaInfo")
 
 def _proxy(ctx):
     return bazel_java_library_rule(
diff --git a/java/bazel/rules/bazel_java_plugin.bzl b/java/bazel/rules/bazel_java_plugin.bzl
index b1bfacb..f2619ed 100644
--- a/java/bazel/rules/bazel_java_plugin.bzl
+++ b/java/bazel/rules/bazel_java_plugin.bzl
@@ -16,13 +16,13 @@
 Definition of java_plugin rule.
 """
 
-load("//java/common:java_plugin_info.bzl", "JavaPluginInfo")
 load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules:android_lint.bzl", "android_lint_subrule")
 load("//java/common/rules:java_library.bzl", "JAVA_LIBRARY_IMPLICIT_ATTRS")
 load("//java/common/rules:java_plugin.bzl", "JAVA_PLUGIN_ATTRS")
 load("//java/common/rules:rule_util.bzl", "merge_attrs")
 load("//java/common/rules/impl:basic_java_library_impl.bzl", "basic_java_library", "construct_defaultinfo")
+load("//java/private:java_info.bzl", "JavaPluginInfo")
 
 def bazel_java_plugin_rule(
         ctx,
diff --git a/java/common/BUILD b/java/common/BUILD
index 01fab79..62e47db 100644
--- a/java/common/BUILD
+++ b/java/common/BUILD
@@ -16,7 +16,7 @@
     name = "common",
     srcs = glob(["*.bzl"]),
     visibility = ["//visibility:public"],
-    deps = ["//java/private:native_bzl"],
+    deps = ["//java/private:internals"],
 )
 
 filegroup(
diff --git a/java/common/java_common.bzl b/java/common/java_common.bzl
index 201beba..ed55bdb 100644
--- a/java/common/java_common.bzl
+++ b/java/common/java_common.bzl
@@ -13,6 +13,6 @@
 # limitations under the License.
 """java_common module"""
 
-load("//java/private:native.bzl", "native_java_common")
+load("@compatibility_proxy//:proxy.bzl", _java_common = "java_common")
 
-java_common = native_java_common
+java_common = _java_common
diff --git a/java/common/java_info.bzl b/java/common/java_info.bzl
index e22fb3d..2748f6d 100644
--- a/java/common/java_info.bzl
+++ b/java/common/java_info.bzl
@@ -13,6 +13,6 @@
 # limitations under the License.
 """JavaInfo provider"""
 
-load("//java/private:native.bzl", "NativeJavaInfo")
+load("@compatibility_proxy//:proxy.bzl", _JavaInfo = "JavaInfo")
 
-JavaInfo = NativeJavaInfo
+JavaInfo = _JavaInfo
diff --git a/java/common/java_plugin_info.bzl b/java/common/java_plugin_info.bzl
index 36d84f9..b43dfd5 100644
--- a/java/common/java_plugin_info.bzl
+++ b/java/common/java_plugin_info.bzl
@@ -13,6 +13,6 @@
 # limitations under the License.
 """JavaPluginInfo provider"""
 
-load("//java/private:native.bzl", "NativeJavaPluginInfo")
+load("@compatibility_proxy//:proxy.bzl", _JavaPluginInfo = "JavaPluginInfo")
 
-JavaPluginInfo = NativeJavaPluginInfo
+JavaPluginInfo = _JavaPluginInfo
diff --git a/java/common/java_semantics.bzl b/java/common/java_semantics.bzl
index ec17c92..a08717b 100644
--- a/java/common/java_semantics.bzl
+++ b/java/common/java_semantics.bzl
@@ -66,10 +66,6 @@
     },
 )
 
-tokenize_javacopts = cc_helper.tokenize
-
-PLATFORMS_ROOT = "@platforms//"
-
 semantics = struct(
     JAVA_TOOLCHAIN_LABEL = "@bazel_tools//tools/jdk:current_java_toolchain",
     JAVA_TOOLCHAIN_TYPE = "@bazel_tools//tools/jdk:toolchain_type",
@@ -108,4 +104,6 @@
         for_attribute = lambda name: _DOCS.ATTRS.get(name, ""),
     ),
     minimize_cc_info = _minimize_cc_info,
+    tokenize_javacopts = cc_helper.tokenize,
+    PLATFORMS_ROOT = "@platforms//",
 )
diff --git a/java/common/rules/android_lint.bzl b/java/common/rules/android_lint.bzl
index d7fec44..5275ec2 100644
--- a/java/common/rules/android_lint.bzl
+++ b/java/common/rules/android_lint.bzl
@@ -14,13 +14,13 @@
 
 """Creates the android lint action for java rules"""
 
-load("//java/common:java_semantics.bzl", "semantics", _semantics_tokenize_javacopts = "tokenize_javacopts")
+load("//java/common:java_semantics.bzl", "semantics")
 
 # copybara: default visibility
 
 def _tokenize_opts(opts_depset):
     opts = reversed(opts_depset.to_list())
-    return _semantics_tokenize_javacopts(opts)
+    return semantics.tokenize_javacopts(opts)
 
 def _android_lint_action(ctx, source_files, source_jars, compilation_info):
     """
@@ -112,7 +112,7 @@
     args.add_all(linter.lint_opts)
 
     for package_config in linter.package_config:
-        if package_config.matches(ctx.label):
+        if package_config.matches(package_config.package_specs, ctx.label):
             # wrap in a list so that map_each passes the depset to _tokenize_opts
             package_opts = [package_config.javac_opts]
             args.add_all(package_opts, map_each = _tokenize_opts)
diff --git a/java/common/rules/basic_java_library.bzl b/java/common/rules/basic_java_library.bzl
index c8a13fb..f55351e 100644
--- a/java/common/rules/basic_java_library.bzl
+++ b/java/common/rules/basic_java_library.bzl
@@ -16,9 +16,9 @@
 Common code for reuse across java_* rules
 """
 
-load("//java/common:java_common.bzl", "java_common")
-load("//java/common:java_plugin_info.bzl", "JavaPluginInfo")
 load("//java/common:java_semantics.bzl", "semantics")
+load("//java/private:java_common.bzl", "java_common")
+load("//java/private:java_info.bzl", "JavaPluginInfo")
 load(":rule_util.bzl", "merge_attrs")
 
 visibility([
diff --git a/java/common/rules/impl/basic_java_library_impl.bzl b/java/common/rules/impl/basic_java_library_impl.bzl
index 8ba5343..da5b2bc 100644
--- a/java/common/rules/impl/basic_java_library_impl.bzl
+++ b/java/common/rules/impl/basic_java_library_impl.bzl
@@ -17,10 +17,10 @@
 """
 
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
-load("//java/common:java_common.bzl", "java_common")
-load("//java/common:java_info.bzl", "JavaInfo")
-load("//java/common:java_plugin_info.bzl", "JavaPluginInfo")
 load("//java/common/rules:android_lint.bzl", "android_lint_subrule")
+load("//java/private:boot_class_path_info.bzl", "BootClassPathInfo")
+load("//java/private:java_common_internal.bzl", "target_kind")
+load("//java/private:java_info.bzl", "JavaInfo", "JavaPluginInfo")
 load(":compile_action.bzl", "compile_action")
 load(":proguard_validation.bzl", "validate_proguard_specs")
 
@@ -28,10 +28,6 @@
     "//java/...",
 ])
 
-_java_common_internal = java_common.internal_DO_NOT_USE()
-BootClassPathInfo = java_common.BootClassPathInfo
-target_kind = _java_common_internal.target_kind
-
 def _filter_srcs(srcs, ext):
     return [f for f in srcs if f.extension == ext]
 
diff --git a/java/common/rules/impl/bazel_java_import_impl.bzl b/java/common/rules/impl/bazel_java_import_impl.bzl
index 6d636dc..4df2ab8 100644
--- a/java/common/rules/impl/bazel_java_import_impl.bzl
+++ b/java/common/rules/impl/bazel_java_import_impl.bzl
@@ -17,18 +17,16 @@
 """
 
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
-load("//java/common:java_common.bzl", "java_common")
-load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules/impl:basic_java_library_impl.bzl", "construct_defaultinfo")
 load("//java/common/rules/impl:import_deps_check.bzl", "import_deps_check")
+load("//java/private:java_common.bzl", "java_common")
+load("//java/private:java_common_internal.bzl", _run_ijar_private_for_builtins = "run_ijar")
+load("//java/private:java_info.bzl", "JavaInfo")
 load(":proguard_validation.bzl", "validate_proguard_specs")
 
 # copybara: default visibility
 
-_java_common_internal = java_common.internal_DO_NOT_USE()
-_run_ijar_private_for_builtins = _java_common_internal.run_ijar_private_for_builtins
-
 def _filter_provider(provider, *attrs):
     return [dep[provider] for attr in attrs for dep in attr if provider in dep]
 
diff --git a/java/common/rules/impl/compile_action.bzl b/java/common/rules/impl/compile_action.bzl
index d1c7f0e..bf5b935 100644
--- a/java/common/rules/impl/compile_action.bzl
+++ b/java/common/rules/impl/compile_action.bzl
@@ -17,12 +17,10 @@
 """
 
 load("//java/common:java_semantics.bzl", "semantics")
+load("//java/private:java_common_internal.bzl", _compile_private_for_builtins = "compile")
 
 visibility("private")
 
-_java_common_internal = java_common.internal_DO_NOT_USE()
-_compile_private_for_builtins = _java_common_internal.compile
-
 def _filter_strict_deps(mode):
     return "error" if mode in ["strict", "default"] else mode
 
diff --git a/java/common/rules/impl/java_binary_impl.bzl b/java/common/rules/impl/java_binary_impl.bzl
index bdaa4ac..7de9d30 100644
--- a/java/common/rules/impl/java_binary_impl.bzl
+++ b/java/common/rules/impl/java_binary_impl.bzl
@@ -17,21 +17,20 @@
 load("@com_google_protobuf//bazel/common:proto_info.bzl", "ProtoInfo")
 load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
-load("//java/common:java_common.bzl", "java_common")
-load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules/impl:basic_java_library_impl.bzl", "basic_java_library", "collect_deps")
+load("//java/private:java_common.bzl", "java_common")
+load(
+    "//java/private:java_common_internal.bzl",
+    "collect_native_deps_dirs",
+    "get_runtime_classpath_for_archive",
+)
+load("//java/private:java_info.bzl", "JavaCompilationInfo", "JavaInfo", "to_java_binary_info")
 load(":java_binary_deploy_jar.bzl", "create_deploy_archive")
 load(":java_helper.bzl", "helper")
 
 # copybara: default visibility
 
-_java_common_internal = java_common.internal_DO_NOT_USE()
-JavaCompilationInfo = _java_common_internal.JavaCompilationInfo
-collect_native_deps_dirs = _java_common_internal.collect_native_deps_dirs
-get_runtime_classpath_for_archive = _java_common_internal.get_runtime_classpath_for_archive
-to_java_binary_info = _java_common_internal.to_java_binary_info
-
 InternalDeployJarInfo = provider(
     "Provider for passing info to deploy jar rule",
     fields = [
diff --git a/java/common/rules/impl/java_helper.bzl b/java/common/rules/impl/java_helper.bzl
index 87465f0..fa82898 100644
--- a/java/common/rules/impl/java_helper.bzl
+++ b/java/common/rules/impl/java_helper.bzl
@@ -450,6 +450,35 @@
         return path_b
     return paths.normalize(paths.join(path_a, path_b))
 
+def _tokenize_javacopts(ctx = None, opts = []):
+    """Tokenizes a list or depset of options to a list.
+
+    Iff opts is a depset, we reverse the flattened list to ensure right-most
+    duplicates are preserved in their correct position.
+
+    If the ctx parameter is omitted, a slow, but pure Starlark, implementation
+    of shell tokenization is used. Otherwise, tokenization is performed using
+    ctx.tokenize() which has significantly better performance (up to 100x for
+    large options lists).
+
+    Args:
+        ctx: (RuleContext|None) the rule context
+        opts: (depset[str]|[str]) the javac options to tokenize
+    Returns:
+        [str] list of tokenized options
+    """
+    if hasattr(opts, "to_list"):
+        opts = reversed(opts.to_list())
+    if ctx:
+        return [
+            token
+            for opt in opts
+            for token in ctx.tokenize(opt)
+        ]
+    else:
+        # TODO: optimize and use the pure Starlark implementation in cc_helper
+        return semantics.tokenize_javacopts(opts)
+
 helper = struct(
     collect_all_targets_as_deps = _collect_all_targets_as_deps,
     filter_launcher_for_target = _filter_launcher_for_target,
@@ -474,6 +503,7 @@
     create_single_jar = _create_single_jar,
     shell_escape = _shell_escape,
     detokenize_javacopts = _detokenize_javacopts,
+    tokenize_javacopts = _tokenize_javacopts,
     derive_output_file = _derive_output_file,
     is_stamping_enabled = _is_stamping_enabled,
     get_relative = _get_relative,
diff --git a/java/common/rules/java_binary.bzl b/java/common/rules/java_binary.bzl
index 8e0ce02..09b6b12 100644
--- a/java/common/rules/java_binary.bzl
+++ b/java/common/rules/java_binary.bzl
@@ -16,18 +16,17 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
-load("//java/common:java_common.bzl", "java_common")
-load("//java/common:java_info.bzl", "JavaInfo")
-load("//java/common:java_plugin_info.bzl", "JavaPluginInfo")
-load("//java/common:java_semantics.bzl", "PLATFORMS_ROOT", "semantics")
+load("//java/common:java_semantics.bzl", "semantics")
+load("//java/private:java_common.bzl", "java_common")
+load("//java/private:java_info.bzl", "JavaInfo", "JavaPluginInfo")
+load("//java/private:native.bzl", "get_internal_java_common")
 load(":basic_java_library.bzl", "BASIC_JAVA_LIBRARY_IMPLICIT_ATTRS")
 load(":rule_util.bzl", "merge_attrs")
 
 # copybara: default visibility
 
 BootClassPathInfo = java_common.BootClassPathInfo
-
-_java_common_internal = java_common.internal_DO_NOT_USE()
+_PLATFORMS_ROOT = semantics.PLATFORMS_ROOT
 
 BASIC_JAVA_BINARY_ATTRIBUTES = merge_attrs(
     BASIC_JAVA_LIBRARY_IMPLICIT_ATTRS,
@@ -321,10 +320,10 @@
         ),
         "_java_toolchain_type": attr.label(default = semantics.JAVA_TOOLCHAIN_TYPE),
         "_windows_constraints": attr.label_list(
-            default = [paths.join(PLATFORMS_ROOT, "os:windows")],
+            default = [paths.join(_PLATFORMS_ROOT, "os:windows")],
         ),
         "_build_info_translator": attr.label(default = semantics.BUILD_INFO_TRANSLATOR_LABEL),
-    } | ({} if _java_common_internal.incompatible_disable_non_executable_java_binary() else {"create_executable": attr.bool(default = True, doc = "Deprecated, use <code>java_single_jar</code> instead.")}),
+    } | ({} if get_internal_java_common().incompatible_disable_non_executable_java_binary() else {"create_executable": attr.bool(default = True, doc = "Deprecated, use <code>java_single_jar</code> instead.")}),
 )
 
 BASE_TEST_ATTRIBUTES = {
@@ -367,11 +366,11 @@
     "env_inherit": attr.string_list(),
     "_apple_constraints": attr.label_list(
         default = [
-            paths.join(PLATFORMS_ROOT, "os:ios"),
-            paths.join(PLATFORMS_ROOT, "os:macos"),
-            paths.join(PLATFORMS_ROOT, "os:tvos"),
-            paths.join(PLATFORMS_ROOT, "os:visionos"),
-            paths.join(PLATFORMS_ROOT, "os:watchos"),
+            paths.join(_PLATFORMS_ROOT, "os:ios"),
+            paths.join(_PLATFORMS_ROOT, "os:macos"),
+            paths.join(_PLATFORMS_ROOT, "os:tvos"),
+            paths.join(_PLATFORMS_ROOT, "os:visionos"),
+            paths.join(_PLATFORMS_ROOT, "os:watchos"),
         ],
     ),
     "_legacy_any_type_attrs": attr.string_list(default = ["stamp"]),
diff --git a/java/common/rules/java_import.bzl b/java/common/rules/java_import.bzl
index 029f0ab..4a22b2a 100644
--- a/java/common/rules/java_import.bzl
+++ b/java/common/rules/java_import.bzl
@@ -16,8 +16,8 @@
 Definition of java_import rule.
 """
 
-load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
+load("//java/private:java_info.bzl", "JavaInfo")
 
 # copybara: default visibility
 
diff --git a/java/common/rules/java_library.bzl b/java/common/rules/java_library.bzl
index cc6b749..77861ac 100644
--- a/java/common/rules/java_library.bzl
+++ b/java/common/rules/java_library.bzl
@@ -17,9 +17,9 @@
 """
 
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
-load("//java/common:java_info.bzl", "JavaInfo")
-load("//java/common:java_plugin_info.bzl", "JavaPluginInfo")
 load("//java/common:java_semantics.bzl", "semantics")
+load("//java/private:java_common.bzl", "java_common")
+load("//java/private:java_info.bzl", "JavaInfo", "JavaPluginInfo")
 load(":basic_java_library.bzl", "BASIC_JAVA_LIBRARY_IMPLICIT_ATTRS")
 load(":rule_util.bzl", "merge_attrs")
 
diff --git a/java/common/rules/java_package_configuration.bzl b/java/common/rules/java_package_configuration.bzl
index 49b2405..0752e41 100644
--- a/java/common/rules/java_package_configuration.bzl
+++ b/java/common/rules/java_package_configuration.bzl
@@ -14,15 +14,12 @@
 
 """Implementation for the java_package_configuration rule"""
 
-load("//java/common:java_common.bzl", "java_common")
 load("//java/common/rules/impl:java_helper.bzl", "helper")
+load("//java/private:boot_class_path_info.bzl", "BootClassPathInfo")
+load("//java/private:native.bzl", "get_internal_java_common")
 
 # copybara: default visibility
 
-_java_common_internal = java_common.internal_DO_NOT_USE()
-
-BootClassPathInfo = java_common.BootClassPathInfo
-
 JavaPackageConfigurationInfo = provider(
     "A provider for Java per-package configuration",
     fields = [
@@ -41,7 +38,7 @@
     return False
 
 def _rule_impl(ctx):
-    javacopts = _java_common_internal.expand_java_opts(ctx, "javacopts", tokenize = True)
+    javacopts = get_internal_java_common().expand_java_opts(ctx, "javacopts", tokenize = True)
     javacopts_depset = helper.detokenize_javacopts(javacopts)
     package_specs = [package[PackageSpecificationInfo] for package in ctx.attr.packages]
     system = ctx.attr.system[BootClassPathInfo] if ctx.attr.system else None
@@ -50,7 +47,7 @@
         JavaPackageConfigurationInfo(
             data = depset(ctx.files.data),
             javac_opts = javacopts_depset,
-            matches = lambda label: _matches(package_specs, label),
+            matches = _matches,
             package_specs = package_specs,
             system = system,
         ),
diff --git a/java/common/rules/java_runtime.bzl b/java/common/rules/java_runtime.bzl
index 602819b..fa0bd52 100644
--- a/java/common/rules/java_runtime.bzl
+++ b/java/common/rules/java_runtime.bzl
@@ -18,7 +18,7 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
-load("//java/common:java_semantics.bzl", "PLATFORMS_ROOT")
+load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules/impl:java_helper.bzl", "helper")
 
 # copybara: default visibility
@@ -249,7 +249,7 @@
         # buildifier: disable=attr-licenses
         "output_licenses": attr.license() if hasattr(attr, "license") else attr.string_list(),
         "_windows_constraints": attr.label_list(
-            default = [paths.join(PLATFORMS_ROOT, "os:windows")],
+            default = [paths.join(semantics.PLATFORMS_ROOT, "os:windows")],
         ),
     },
     fragments = ["java"],
diff --git a/java/common/rules/java_toolchain.bzl b/java/common/rules/java_toolchain.bzl
index 174733d..829386f 100644
--- a/java/common/rules/java_toolchain.bzl
+++ b/java/common/rules/java_toolchain.bzl
@@ -18,6 +18,8 @@
 
 load("//java/common:java_semantics.bzl", "semantics")
 load("//java/common/rules/impl:java_helper.bzl", "helper")
+load("//java/private:boot_class_path_info.bzl", "BootClassPathInfo")
+load("//java/private:java_info.bzl", "JavaPluginDataInfo")
 load(":java_package_configuration.bzl", "JavaPackageConfigurationInfo")
 load(":java_runtime.bzl", "JavaRuntimeInfo")
 
@@ -25,8 +27,6 @@
 
 _java_common_internal = java_common.internal_DO_NOT_USE()
 ToolchainInfo = platform_common.ToolchainInfo
-BootClassPathInfo = java_common.BootClassPathInfo
-JavaPluginDataInfo = _java_common_internal.JavaPluginDataInfo
 
 def _java_toolchain_info_init(**_kwargs):
     fail("JavaToolchainInfo instantiation is a private API")
diff --git a/java/extensions.bzl b/java/extensions.bzl
index 0530aa2..f456f3f 100644
--- a/java/extensions.bzl
+++ b/java/extensions.bzl
@@ -16,7 +16,6 @@
 load("@bazel_features//:features.bzl", "bazel_features")
 load(
     "//java:repositories.bzl",
-    "compatibility_proxy_repo",
     "java_tools_repos",
     "local_jdk_repo",
     "remote_jdk11_repos",
@@ -39,8 +38,3 @@
         return None
 
 toolchains = module_extension(_toolchains_impl)
-
-def _compat_proxy_impl(_unused):
-    compatibility_proxy_repo()
-
-compatibility_proxy = module_extension(_compat_proxy_impl)
diff --git a/java/private/BUILD b/java/private/BUILD
index 8197421..af9edbe 100644
--- a/java/private/BUILD
+++ b/java/private/BUILD
@@ -15,16 +15,17 @@
     srcs = [
         "boot_class_path_info.bzl",
         "java_common.bzl",
+        "java_common_internal.bzl",
         "java_info.bzl",
         "message_bundle_info.bzl",
     ],
     visibility = ["//java:__subpackages__"],
     deps = [
         ":native_bzl",
-        "//java/common",
         "//java/common/rules:toolchain_rules",
         "//java/common/rules/impl:java_helper_bzl",
         "@bazel_skylib//lib:paths",
+        "@rules_cc//cc:find_cc_toolchain_bzl",
         "@rules_cc//cc/common",
     ],
 )
@@ -48,6 +49,7 @@
     testonly = 1,
     srcs = [
         "BUILD",
+        ":internals",
         ":native_bzl",
         ":proto_support",
     ],
diff --git a/java/private/boot_class_path_info.bzl b/java/private/boot_class_path_info.bzl
index 7280da3..f742e8f 100644
--- a/java/private/boot_class_path_info.bzl
+++ b/java/private/boot_class_path_info.bzl
@@ -18,7 +18,9 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 
-visibility("private")
+visibility(
+    ["//java/..."],
+)
 
 def _init(bootclasspath = [], auxiliary = [], system = None):
     """The <code>BootClassPathInfo</code> constructor.
diff --git a/java/private/java_common.bzl b/java/private/java_common.bzl
index 5175ac5..ebaa35d 100644
--- a/java/private/java_common.bzl
+++ b/java/private/java_common.bzl
@@ -21,6 +21,11 @@
 load("//java/common/rules/impl:java_helper.bzl", "helper")
 load(":boot_class_path_info.bzl", "BootClassPathInfo")
 load(
+    ":java_common_internal.bzl",
+    _compile_internal = "compile",
+    _run_ijar_internal = "run_ijar",
+)
+load(
     ":java_info.bzl",
     "JavaInfo",
     "JavaPluginInfo",
@@ -30,11 +35,9 @@
     _java_info_set_annotation_processing = "set_annotation_processing",
 )
 load(":message_bundle_info.bzl", "MessageBundleInfo")
-load(":native.bzl", _native_java_common = "native_java_common")
+load(":native.bzl", "get_internal_java_common")
 
-visibility("private")
-
-_java_common_internal = _native_java_common.internal_DO_NOT_USE()
+# copybara: default visibility
 
 JavaRuntimeClasspathInfo = provider(
     "Provider for the runtime classpath contributions of a Java binary.",
@@ -65,7 +68,7 @@
         enable_annotation_processing = True,
         add_exports = [],
         add_opens = []):
-    return _java_common_internal.compile(
+    return _compile_internal(
         ctx,
         output,
         java_toolchain,
@@ -92,8 +95,8 @@
     )
 
 def _run_ijar(actions, jar, java_toolchain, target_label = None):
-    _java_common_internal.check_java_toolchain_is_declared_on_rule(actions)
-    return _java_common_internal.run_ijar_private_for_builtins(
+    get_internal_java_common().check_java_toolchain_is_declared_on_rule(actions)
+    return _run_ijar_internal(
         actions = actions,
         jar = jar,
         java_toolchain = java_toolchain,
@@ -117,7 +120,7 @@
         (File) The output artifact
 
     """
-    _java_common_internal.check_java_toolchain_is_declared_on_rule(actions)
+    get_internal_java_common().check_java_toolchain_is_declared_on_rule(actions)
     output = actions.declare_file(paths.replace_extension(jar.basename, "-stamped.jar"), sibling = jar)
     args = actions.args()
     args.add(jar)
@@ -156,7 +159,7 @@
     Returns:
         (File) The output artifact
     """
-    _java_common_internal.check_java_toolchain_is_declared_on_rule(actions)
+    get_internal_java_common().check_java_toolchain_is_declared_on_rule(actions)
     return helper.create_single_jar(
         actions,
         toolchain = java_toolchain,
@@ -287,7 +290,7 @@
         # (discouraged) use of --experimental_google_legacy_api.
         return None
 
-    _java_common_internal.check_provider_instances([java_toolchain], "java_toolchain", JavaToolchainInfo)
+    get_internal_java_common().check_provider_instances([java_toolchain], "java_toolchain", JavaToolchainInfo)
     return java_toolchain.label
 
 def _make_java_common():
@@ -307,7 +310,7 @@
         "BootClassPathInfo": BootClassPathInfo,
         "JavaRuntimeClasspathInfo": JavaRuntimeClasspathInfo,
     }
-    if _java_common_internal.google_legacy_api_enabled():
+    if get_internal_java_common().google_legacy_api_enabled():
         methods.update(
             MessageBundleInfo = _get_message_bundle_info(),  # struct field that is None in bazel
             add_constraints = _add_constraints,
diff --git a/java/private/java_common_internal.bzl b/java/private/java_common_internal.bzl
new file mode 100644
index 0000000..78a8ee2
--- /dev/null
+++ b/java/private/java_common_internal.bzl
@@ -0,0 +1,435 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""" Private utilities for Java compilation support in Starlark. """
+
+load("@bazel_skylib//lib:paths.bzl", "paths")
+load("//java/common:java_semantics.bzl", "semantics")
+load("//java/common/rules:java_toolchain.bzl", "JavaToolchainInfo")
+load("//java/common/rules/impl:java_helper.bzl", "helper")
+load(
+    ":java_info.bzl",
+    "JavaPluginInfo",
+    "disable_plugin_info_annotation_processing",
+    "java_info_for_compilation",
+    "merge_plugin_info_without_outputs",
+)
+load(":native.bzl", "get_internal_java_common")
+
+visibility([
+    "//java/...",
+])
+
+def compile(
+        ctx,
+        output,
+        java_toolchain,
+        source_jars = [],
+        source_files = [],
+        output_source_jar = None,
+        javac_opts = [],
+        deps = [],
+        runtime_deps = [],
+        exports = [],
+        plugins = [],
+        exported_plugins = [],
+        native_libraries = [],
+        annotation_processor_additional_inputs = [],
+        annotation_processor_additional_outputs = [],
+        strict_deps = "ERROR",
+        bootclasspath = None,
+        javabuilder_jvm_flags = None,
+        sourcepath = [],
+        resources = [],
+        add_exports = [],
+        add_opens = [],
+        neverlink = False,
+        enable_annotation_processing = True,
+        # private to @_builtins:
+        enable_compile_jar_action = True,
+        enable_jspecify = True,
+        include_compilation_info = True,
+        classpath_resources = [],
+        resource_jars = [],
+        injecting_rule_kind = None):
+    """Compiles Java source files/jars from the implementation of a Starlark rule
+
+    The result is a provider that represents the results of the compilation and can be added to the
+    set of providers emitted by this rule.
+
+    Args:
+        ctx: (RuleContext) The rule context
+        output: (File) The output of compilation
+        java_toolchain: (JavaToolchainInfo) Toolchain to be used for this compilation. Mandatory.
+        source_jars: ([File]) A list of the jars to be compiled. At least one of source_jars or
+            source_files should be specified.
+        source_files: ([File]) A list of the Java source files to be compiled. At least one of
+            source_jars or source_files should be specified.
+        output_source_jar: (File) The output source jar. Optional. Defaults to
+            `{output_jar}-src.jar` if unset.
+        javac_opts: ([str]|depset[str]) A list of the desired javac options. Optional.
+        deps: ([JavaInfo]) A list of dependencies. Optional.
+        runtime_deps: ([JavaInfo]) A list of runtime dependencies. Optional.
+        exports: ([JavaInfo]) A list of exports. Optional.
+        plugins: ([JavaPluginInfo|JavaInfo]) A list of plugins. Optional.
+        exported_plugins: ([JavaPluginInfo|JavaInfo]) A list of exported plugins. Optional.
+        native_libraries: ([CcInfo]) CC library dependencies that are needed for this library.
+        annotation_processor_additional_inputs: ([File]) A list of inputs that the Java compilation
+            action will take in addition to the Java sources for annotation processing.
+        annotation_processor_additional_outputs: ([File]) A list of outputs that the Java
+            compilation action will output in addition to the class jar from annotation processing.
+        strict_deps: (str) A string that specifies how to handle strict deps. Possible values:
+            'OFF', 'ERROR', 'WARN' and 'DEFAULT'.
+        bootclasspath: (BootClassPathInfo) If present, overrides the bootclasspath associated with
+            the provided java_toolchain. Optional.
+        javabuilder_jvm_flags: (list[str]) Additional JVM flags to pass to JavaBuilder.
+        sourcepath: ([File])
+        resources: ([File])
+        resource_jars: ([File])
+        classpath_resources: ([File])
+        neverlink: (bool)
+        enable_annotation_processing: (bool) Disables annotation processing in this compilation,
+            causing any annotation processors provided in plugins or in exported_plugins of deps to
+            be ignored.
+        enable_compile_jar_action: (bool) Enables header compilation or ijar creation. If set to
+            False, it forces use of the full class jar in the compilation classpaths of any
+            dependants. Doing so is intended for use by non-library targets such as binaries that
+            do not have dependants.
+        enable_jspecify: (bool)
+        include_compilation_info: (bool)
+        injecting_rule_kind: (str|None)
+        add_exports: ([str]) Allow this library to access the given <module>/<package>. Optional.
+        add_opens: ([str]) Allow this library to reflectively access the given <module>/<package>.
+             Optional.
+
+    Returns:
+        (JavaInfo)
+    """
+    get_internal_java_common().check_provider_instances([java_toolchain], "java_toolchain", JavaToolchainInfo)
+    get_internal_java_common().check_provider_instances(plugins, "plugins", JavaPluginInfo)
+
+    plugin_info = merge_plugin_info_without_outputs(plugins + deps)
+
+    all_javac_opts = []  # [depset[str]]
+    all_javac_opts.append(java_toolchain._javacopts)
+
+    all_javac_opts.append(ctx.fragments.java.default_javac_flags_depset)
+    all_javac_opts.append(semantics.compatible_javac_options(ctx, java_toolchain))
+
+    if ("com.google.devtools.build.runfiles.AutoBazelRepositoryProcessor" in
+        plugin_info.plugins.processor_classes.to_list()):
+        all_javac_opts.append(depset(
+            ["-Abazel.repository=" + ctx.label.workspace_name],
+            order = "preorder",
+        ))
+    system_bootclasspath = None
+    for package_config in java_toolchain._package_configuration:
+        if package_config.matches(package_config.package_specs, ctx.label):
+            all_javac_opts.append(package_config.javac_opts)
+            if package_config.system:
+                if system_bootclasspath:
+                    fail("Multiple system package configurations found for %s" % ctx.label)
+                system_bootclasspath = package_config.system
+    if not bootclasspath:
+        bootclasspath = system_bootclasspath
+
+    all_javac_opts.append(depset(
+        ["--add-exports=%s=ALL-UNNAMED" % x for x in add_exports],
+        order = "preorder",
+    ))
+
+    if type(javac_opts) == type([]):
+        # detokenize target's javacopts, it will be tokenized before compilation
+        all_javac_opts.append(helper.detokenize_javacopts(helper.tokenize_javacopts(ctx, javac_opts)))
+    elif type(javac_opts) == type(depset()):
+        all_javac_opts.append(javac_opts)
+    else:
+        fail("Expected javac_opts to be a list or depset, got:", type(javac_opts))
+
+    # we reverse the list of javacopts depsets, so that we keep the right-most set
+    # in case it's deduped. When this depset is flattened, we will reverse again,
+    # and then tokenize before passing to javac. This way, right-most javacopts will
+    # be retained and "win out".
+    all_javac_opts = depset(order = "preorder", transitive = reversed(all_javac_opts))
+
+    # Optimization: skip this if there are no annotation processors, to avoid unnecessarily
+    # disabling the direct classpath optimization if `enable_annotation_processor = False`
+    # but there aren't any annotation processors.
+    enable_direct_classpath = True
+    if not enable_annotation_processing and plugin_info.plugins.processor_classes:
+        plugin_info = disable_plugin_info_annotation_processing(plugin_info)
+        enable_direct_classpath = False
+
+    all_javac_opts_list = helper.tokenize_javacopts(ctx, all_javac_opts)
+    uses_annotation_processing = False
+    if "-processor" in all_javac_opts_list or plugin_info.plugins.processor_classes:
+        uses_annotation_processing = True
+
+    has_sources = source_files or source_jars
+    has_resources = resources or resource_jars
+
+    is_strict_mode = strict_deps != "OFF"
+    classpath_mode = ctx.fragments.java.reduce_java_classpath()
+
+    direct_jars = depset()
+    if is_strict_mode:
+        direct_jars = depset(order = "preorder", transitive = [dep.compile_jars for dep in deps])
+    compilation_classpath = depset(
+        order = "preorder",
+        transitive = [direct_jars] + [dep.transitive_compile_time_jars for dep in deps],
+    )
+    compile_time_java_deps = depset()
+    if is_strict_mode and classpath_mode != "OFF":
+        compile_time_java_deps = depset(transitive = [dep._compile_time_java_dependencies for dep in deps])
+
+    # create compile time jar action
+    if not has_sources:
+        compile_jar = None
+        compile_deps_proto = None
+    elif not enable_compile_jar_action:
+        compile_jar = output
+        compile_deps_proto = None
+    elif _should_use_header_compilation(ctx, java_toolchain):
+        compile_jar = helper.derive_output_file(ctx, output, name_suffix = "-hjar", extension = "jar")
+        compile_deps_proto = helper.derive_output_file(ctx, output, name_suffix = "-hjar", extension = "jdeps")
+        get_internal_java_common().create_header_compilation_action(
+            ctx,
+            java_toolchain,
+            compile_jar,
+            compile_deps_proto,
+            plugin_info,
+            depset(source_files),
+            source_jars,
+            compilation_classpath,
+            direct_jars,
+            bootclasspath,
+            compile_time_java_deps,
+            all_javac_opts,
+            strict_deps,
+            ctx.label,
+            injecting_rule_kind,
+            enable_direct_classpath,
+            annotation_processor_additional_inputs,
+        )
+    elif ctx.fragments.java.use_ijars():
+        compile_jar = run_ijar(
+            ctx.actions,
+            output,
+            java_toolchain,
+            target_label = ctx.label,
+            injecting_rule_kind = injecting_rule_kind,
+        )
+        compile_deps_proto = None
+    else:
+        compile_jar = output
+        compile_deps_proto = None
+
+    native_headers_jar = helper.derive_output_file(ctx, output, name_suffix = "-native-header")
+    manifest_proto = helper.derive_output_file(ctx, output, extension_suffix = "_manifest_proto")
+    deps_proto = None
+    if ctx.fragments.java.generate_java_deps() and has_sources:
+        deps_proto = helper.derive_output_file(ctx, output, extension = "jdeps")
+    generated_class_jar = None
+    generated_source_jar = None
+    if uses_annotation_processing:
+        generated_class_jar = helper.derive_output_file(ctx, output, name_suffix = "-gen")
+        generated_source_jar = helper.derive_output_file(ctx, output, name_suffix = "-gensrc")
+    get_internal_java_common().create_compilation_action(
+        ctx,
+        java_toolchain,
+        output,
+        manifest_proto,
+        plugin_info,
+        compilation_classpath,
+        direct_jars,
+        bootclasspath,
+        depset(javabuilder_jvm_flags),
+        compile_time_java_deps,
+        all_javac_opts,
+        strict_deps,
+        ctx.label,
+        deps_proto,
+        generated_class_jar,
+        generated_source_jar,
+        native_headers_jar,
+        depset(source_files),
+        source_jars,
+        resources,
+        depset(resource_jars),
+        classpath_resources,
+        sourcepath,
+        injecting_rule_kind,
+        enable_jspecify,
+        enable_direct_classpath,
+        annotation_processor_additional_inputs,
+        annotation_processor_additional_outputs,
+    )
+
+    create_output_source_jar = len(source_files) > 0 or source_jars != [output_source_jar]
+    if not output_source_jar:
+        output_source_jar = helper.derive_output_file(ctx, output, name_suffix = "-src", extension = "jar")
+    if create_output_source_jar:
+        helper.create_single_jar(
+            ctx.actions,
+            toolchain = java_toolchain,
+            output = output_source_jar,
+            sources = depset(source_jars + ([generated_source_jar] if generated_source_jar else [])),
+            resources = depset(source_files),
+            progress_message = "Building source jar %{output}",
+            mnemonic = "JavaSourceJar",
+        )
+
+    if has_sources or has_resources:
+        direct_runtime_jars = [output]
+    else:
+        direct_runtime_jars = []
+
+    compilation_info = struct(
+        javac_options = all_javac_opts,
+        # needs to be flattened because the public API is a list
+        boot_classpath = (bootclasspath.bootclasspath if bootclasspath else java_toolchain.bootclasspath).to_list(),
+        # we only add compile time jars from deps, and not exports
+        compilation_classpath = compilation_classpath,
+        runtime_classpath = depset(
+            order = "preorder",
+            direct = direct_runtime_jars,
+            transitive = [dep.transitive_runtime_jars for dep in runtime_deps + deps],
+        ),
+        uses_annotation_processing = uses_annotation_processing,
+    ) if include_compilation_info else None
+
+    return java_info_for_compilation(
+        output_jar = output,
+        compile_jar = compile_jar,
+        source_jar = output_source_jar,
+        generated_class_jar = generated_class_jar,
+        generated_source_jar = generated_source_jar,
+        plugin_info = plugin_info,
+        deps = deps,
+        runtime_deps = runtime_deps,
+        exports = exports,
+        exported_plugins = exported_plugins,
+        compile_jdeps = compile_deps_proto if compile_deps_proto else deps_proto,
+        jdeps = deps_proto if include_compilation_info else None,
+        native_headers_jar = native_headers_jar,
+        manifest_proto = manifest_proto,
+        native_libraries = native_libraries,
+        neverlink = neverlink,
+        add_exports = add_exports,
+        add_opens = add_opens,
+        direct_runtime_jars = direct_runtime_jars,
+        compilation_info = compilation_info,
+    )
+
+def _should_use_header_compilation(ctx, toolchain):
+    if not ctx.fragments.java.use_header_compilation():
+        return False
+    if toolchain._forcibly_disable_header_compilation:
+        return False
+    if not toolchain._header_compiler:
+        fail(
+            "header compilation was requested but it is not supported by the " +
+            "current Java toolchain '" + str(toolchain.label) +
+            "'; see the java_toolchain.header_compiler attribute",
+        )
+    if not toolchain._header_compiler_direct:
+        fail(
+            "header compilation was requested but it is not supported by the " +
+            "current Java toolchain '" + str(toolchain.label) +
+            "'; see the java_toolchain.header_compiler_direct attribute",
+        )
+    return True
+
+def run_ijar(
+        actions,
+        jar,
+        java_toolchain,
+        target_label = None,
+        # private to @_builtins:
+        output = None,
+        injecting_rule_kind = None):
+    """Runs ijar on a jar, stripping it of its method bodies.
+
+    This helps reduce rebuilding of dependent jars during any recompiles consisting only of simple
+    changes to method implementations. The return value is typically passed to JavaInfo.compile_jar
+
+    Args:
+        actions: (actions) ctx.actions
+        jar: (File) The jar to run ijar on.
+        java_toolchain: (JavaToolchainInfo) The toolchain to used to find the ijar tool.
+        target_label: (Label|None) A target label to stamp the jar with. Used for `add_dep` support.
+            Typically, you would pass `ctx.label` to stamp the jar with the current rule's label.
+        output: (File) Optional.
+        injecting_rule_kind: (str) the rule class of the current target
+    Returns:
+        (File) The output artifact
+    """
+    if not output:
+        output = actions.declare_file(paths.replace_extension(jar.basename, "-ijar.jar"), sibling = jar)
+    args = actions.args()
+    args.add(jar)
+    args.add(output)
+    if target_label != None:
+        args.add("--target_label", target_label)
+    if injecting_rule_kind != None:
+        args.add("--injecting_rule_kind", injecting_rule_kind)
+
+    actions.run(
+        mnemonic = "JavaIjar",
+        inputs = [jar],
+        outputs = [output],
+        executable = java_toolchain.ijar,
+        arguments = [args],
+        progress_message = "Extracting interface for jar %{input}",
+        toolchain = semantics.JAVA_TOOLCHAIN_TYPE,
+        use_default_shell_env = True,
+    )
+    return output
+
+def target_kind(target):
+    """Get the rule class string for a target
+
+    Args:
+        target: (Target)
+
+    Returns:
+        (str) The rule class string of the target
+    """
+    return get_internal_java_common().target_kind(target)
+
+def collect_native_deps_dirs(libraries):
+    """Collect the set of root-relative paths containing native libraries
+
+    Args:
+        libraries: (depset[LibraryToLink]) set of native libraries
+
+    Returns:
+        ([String]) A set of root-relative paths as a list
+    """
+    return get_internal_java_common().collect_native_deps_dirs(libraries)
+
+def get_runtime_classpath_for_archive(jars, excluded_jars):
+    """Filters a classpath to remove certain entries
+
+    Args
+        jars: (depset[File]) The classpath to filter
+        excluded_jars: (depset[File]) The files to remove
+
+    Returns:
+        (depset[File]) The filtered classpath
+    """
+    return get_internal_java_common().get_runtime_classpath_for_archive(
+        jars,
+        excluded_jars,
+    )
diff --git a/java/private/java_info.bzl b/java/private/java_info.bzl
index f55020f..8ba655e 100644
--- a/java/private/java_info.bzl
+++ b/java/private/java_info.bzl
@@ -19,14 +19,9 @@
 load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
 load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
 load("//java/common:java_semantics.bzl", "semantics")
-load(":native.bzl", _native_java_common = "native_java_common")
+load(":native.bzl", "get_internal_java_common")
 
-visibility("private")
-
-# TODO(hvd): remove this when:
-# - we have a general provider-type checking API
-# - no longer need to check for --experimental_google_legacy_api
-_java_common_internal = _native_java_common.internal_DO_NOT_USE()
+# copybara: default visibility
 
 _JavaOutputInfo = provider(
     doc = "The outputs of Java compilation.",
@@ -175,7 +170,7 @@
         "compilation_info": None,
     }
 
-    if _java_common_internal.google_legacy_api_enabled():
+    if get_internal_java_common().google_legacy_api_enabled():
         cc_info = semantics.minimize_cc_info(cc_common.merge_cc_infos(cc_infos = [p.cc_link_params_info for p in providers]))
         result.update(
             cc_link_params_info = cc_info,
@@ -188,7 +183,7 @@
                 transitive = [p.transitive_native_libraries for p in providers],
             ),
         )
-    return _java_common_internal.wrap_java_info(_new_javainfo(**result))
+    return get_internal_java_common().wrap_java_info(_new_javainfo(**result))
 
 def to_java_binary_info(java_info, compilation_info):
     """Get a copy of the given JavaInfo with minimal info returned by a java_binary
@@ -496,10 +491,10 @@
             compilation_info = None,
             annotation_processing = None,
         )
-    return _java_common_internal.wrap_java_info(_new_javainfo(**result))
+    return get_internal_java_common().wrap_java_info(_new_javainfo(**result))
 
 def _validate_provider_list(provider_list, what, expected_provider_type):
-    _java_common_internal.check_provider_instances(provider_list, what, expected_provider_type)
+    get_internal_java_common().check_provider_instances(provider_list, what, expected_provider_type)
 
 def _compute_concatenated_deps(deps, runtime_deps, exports):
     deps_exports = []
@@ -627,7 +622,7 @@
         "_constraints": [],
     }
 
-    if _java_common_internal.google_legacy_api_enabled():
+    if get_internal_java_common().google_legacy_api_enabled():
         transitive_cc_infos = [dep.cc_link_params_info for dep in concatenated_deps.runtimedeps_exports_deps]
         transitive_cc_infos.extend(native_libraries)
         cc_info = semantics.minimize_cc_info(cc_common.merge_cc_infos(cc_infos = transitive_cc_infos))
@@ -737,7 +732,7 @@
     # TODO: When this flag is removed, move this logic into _javainfo_init_base
     #  and remove the special case from java_info_for_compilation.
     module_flags_deps = concatenated_deps.deps_exports
-    if _java_common_internal._incompatible_java_info_merge_runtime_module_flags():
+    if get_internal_java_common().incompatible_java_info_merge_runtime_module_flags():
         module_flags_deps = concatenated_deps.runtimedeps_exports_deps
 
     result.update(
diff --git a/java/private/native.bzl b/java/private/native.bzl
index 64a4d5a..22f84ff 100644
--- a/java/private/native.bzl
+++ b/java/private/native.bzl
@@ -21,6 +21,8 @@
 
 """Lovely workaround to be able to expose native constants pretending to be Starlark."""
 
+# Unused with Bazel@HEAD, used by the compatibility layer for older Bazel versions
+
 # buildifier: disable=native-java
 native_java_common = java_common
 
@@ -29,3 +31,10 @@
 
 # buildifier: disable=native-java
 NativeJavaPluginInfo = JavaPluginInfo
+
+# Used for some private native APIs that we can't replicate just yet in Starlark
+# getattr() for loading this file with Bazel 6, where we won't use this
+def get_internal_java_common():
+    if hasattr(native_java_common, "internal_DO_NOT_USE"):
+        return native_java_common.internal_DO_NOT_USE()
+    return None
diff --git a/java/private/proto_support.bzl b/java/private/proto_support.bzl
index 8666e5a..dcb8f09 100644
--- a/java/private/proto_support.bzl
+++ b/java/private/proto_support.bzl
@@ -13,13 +13,13 @@
 # limitations under the License.
 """Support for Java compilation of protocol buffer generated code."""
 
-load("//java/private:native.bzl", "native_java_common")
+load("//java/common:java_common.bzl", "java_common")
 
 # Partial support, because internal symbols are not available in older Bazel version
 # TODO: Once Java rules are moved into the rules_java, this should become a full support.
 
 def compile(*, injecting_rule_kind, enable_jspecify, include_compilation_info, **kwargs):  # buildifier: disable=unused-variable
-    return native_java_common.compile(**kwargs)
+    return java_common.compile(**kwargs)
 
 def merge(providers, *, merge_java_outputs = True, merge_source_jars = True):  # buildifier: disable=unused-variable
-    return native_java_common.merge(providers)
+    return java_common.merge(providers)
diff --git a/java/repositories.bzl b/java/repositories.bzl
index 60f94ef..f02b0f6 100644
--- a/java/repositories.bzl
+++ b/java/repositories.bzl
@@ -362,51 +362,9 @@
     """Imports OpenJDK 21 repositories."""
     _remote_jdk_repos_for_version("21")
 
-def protobuf_repo():
-    maybe(
-        http_archive,
-        name = "com_google_protobuf",
-        sha256 = "ce5d00b78450a0ca400bf360ac00c0d599cc225f049d986a27e9a4e396c5a84a",
-        strip_prefix = "protobuf-29.0-rc2",
-        url = "https://github.com/protocolbuffers/protobuf/releases/download/v29.0-rc2/protobuf-29.0-rc2.tar.gz",
-    )
-
-def rules_cc_repo():
-    maybe(
-        http_archive,
-        name = "rules_cc",
-        sha256 = "f4aadd8387f381033a9ad0500443a52a0cea5f8ad1ede4369d3c614eb7b2682e",
-        strip_prefix = "rules_cc-0.0.15",
-        urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.15/rules_cc-0.0.15.tar.gz"],
-    )
-
-def bazel_skylib_repo():
-    maybe(
-        http_archive,
-        name = "bazel_skylib",
-        sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
-        urls = [
-            "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
-            "https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
-        ],
-    )
-
 def rules_java_dependencies():
-    """An utility method to load all dependencies of rules_java.
-
-    Loads the remote repositories used by default in Bazel.
-    """
-
-    local_jdk_repo()
-    remote_jdk8_repos()
-    remote_jdk11_repos()
-    remote_jdk17_repos()
-    remote_jdk21_repos()
-    java_tools_repos()
-    compatibility_proxy_repo()
-    protobuf_repo()
-    rules_cc_repo()
-    bazel_skylib_repo()
+    """DEPRECATED: No-op, kept for backwards compatibility"""
+    print("DEPRECATED: use rules_java_dependencies() from rules_java_deps.bzl")  # buildifier: disable=print
 
 def rules_java_toolchains(name = "toolchains"):
     """An utility method to load all Java toolchains.
@@ -414,6 +372,13 @@
     Args:
         name: The name of this macro (not used)
     """
+    local_jdk_repo()
+    remote_jdk8_repos()
+    remote_jdk11_repos()
+    remote_jdk17_repos()
+    remote_jdk21_repos()
+    java_tools_repos()
+
     native.register_toolchains(
         "//toolchains:all",
         "@local_jdk//:runtime_toolchain_definition",
@@ -425,51 +390,3 @@
                 "@" + item.name + "_toolchain_config_repo//:toolchain",
                 "@" + item.name + "_toolchain_config_repo//:bootstrap_runtime_toolchain",
             )
-
-def _compatibility_proxy_repo_impl(rctx):
-    # TODO: use @bazel_features
-    bazel = native.bazel_version
-    rctx.file("BUILD.bazel", "")
-    if not bazel or bazel >= "8":
-        rctx.file(
-            "proxy.bzl",
-            """
-load("@rules_java//java/bazel/rules:bazel_java_binary_wrapper.bzl", _java_binary = "java_binary") # copybara-use-repo-external-label
-load("@rules_java//java/bazel/rules:bazel_java_import.bzl", _java_import = "java_import") # copybara-use-repo-external-label
-load("@rules_java//java/bazel/rules:bazel_java_library.bzl", _java_library = "java_library") # copybara-use-repo-external-label
-load("@rules_java//java/bazel/rules:bazel_java_plugin.bzl", _java_plugin = "java_plugin") # copybara-use-repo-external-label
-load("@rules_java//java/bazel/rules:bazel_java_test.bzl", _java_test = "java_test") # copybara-use-repo-external-label
-load("@rules_java//java:http_jar.bzl", _http_jar = "http_jar") # copybara-use-repo-external-label
-
-java_binary = _java_binary
-java_import = _java_import
-java_library = _java_library
-java_plugin = _java_plugin
-java_test = _java_test
-
-http_jar = _http_jar
-            """,
-        )
-    else:
-        rctx.file(
-            "proxy.bzl",
-            """
-load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_jar = "http_jar")
-java_binary = native.java_binary
-java_import = native.java_import
-java_library = native.java_library
-java_plugin = native.java_plugin
-java_test = native.java_test
-
-http_jar = _http_jar
-            """,
-        )
-
-_compatibility_proxy_repo_rule = repository_rule(
-    _compatibility_proxy_repo_impl,
-    # force reruns on server restarts to use correct native.bazel_version
-    local = True,
-)
-
-def compatibility_proxy_repo():
-    maybe(_compatibility_proxy_repo_rule, name = "compatibility_proxy")
diff --git a/java/rules_java_deps.bzl b/java/rules_java_deps.bzl
new file mode 100644
index 0000000..5520ba1
--- /dev/null
+++ b/java/rules_java_deps.bzl
@@ -0,0 +1,117 @@
+"""Module extension for compatibility with previous Bazel versions"""
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
+
+def _compatibility_proxy_repo_impl(rctx):
+    # TODO: use @bazel_features
+    bazel = native.bazel_version
+    rctx.file("BUILD.bazel", "")
+    if not bazel or bazel >= "8":
+        rctx.file(
+            "proxy.bzl",
+            """
+load("@rules_java//java/bazel/rules:bazel_java_binary_wrapper.bzl", _java_binary = "java_binary") # copybara-use-repo-external-label
+load("@rules_java//java/bazel/rules:bazel_java_import.bzl", _java_import = "java_import") # copybara-use-repo-external-label
+load("@rules_java//java/bazel/rules:bazel_java_library.bzl", _java_library = "java_library") # copybara-use-repo-external-label
+load("@rules_java//java/bazel/rules:bazel_java_plugin.bzl", _java_plugin = "java_plugin") # copybara-use-repo-external-label
+load("@rules_java//java/bazel/rules:bazel_java_test.bzl", _java_test = "java_test") # copybara-use-repo-external-label
+load("@rules_java//java/common/rules:java_package_configuration.bzl", _java_package_configuration = "java_package_configuration") # copybara-use-repo-external-label
+load("@rules_java//java/common/rules:java_runtime.bzl", _java_runtime = "java_runtime") # copybara-use-repo-external-label
+load("@rules_java//java/common/rules:java_toolchain.bzl", _java_toolchain = "java_toolchain") # copybara-use-repo-external-label
+load("@rules_java//java/private:java_common.bzl", _java_common = "java_common") # copybara-use-repo-external-label
+load("@rules_java//java/private:java_info.bzl", _JavaInfo = "JavaInfo", _JavaPluginInfo = "JavaPluginInfo") # copybara-use-repo-external-label
+load("@rules_java//java:http_jar.bzl", _http_jar = "http_jar") # copybara-use-repo-external-label
+
+java_binary = _java_binary
+java_import = _java_import
+java_library = _java_library
+java_plugin = _java_plugin
+java_test = _java_test
+java_package_configuration = _java_package_configuration
+java_runtime = _java_runtime
+java_toolchain = _java_toolchain
+java_common = _java_common
+JavaInfo = _JavaInfo
+JavaPluginInfo = _JavaPluginInfo
+
+http_jar = _http_jar
+            """,
+        )
+    else:
+        rctx.file(
+            "proxy.bzl",
+            """
+load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_jar = "http_jar")
+load("@rules_java//java/private:native.bzl", "native_java_common", "NativeJavaInfo", "NativeJavaPluginInfo") # copybara-use-repo-external-label
+
+java_binary = native.java_binary
+java_import = native.java_import
+java_library = native.java_library
+java_plugin = native.java_plugin
+java_test = native.java_test
+
+java_package_configuration = native.java_package_configuration
+java_runtime = native.java_runtime
+java_toolchain = native.java_toolchain
+
+java_common = native_java_common
+JavaInfo = NativeJavaInfo
+JavaPluginInfo = NativeJavaPluginInfo
+
+http_jar = _http_jar
+            """,
+        )
+
+_compatibility_proxy_repo_rule = repository_rule(
+    _compatibility_proxy_repo_impl,
+    # force reruns on server restarts to use correct native.bazel_version
+    local = True,
+)
+
+def compatibility_proxy_repo():
+    maybe(_compatibility_proxy_repo_rule, name = "compatibility_proxy")
+
+def _compat_proxy_impl(_unused):
+    compatibility_proxy_repo()
+
+compatibility_proxy = module_extension(_compat_proxy_impl)
+
+def protobuf_repo():
+    maybe(
+        http_archive,
+        name = "com_google_protobuf",
+        sha256 = "ce5d00b78450a0ca400bf360ac00c0d599cc225f049d986a27e9a4e396c5a84a",
+        strip_prefix = "protobuf-29.0-rc2",
+        url = "https://github.com/protocolbuffers/protobuf/releases/download/v29.0-rc2/protobuf-29.0-rc2.tar.gz",
+    )
+
+def rules_cc_repo():
+    maybe(
+        http_archive,
+        name = "rules_cc",
+        sha256 = "f4aadd8387f381033a9ad0500443a52a0cea5f8ad1ede4369d3c614eb7b2682e",
+        strip_prefix = "rules_cc-0.0.15",
+        urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.15/rules_cc-0.0.15.tar.gz"],
+    )
+
+def bazel_skylib_repo():
+    maybe(
+        http_archive,
+        name = "bazel_skylib",
+        sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
+        urls = [
+            "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
+            "https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
+        ],
+    )
+
+def rules_java_dependencies():
+    """An utility method to load non-toolchain dependencies of rules_java.
+
+    Loads the remote repositories used by default in Bazel.
+    """
+    compatibility_proxy_repo()
+    bazel_skylib_repo()
+    rules_cc_repo()
+    protobuf_repo()
diff --git a/java/toolchains/java_package_configuration.bzl b/java/toolchains/java_package_configuration.bzl
index 09d8e1e..7ef0728 100644
--- a/java/toolchains/java_package_configuration.bzl
+++ b/java/toolchains/java_package_configuration.bzl
@@ -13,6 +13,8 @@
 # limitations under the License.
 """java_package_configuration rule"""
 
+load("@compatibility_proxy//:proxy.bzl", _java_package_configuration = "java_package_configuration")
+
 def java_package_configuration(**attrs):
     """Bazel java_package_configuration rule.
 
@@ -22,5 +24,4 @@
       **attrs: Rule attributes
     """
 
-    # buildifier: disable=native-java
-    native.java_package_configuration(**attrs)
+    _java_package_configuration(**attrs)
diff --git a/java/toolchains/java_runtime.bzl b/java/toolchains/java_runtime.bzl
index 3657a88..c1d1641 100644
--- a/java/toolchains/java_runtime.bzl
+++ b/java/toolchains/java_runtime.bzl
@@ -13,6 +13,8 @@
 # limitations under the License.
 """java_runtime rule"""
 
+load("@compatibility_proxy//:proxy.bzl", _java_runtime = "java_runtime")
+
 def java_runtime(**attrs):
     """Bazel java_runtime rule.
 
@@ -22,5 +24,4 @@
       **attrs: Rule attributes
     """
 
-    # buildifier: disable=native-java
-    native.java_runtime(**attrs)
+    _java_runtime(**attrs)
diff --git a/java/toolchains/java_toolchain.bzl b/java/toolchains/java_toolchain.bzl
index 5b07292..5207f8c 100644
--- a/java/toolchains/java_toolchain.bzl
+++ b/java/toolchains/java_toolchain.bzl
@@ -13,6 +13,8 @@
 # limitations under the License.
 """java_toolchain rule"""
 
+load("@compatibility_proxy//:proxy.bzl", _java_toolchain = "java_toolchain")
+
 def java_toolchain(**attrs):
     """Bazel java_toolchain rule.
 
@@ -22,5 +24,4 @@
       **attrs: Rule attributes
     """
 
-    # buildifier: disable=native-java
-    native.java_toolchain(**attrs)
+    _java_toolchain(**attrs)
diff --git a/test/repo/WORKSPACE b/test/repo/WORKSPACE
index c4f22a6..aa3b7cb 100644
--- a/test/repo/WORKSPACE
+++ b/test/repo/WORKSPACE
@@ -5,7 +5,7 @@
     path = "../../",
 )
 
-load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
+load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")
 
 rules_java_dependencies()
 
@@ -13,6 +13,8 @@
 
 proto_bazel_features(name = "proto_bazel_features")
 
+load("@rules_java//java:repositories.bzl", "rules_java_toolchains")
+
 rules_java_toolchains()
 
 load("@compatibility_proxy//:proxy.bzl", "http_jar")