From fec769b0a840ca4351e2458c24184ec69c112c09 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Tue, 14 Jan 2025 10:34:51 +0000 Subject: [PATCH] 8346778: Enable native access should work with the source launcher Reviewed-by: alanb --- make/conf/module-loader-map.conf | 3 +- .../jdk/internal/module/ModuleBootstrap.java | 10 ++++-- src/java.base/share/native/libjli/java.c | 4 ++- .../tools/javac/launcher/MemoryContext.java | 36 +++++++++++++++++-- .../javac/launcher/RelevantJavacOptions.java | 28 ++++++++++++--- .../launcher/ModuleSourceLauncherTests.java | 16 ++++++--- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/make/conf/module-loader-map.conf b/make/conf/module-loader-map.conf index b628bfbf2da..92bffc0e9bc 100644 --- a/make/conf/module-loader-map.conf +++ b/make/conf/module-loader-map.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -103,6 +103,7 @@ NATIVE_ACCESS_MODULES= \ java.smartcardio \ jdk.accessibility \ jdk.attach \ + jdk.compiler \ jdk.crypto.cryptoki \ jdk.crypto.mscapi \ jdk.hotspot.agent \ diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java index f5904915e26..e8a9281fbea 100644 --- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -834,9 +834,15 @@ public final class ModuleBootstrap { /** * Grants native access to modules selected using the --enable-native-access * command line option, and also to JDK modules that need the access. + *

+ * In case of being in "source" launcher mode, warnings about unknown modules are + * deferred to the source launcher logic in the jdk.compiler module, as those + * modules might be not compiled, yet. */ private static void addEnableNativeAccess(ModuleLayer layer) { - addEnableNativeAccess(layer, USER_NATIVE_ACCESS_MODULES, true); + String launcherMode = getAndRemoveProperty("sun.java.launcher.mode"); + boolean shouldWarn = !"source".equals(launcherMode); + addEnableNativeAccess(layer, USER_NATIVE_ACCESS_MODULES, shouldWarn); addEnableNativeAccess(layer, JDK_NATIVE_ACCESS_MODULES, false); } diff --git a/src/java.base/share/native/libjli/java.c b/src/java.base/share/native/libjli/java.c index e88d104452d..a36b91e29af 100644 --- a/src/java.base/share/native/libjli/java.c +++ b/src/java.base/share/native/libjli/java.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1374,6 +1374,8 @@ ParseArguments(int *pargc, char ***pargv, } if (mode == LM_SOURCE) { + // communicate the launcher mode to runtime + AddOption("-Dsun.java.launcher.mode=source", NULL); AddOption("--add-modules=ALL-DEFAULT", NULL); *pwhat = SOURCE_LAUNCHER_MAIN_ENTRY; // adjust (argc, argv) so that the name of the source file diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/MemoryContext.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/MemoryContext.java index 941f5c4c40e..5fa76c14d3f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/MemoryContext.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/MemoryContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,7 +208,9 @@ final class MemoryContext { var modulePathModules = modulePathFinder.findAll().stream().map(ModuleReference::descriptor).map(ModuleDescriptor::name).toList(); if (!modulePathModules.isEmpty()) { var modulePathConfiguration = bootLayer.configuration().resolveAndBind(modulePathFinder, ModuleFinder.of(), Set.copyOf(modulePathModules)); - var modulePathLayer = ModuleLayer.defineModulesWithOneLoader(modulePathConfiguration, List.of(bootLayer), parent).layer(); + var modulePathController = ModuleLayer.defineModulesWithOneLoader(modulePathConfiguration, List.of(bootLayer), parent); + enableNativeAccess(modulePathController, false); + var modulePathLayer = modulePathController.layer(); parentLayer = modulePathLayer; parentLoader = modulePathLayer.findLoader(modulePathModules.getFirst()); } @@ -226,6 +228,9 @@ final class MemoryContext { var mainClassNamePackageName = mainClassName.substring(0, lastDotInMainClassName); memoryController.addOpens(module, mainClassNamePackageName, getClass().getModule()); + // Configure native access for the modular application. + enableNativeAccess(memoryController, true); + return memoryLayer.findLoader(applicationModule.name()); } @@ -238,6 +243,33 @@ final class MemoryContext { return ModuleFinder.of(paths.toArray(Path[]::new)); } + /** + * Grants native access to modules selected using the --enable-native-access + * command line option. + */ + @SuppressWarnings("restricted") + private void enableNativeAccess(ModuleLayer.Controller controller, boolean shouldWarn) { + var layer = controller.layer(); + for (var name : options.enableNativeAccessForModules()) { + if (name.equals("ALL-UNNAMED")) { + continue; // was taken care of by module bootstrap + } + var found = layer.findModule(name); + if (found.isEmpty()) { + if (shouldWarn) { + // same message as ModuleBootstrap.warnUnknownModule(ENABLE_NATIVE_ACCESS, name); + out.println("WARNING: Unknown module: " + name + " specified to --enable-native-access"); + } + continue; + } + var module = found.get(); + if (module.isNativeAccessEnabled()) { + continue; + } + controller.enableNativeAccess(module); + } + } + static class MemoryPreview extends Preview { static void registerInstance(Context context) { context.put(previewKey, (Factory)MemoryPreview::new); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/RelevantJavacOptions.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/RelevantJavacOptions.java index f619807f9bf..2a07a20b6f9 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/RelevantJavacOptions.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/RelevantJavacOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,8 @@ import java.util.List; * or deletion without notice.

*/ record RelevantJavacOptions(List forProgramCompilation, - List forSubsequentCompilations) { + List forSubsequentCompilations, + List enableNativeAccessForModules) { /** * Returns the subset of the runtime arguments that are relevant to {@code javac}. @@ -55,6 +56,7 @@ record RelevantJavacOptions(List forProgramCompilation, static RelevantJavacOptions of(ProgramDescriptor program, String... runtimeArgs) throws Fault { var programOptions = new ArrayList(); var subsequentOptions = new ArrayList(); + var enableNativeAccessForModules = new ArrayList(); String sourceOpt = System.getProperty("jdk.internal.javac.source"); if (sourceOpt != null) { @@ -94,7 +96,7 @@ record RelevantJavacOptions(List forProgramCompilation, value = runtimeArgs[++i]; } if (opt.equals("--add-modules")) { - var modules = computeListOfAddModules(program, value); + var modules = computeListOfModules(program, value); if (modules.isEmpty()) { break; } @@ -117,6 +119,19 @@ record RelevantJavacOptions(List forProgramCompilation, subsequentOptions.addAll(List.of("--release", feature)); } } + case "--enable-native-access" -> { + if (value == null) { + if (i == runtimeArgs.length - 1) { + // should not happen when invoked from launcher + throw new Fault(Errors.NoValueForOption(opt)); + } + value = runtimeArgs[++i]; + } + var modules = computeListOfModules(program, value); + if (program.isModular()) { + enableNativeAccessForModules.addAll(modules); + } + } default -> { if (opt.startsWith("-agentlib:jdwp=") || opt.startsWith("-Xrunjdwp:")) { programOptions.add("-g"); @@ -145,10 +160,13 @@ record RelevantJavacOptions(List forProgramCompilation, subsequentOptions.add(option); }); - return new RelevantJavacOptions(List.copyOf(programOptions), List.copyOf(subsequentOptions)); + return new RelevantJavacOptions( + List.copyOf(programOptions), + List.copyOf(subsequentOptions), + List.copyOf(enableNativeAccessForModules)); } - private static List computeListOfAddModules(ProgramDescriptor program, String value) { + private static List computeListOfModules(ProgramDescriptor program, String value) { var modules = new ArrayList<>(List.of(value.split(","))); // these options are only supported at run time; // they are not required or supported at compile time diff --git a/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java b/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java index 42bed1d1e47..44ae29dccaa 100644 --- a/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java +++ b/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8304400 8332226 + * @bug 8304400 8332226 8346778 * @summary Test source launcher running Java programs contained in one module * @modules jdk.compiler/com.sun.tools.javac.launcher * @run junit ModuleSourceLauncherTests @@ -192,6 +192,8 @@ class ModuleSourceLauncherTests { class Prog1 { public static void main(String... args) { System.out.println(new foo.Foo()); + System.out.println("bar=" + Prog1.class.getModule().isNativeAccessEnabled()); + System.out.println("foo=" + foo.Foo.class.getModule().isNativeAccessEnabled()); } } """); @@ -199,6 +201,7 @@ class ModuleSourceLauncherTests { var command = List.of( Path.of(System.getProperty("java.home"), "bin", "java").toString(), "-p", ".", + "--enable-native-access", "foo,bar,baz,ALL-UNNAMED", "bar/bar/Prog1.java"); var redirectedOut = base.resolve("out.redirected"); var redirectedErr = base.resolve("err.redirected"); @@ -212,12 +215,17 @@ class ModuleSourceLauncherTests { var err = Files.readAllLines(redirectedErr); assertAll( - () -> assertEquals(0, code), + () -> assertEquals(0, code, out.toString()), () -> assertLinesMatch( """ Foo[] + bar=true + foo=true """.lines(), out.stream()), - () -> assertTrue(err.isEmpty()) + () -> assertLinesMatch( + """ + WARNING: Unknown module: baz specified to --enable-native-access + """.lines(), err.stream()) ); }