Merge pull request #133 from fmeum:java-bin-path

PiperOrigin-RevId: 571283599
Change-Id: I778b51950acbe2f39bcb0426a5712bdb25a8c370
diff --git a/MODULE.bazel b/MODULE.bazel
index 5436b67..fdd86cd 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -55,8 +55,8 @@
         "win",
         "win_arm64",
     ],
-    # Must match JDK repos defined in remote_jdk20_repos()
-    "20": [
+    # Must match JDK repos defined in remote_jdk21_repos()
+    "21": [
         "linux",
         "linux_aarch64",
         "macos",
diff --git a/java/BUILD b/java/BUILD
index 9e6bd30..a42b374 100644
--- a/java/BUILD
+++ b/java/BUILD
@@ -22,3 +22,12 @@
     srcs = ["java_single_jar.bzl"],
     visibility = ["//visibility:public"],
 )
+
+filegroup(
+    name = "for_bazel_tests",
+    srcs = [
+        "BUILD",
+        ":java_single_jar",
+    ],
+    visibility = ["//visibility:public"],
+)
diff --git a/java/extensions.bzl b/java/extensions.bzl
index 5e456ed..0fff36b 100644
--- a/java/extensions.bzl
+++ b/java/extensions.bzl
@@ -13,13 +13,13 @@
 # limitations under the License.
 """Module extensions for rules_java."""
 
-load("//java:repositories.bzl", "java_tools_repos", "local_jdk_repo", "remote_jdk11_repos", "remote_jdk17_repos", "remote_jdk20_repos")
+load("//java:repositories.bzl", "java_tools_repos", "local_jdk_repo", "remote_jdk11_repos", "remote_jdk17_repos", "remote_jdk21_repos")
 
 def _toolchains_impl(_ctx):
     java_tools_repos()
     local_jdk_repo()
     remote_jdk11_repos()
     remote_jdk17_repos()
-    remote_jdk20_repos()
+    remote_jdk21_repos()
 
 toolchains = module_extension(implementation = _toolchains_impl)
diff --git a/java/proto/BUILD b/java/proto/BUILD
new file mode 100644
index 0000000..c6b4b50
--- /dev/null
+++ b/java/proto/BUILD
@@ -0,0 +1,7 @@
+package(default_visibility = ["//visibility:public"])
+
+# Toolchain type provided by proto_lang_toolchain rule and used by java_proto_library
+toolchain_type(name = "toolchain_type")
+
+# Toolchain type provided by proto_lang_toolchain rule and used by java_lite_proto_library
+toolchain_type(name = "lite_toolchain_type")
diff --git a/java/repositories.bzl b/java/repositories.bzl
index bd2c19f..292447a 100644
--- a/java/repositories.bzl
+++ b/java/repositories.bzl
@@ -442,85 +442,85 @@
         version = "17",
     )
 
