8346778: Enable native access should work with the source launcher

Reviewed-by: alanb
This commit is contained in:
Christian Stein 2025-01-14 10:34:51 +00:00
parent cbb2b847e4
commit fec769b0a8
6 changed files with 82 additions and 15 deletions

View File

@ -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 \

View File

@ -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.
* <p>
* 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);
}

View File

@ -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

View File

@ -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<Preview>)MemoryPreview::new);

View File

@ -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.</strong></p>
*/
record RelevantJavacOptions(List<String> forProgramCompilation,
List<String> forSubsequentCompilations) {
List<String> forSubsequentCompilations,
List<String> enableNativeAccessForModules) {
/**
* Returns the subset of the runtime arguments that are relevant to {@code javac}.
@ -55,6 +56,7 @@ record RelevantJavacOptions(List<String> forProgramCompilation,
static RelevantJavacOptions of(ProgramDescriptor program, String... runtimeArgs) throws Fault {
var programOptions = new ArrayList<String>();
var subsequentOptions = new ArrayList<String>();
var enableNativeAccessForModules = new ArrayList<String>();
String sourceOpt = System.getProperty("jdk.internal.javac.source");
if (sourceOpt != null) {
@ -94,7 +96,7 @@ record RelevantJavacOptions(List<String> 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<String> 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<String> 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<String> computeListOfAddModules(ProgramDescriptor program, String value) {
private static List<String> 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

View File

@ -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())
);
}