-def remote_jdk20_repos():
-    """Imports OpenJDK 20 repositories."""
+def remote_jdk21_repos():
+    """Imports OpenJDK 21 repositories."""
     maybe(
         remote_java_repository,
-        name = "remotejdk20_linux",
+        name = "remotejdk21_linux",
         target_compatible_with = [
             "@platforms//os:linux",
             "@platforms//cpu:x86_64",
         ],
-        sha256 = "0386418db7f23ae677d05045d30224094fc13423593ce9cd087d455069893bac",
-        strip_prefix = "zulu20.28.85-ca-jdk20.0.0-linux_x64",
+        sha256 = "0c0eadfbdc47a7ca64aeab51b9c061f71b6e4d25d2d87674512e9b6387e9e3a6",
+        strip_prefix = "zulu21.28.85-ca-jdk21.0.0-linux_x64",
         urls = [
-            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_x64.tar.gz",
-            "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_x64.tar.gz",
+            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_x64.tar.gz",
+            "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_x64.tar.gz",
         ],
-        version = "20",
+        version = "21",
     )
 
     maybe(
         remote_java_repository,
-        name = "remotejdk20_linux_aarch64",
+        name = "remotejdk21_linux_aarch64",
         target_compatible_with = [
             "@platforms//os:linux",
             "@platforms//cpu:aarch64",
         ],
-        sha256 = "47ce58ead9a05d5d53b96706ff6fa0eb2e46755ee67e2b416925e28f5b55038a",
-        strip_prefix = "zulu20.28.85-ca-jdk20.0.0-linux_aarch64",
+        sha256 = "1fb64b8036c5d463d8ab59af06bf5b6b006811e6012e3b0eb6bccf57f1c55835",
+        strip_prefix = "zulu21.28.85-ca-jdk21.0.0-linux_aarch64",
         urls = [
-            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_aarch64.tar.gz",
-            "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_aarch64.tar.gz",
+            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_aarch64.tar.gz",
+            "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_aarch64.tar.gz",
         ],
-        version = "20",
+        version = "21",
     )
 
     maybe(
         remote_java_repository,
-        name = "remotejdk20_macos",
+        name = "remotejdk21_macos",
         target_compatible_with = [
             "@platforms//os:macos",
             "@platforms//cpu:x86_64",
         ],
-        sha256 = "fde6cc17a194ea0d9b0c6c0cb6178199d8edfc282d649eec2c86a9796e843f86",
-        strip_prefix = "zulu20.28.85-ca-jdk20.0.0-macosx_x64",
+        sha256 = "9639b87db586d0c89f7a9892ae47f421e442c64b97baebdff31788fbe23265bd",
+        strip_prefix = "zulu21.28.85-ca-jdk21.0.0-macosx_x64",
         urls = [
-            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_x64.tar.gz",
-            "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_x64.tar.gz",
+            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_x64.tar.gz",
+            "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_x64.tar.gz",
         ],
-        version = "20",
+        version = "21",
     )
 
     maybe(
         remote_java_repository,
-        name = "remotejdk20_macos_aarch64",
+        name = "remotejdk21_macos_aarch64",
         target_compatible_with = [
             "@platforms//os:macos",
             "@platforms//cpu:aarch64",
         ],
-        sha256 = "a2eff6a940c2df3a2352278027e83f5959f34dcfc8663034fe92be0f1b91ce6f",
-        strip_prefix = "zulu20.28.85-ca-jdk20.0.0-macosx_aarch64",
+        sha256 = "2a7a99a3ea263dbd8d32a67d1e6e363ba8b25c645c826f5e167a02bbafaff1fa",
+        strip_prefix = "zulu21.28.85-ca-jdk21.0.0-macosx_aarch64",
         urls = [
-            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_aarch64.tar.gz",
-            "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_aarch64.tar.gz",
+            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_aarch64.tar.gz",
+            "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_aarch64.tar.gz",
         ],
-        version = "20",
+        version = "21",
     )
     maybe(
         remote_java_repository,
-        name = "remotejdk20_win",
+        name = "remotejdk21_win",
         target_compatible_with = [
             "@platforms//os:windows",
             "@platforms//cpu:x86_64",
         ],
-        sha256 = "ac5f6a7d84dbbb0bb4d376feb331cc4c49a9920562f2a5e85b7a6b4863b10e1e",
-        strip_prefix = "zulu20.28.85-ca-jdk20.0.0-win_x64",
+        sha256 = "e9959d500a0d9a7694ac243baf657761479da132f0f94720cbffd092150bd802",
+        strip_prefix = "zulu21.28.85-ca-jdk21.0.0-win_x64",
         urls = [
-            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-win_x64.zip",
-            "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-win_x64.zip",
+            "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-win_x64.zip",
+            "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-win_x64.zip",
         ],
-        version = "20",
+        version = "21",
     )
 
 def rules_java_dependencies():
@@ -532,7 +532,7 @@
     local_jdk_repo()
     remote_jdk11_repos()
     remote_jdk17_repos()
-    remote_jdk20_repos()
+    remote_jdk21_repos()
     java_tools_repos()
 
 def rules_java_toolchains(name = "toolchains"):
@@ -546,8 +546,8 @@
         "11": ["linux", "linux_aarch64", "linux_ppc64le", "linux_s390x", "macos", "macos_aarch64", "win", "win_arm64"],
         # Must match JDK repos defined in remote_jdk17_repos()
         "17": ["linux", "linux_aarch64", "linux_ppc64le", "linux_s390x", "macos", "macos_aarch64", "win", "win_arm64"],
-        # Must match JDK repos defined in remote_jdk20_repos()
-        "20": ["linux", "linux_aarch64", "macos", "macos_aarch64", "win"],
+        # Must match JDK repos defined in remote_jdk21_repos()
+        "21": ["linux", "linux_aarch64", "macos", "macos_aarch64", "win"],
     }
 
     REMOTE_JDK_REPOS = [("remotejdk" + version + "_" + platform) for version in JDKS for platform in JDKS[version]]
diff --git a/toolchains/BUILD b/toolchains/BUILD
index b208e7b..c504589 100644
--- a/toolchains/BUILD
+++ b/toolchains/BUILD
@@ -305,13 +305,13 @@
     target_version = "17",
 )
 
-# A toolchain that targets java 20.
+# A toolchain that targets java 21.
 default_java_toolchain(
-    name = "toolchain_jdk_20",
+    name = "toolchain_jdk_21",
     configuration = dict(),
-    java_runtime = "//toolchains:remotejdk_20",
-    source_version = "20",
-    target_version = "20",
+    java_runtime = "//toolchains:remotejdk_21",
+    source_version = "21",
+    target_version = "21",
 )
 
 default_java_toolchain(
@@ -346,8 +346,8 @@
 )
 
 java_runtime_version_alias(
-    name = "remotejdk_20",
-    runtime_version = "remotejdk_20",
+    name = "remotejdk_21",
+    runtime_version = "remotejdk_21",
     visibility = ["//visibility:public"],
 )
 
diff --git a/toolchains/DumpPlatformClassPath.java b/toolchains/DumpPlatformClassPath.java
index fafb843..4707e89 100644
--- a/toolchains/DumpPlatformClassPath.java
+++ b/toolchains/DumpPlatformClassPath.java
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.util.Context;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -21,13 +19,19 @@
 import java.io.OutputStream;
 import java.io.UncheckedIOException;
 import java.lang.reflect.Method;
+import java.net.URI;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.EnumSet;
 import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.Map;
@@ -38,11 +42,6 @@
 import java.util.jar.JarOutputStream;
 import java.util.zip.CRC32;
 import java.util.zip.ZipEntry;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
 
 /**
  * Output a jar file containing all classes on the platform classpath of the given JDK release.
@@ -98,50 +97,35 @@
       return true;
     }
 
-    // Initialize a FileManager to process the --system argument, and then read the
-    // initialized bootclasspath data back out.
-
-    Context context = new Context();
-    try {
-      JavacTool.create()
-          .getTask(
-              /* out = */ null,
-              /* fileManager = */ null,
-              /* diagnosticListener = */ null,
-              /* options = */ Arrays.asList("--system", String.valueOf(targetJavabase)),
-              /* classes = */ null,
-              /* compilationUnits = */ null,
-              context);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException(
-          String.format(
-              "Failed to collect system class path. Please ensure that the configured Java runtime"
-                  + " ('%s') is a complete JDK. There are known issues with Homebrew versions of"
-                  + " the Java runtime.",
-              targetJavabase.toRealPath()),
-          e);
+    // Read the bootclasspath data using the JRT filesystem
+    Map<String, byte[]> entries = new TreeMap<>();
+    Map<String, String> env = new TreeMap<>();
+    env.put("java.home", String.valueOf(targetJavabase));
+    try (FileSystem fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), env)) {
+      Path modules = fileSystem.getPath("/modules");
+      try (DirectoryStream<Path> ms = Files.newDirectoryStream(modules)) {
+        for (Path m : ms) {
+          Files.walkFileTree(
+              m,
+              new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+                  if (file.getFileName().toString().endsWith(".class")) {
+                    entries.put(m.relativize(file).toString(), Files.readAllBytes(file));
+                  }
+                  return super.visitFile(file, attrs);
+                }
+              });
+        }
+      }
+      writeEntries(output, entries);
     }
-    StandardJavaFileManager fileManager =
-        (StandardJavaFileManager) context.get(JavaFileManager.class);
-
-    SortedMap<String, InputStream> entries = new TreeMap<>();
-    for (JavaFileObject fileObject :
-        fileManager.list(
-            StandardLocation.PLATFORM_CLASS_PATH,
-            "",
-            EnumSet.of(Kind.CLASS),
-            /* recurse= */ true)) {
-      String binaryName =
-          fileManager.inferBinaryName(StandardLocation.PLATFORM_CLASS_PATH, fileObject);
-      entries.put(binaryName.replace('.', '/') + ".class", fileObject.openInputStream());
-    }
-    writeEntries(output, entries);
     return true;
   }
 
   /** Writes the given entry names and data to a jar archive at the given path. */
-  private static void writeEntries(Path output, Map<String, InputStream> entries)
-      throws IOException {
+  private static void writeEntries(Path output, Map<String, byte[]> entries) throws IOException {
     if (!entries.containsKey("java/lang/Object.class")) {
       throw new AssertionError(
           "\nCould not find java.lang.Object on bootclasspath; something has gone terribly wrong.\n"
@@ -168,14 +152,14 @@
     for (Path path : paths) {
       jars.add(new JarFile(path.toFile()));
     }
-    SortedMap<String, InputStream> entries = new TreeMap<>();
+    SortedMap<String, byte[]> entries = new TreeMap<>();
     for (JarFile jar : jars) {
       jar.stream()
           .filter(p -> p.getName().endsWith(".class"))
           .forEachOrdered(
               entry -> {
                 try {
-                  entries.put(entry.getName(), jar.getInputStream(entry));
+                  entries.put(entry.getName(), toByteArray(jar.getInputStream(entry)));
                 } catch (IOException e) {
                   throw new UncheckedIOException(e);
                 }
@@ -214,12 +198,10 @@
    * Add a jar entry to the given {@link JarOutputStream}, normalizing the entry timestamps to
    * ensure deterministic build output.
    */
-  private static void addEntry(JarOutputStream jos, String name, InputStream input)
-      throws IOException {
+  private static void addEntry(JarOutputStream jos, String name, byte[] bytes) throws IOException {
     JarEntry je = new JarEntry(name);
     je.setTime(FIXED_TIMESTAMP);
     je.setMethod(ZipEntry.STORED);
-    byte[] bytes = toByteArray(input);
     // When targeting JDK >= 10, patch the major version so it will be accepted by javac 9
     // TODO(cushon): remove this after updating javac
     if (bytes[7] > 53) {
@@ -266,4 +248,4 @@
     throw new IllegalStateException(
         "Unknown Java version: " + System.getProperty("java.specification.version"));
   }
-}
+}
\ No newline at end of file
diff --git a/toolchains/default_java_toolchain.bzl b/toolchains/default_java_toolchain.bzl
index 788f91d..8e28187 100644
--- a/toolchains/default_java_toolchain.bzl
+++ b/toolchains/default_java_toolchain.bzl
@@ -92,7 +92,7 @@
     reduced_classpath_incompatible_processors = [
         "dagger.hilt.processor.internal.root.RootProcessor",  # see b/21307381
     ],
-    java_runtime = Label("//toolchains:remotejdk_17"),
+    java_runtime = Label("//toolchains:remotejdk_21"),
 )
 
 DEFAULT_TOOLCHAIN_CONFIGURATION = _BASE_TOOLCHAIN_CONFIGURATION