8327218: Add an ability to specify modules which should have native access enabled

Co-authored-by: Maurizio Cimadamore <mcimadamore@openjdk.org>
Reviewed-by: mcimadamore, erikj, alanb, ihse
This commit is contained in:
Jan Lahoda 2024-03-08 11:21:24 +00:00
parent d0d4912c3b
commit 27a03e0dc3
9 changed files with 123 additions and 26 deletions

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -91,3 +91,50 @@ PLATFORM_MODULES= \
PLATFORM_MODULES_windows= \ PLATFORM_MODULES_windows= \
jdk.crypto.mscapi \ jdk.crypto.mscapi \
# #
NATIVE_ACCESS_MODULES= \
java.base \
java.datatransfer \
java.desktop \
java.instrument \
java.logging \
java.management \
java.management.rmi \
java.naming \
java.net.http \
java.prefs \
java.rmi \
java.scripting \
java.se \
java.security.jgss \
java.security.sasl \
java.smartcardio \
java.sql \
java.sql.rowset \
java.transaction.xa \
java.xml \
java.xml.crypto \
jdk.accessibility \
jdk.charsets \
jdk.crypto.cryptoki \
jdk.dynalink \
jdk.httpserver \
jdk.incubator.vector \
jdk.internal.vm.ci \
jdk.jfr \
jdk.jsobject \
jdk.localedata \
jdk.management \
jdk.management.agent \
jdk.management.jfr \
jdk.naming.dns \
jdk.naming.rmi \
jdk.net \
jdk.nio.mapmode \
jdk.sctp \
jdk.security.auth \
jdk.security.jgss \
jdk.unsupported \
jdk.xml.dom \
jdk.zipfs \
#

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,7 @@ public class GenModuleLoaderMap {
// default set of boot modules and ext modules // default set of boot modules and ext modules
Stream<String> bootModules = Stream.empty(); Stream<String> bootModules = Stream.empty();
Stream<String> platformModules = Stream.empty(); Stream<String> platformModules = Stream.empty();
Stream<String> nativeAccessModules = Stream.empty();
Path outfile = null; Path outfile = null;
Path source = null; Path source = null;
for (int i=0; i < args.length; i++) { for (int i=0; i < args.length; i++) {
@ -60,6 +61,9 @@ public class GenModuleLoaderMap {
} else if (option.equals("-platform")) { } else if (option.equals("-platform")) {
String[] mns = arg.split(","); String[] mns = arg.split(",");
platformModules = Stream.concat(platformModules, Arrays.stream(mns)); platformModules = Stream.concat(platformModules, Arrays.stream(mns));
} else if (option.equals("-native-access")) {
String[] mns = arg.split(",");
nativeAccessModules = Stream.concat(nativeAccessModules, Arrays.stream(mns));
} else if (option.equals("-o")) { } else if (option.equals("-o")) {
outfile = Paths.get(arg); outfile = Paths.get(arg);
} else { } else {
@ -84,6 +88,8 @@ public class GenModuleLoaderMap {
line = patch(line, "@@BOOT_MODULE_NAMES@@", bootModules); line = patch(line, "@@BOOT_MODULE_NAMES@@", bootModules);
} else if (line.contains("@@PLATFORM_MODULE_NAMES@@")) { } else if (line.contains("@@PLATFORM_MODULE_NAMES@@")) {
line = patch(line, "@@PLATFORM_MODULE_NAMES@@", platformModules); line = patch(line, "@@PLATFORM_MODULE_NAMES@@", platformModules);
} else if (line.contains("@@NATIVE_ACCESS_MODULE_NAMES@@")) {
line = patch(line, "@@NATIVE_ACCESS_MODULE_NAMES@@", nativeAccessModules);
} }
writer.println(line); writer.println(line);
} }

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -37,8 +37,9 @@ $(strip \
endef endef
BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_MODULES)) BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_MODULES))
PLATFORM_MODULES_LIST := $(call SubstComma, $(PLATFORM_MODULES)) PLATFORM_MODULES_LIST := $(call SubstComma, $(PLATFORM_MODULES))
NATIVE_ACCESS_MODULES_LIST := $(call SubstComma, $(NATIVE_ACCESS_MODULES))
VARDEPS_VALUE := $(BOOT_MODULES_LIST) $(PLATFORM_MODULES_LIST) VARDEPS_VALUE := $(BOOT_MODULES_LIST) $(PLATFORM_MODULES_LIST) $(NATIVE_ACCESS_MODULES_LIST)
VARDEPS_FILE := $(call DependOnVariable, VARDEPS_VALUE) VARDEPS_FILE := $(call DependOnVariable, VARDEPS_VALUE)
############################################################################ ############################################################################
@ -49,7 +50,9 @@ $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java:
$(call MakeTargetDir) $(call MakeTargetDir)
$(RM) $@ $@.tmp $(RM) $@ $@.tmp
$(TOOL_GENCLASSLOADERMAP) -boot $(BOOT_MODULES_LIST) \ $(TOOL_GENCLASSLOADERMAP) -boot $(BOOT_MODULES_LIST) \
-platform $(PLATFORM_MODULES_LIST) -o $@.tmp $< -platform $(PLATFORM_MODULES_LIST) \
-native-access $(NATIVE_ACCESS_MODULES_LIST) \
-o $@.tmp $<
$(MV) $@.tmp $@ $(MV) $@.tmp $@
TARGETS += $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java TARGETS += $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -143,10 +143,6 @@ public final class Module implements AnnotatedElement {
String loc = Objects.toString(uri, null); String loc = Objects.toString(uri, null);
Object[] packages = descriptor.packages().toArray(); Object[] packages = descriptor.packages().toArray();
defineModule0(this, isOpen, vs, loc, packages); defineModule0(this, isOpen, vs, loc, packages);
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
// boot/builtin modules are always native
implAddEnableNativeAccess();
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -881,6 +881,24 @@ public final class ModuleLayer {
.findAny(); .findAny();
} }
/**
* Updates the module with the given {@code name} in this layer
* to allow access to restricted methods.
*
* @param name the name of the module for which the native access
* should be enabled
* @return {@code true} iff the module is present in this layer,
* {@code false} otherwise
*/
boolean addEnableNativeAccess(String name) {
Module m = nameToModule.get(name);
if (m != null) {
m.implAddEnableNativeAccess();
return true;
} else {
return false;
}
}
/** /**
* Returns the {@code ClassLoader} for the module with the given name. If * Returns the {@code ClassLoader} for the module with the given name. If

View file

@ -2459,6 +2459,9 @@ public final class System {
public Module addEnableNativeAccess(Module m) { public Module addEnableNativeAccess(Module m) {
return m.implAddEnableNativeAccess(); return m.implAddEnableNativeAccess();
} }
public boolean addEnableNativeAccess(ModuleLayer layer, String name) {
return layer.addEnableNativeAccess(name);
}
public void addEnableNativeAccessToAllUnnamed() { public void addEnableNativeAccessToAllUnnamed() {
Module.implAddEnableNativeAccessToAllUnnamed(); Module.implAddEnableNativeAccessToAllUnnamed();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -269,6 +269,12 @@ public interface JavaLangAccess {
*/ */
Module addEnableNativeAccess(Module m); Module addEnableNativeAccess(Module m);
/**
* Updates module named {@code name} in layer {@code layer} to allow access to restricted methods.
* Returns true iff the given module exists in the given layer.
*/
boolean addEnableNativeAccess(ModuleLayer layer, String name);
/** /**
* Updates all unnamed modules to allow access to restricted methods. * Updates all unnamed modules to allow access to restricted methods.
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -788,31 +788,38 @@ public final class ModuleBootstrap {
} }
private static final boolean HAS_ENABLE_NATIVE_ACCESS_FLAG; private static final boolean HAS_ENABLE_NATIVE_ACCESS_FLAG;
private static final Set<String> NATIVE_ACCESS_MODULES; private static final Set<String> USER_NATIVE_ACCESS_MODULES;
private static final Set<String> JDK_NATIVE_ACCESS_MODULES;
public static boolean hasEnableNativeAccessFlag() { public static boolean hasEnableNativeAccessFlag() {
return HAS_ENABLE_NATIVE_ACCESS_FLAG; return HAS_ENABLE_NATIVE_ACCESS_FLAG;
} }
static { static {
NATIVE_ACCESS_MODULES = decodeEnableNativeAccess(); USER_NATIVE_ACCESS_MODULES = decodeEnableNativeAccess();
HAS_ENABLE_NATIVE_ACCESS_FLAG = !NATIVE_ACCESS_MODULES.isEmpty(); HAS_ENABLE_NATIVE_ACCESS_FLAG = !USER_NATIVE_ACCESS_MODULES.isEmpty();
JDK_NATIVE_ACCESS_MODULES = ModuleLoaderMap.nativeAccessModules();
} }
/** /**
* Process the --enable-native-access option to grant access to restricted methods to selected modules. * Grants native access to modules selected using the --enable-native-access
* command line option, and also to JDK modules that need the access.
*/ */
private static void addEnableNativeAccess(ModuleLayer layer) { private static void addEnableNativeAccess(ModuleLayer layer) {
for (String name : NATIVE_ACCESS_MODULES) { addEnableNativeAccess(layer, USER_NATIVE_ACCESS_MODULES, true);
addEnableNativeAccess(layer, JDK_NATIVE_ACCESS_MODULES, false);
}
/**
* Grants native access for the given modules in the given layer.
* Warns optionally about modules that were specified, but not present in the layer.
*/
private static void addEnableNativeAccess(ModuleLayer layer, Set<String> moduleNames, boolean shouldWarn) {
for (String name : moduleNames) {
if (name.equals("ALL-UNNAMED")) { if (name.equals("ALL-UNNAMED")) {
JLA.addEnableNativeAccessToAllUnnamed(); JLA.addEnableNativeAccessToAllUnnamed();
} else { } else if (!JLA.addEnableNativeAccess(layer, name) && shouldWarn) {
Optional<Module> module = layer.findModule(name); warnUnknownModule(ENABLE_NATIVE_ACCESS, name);
if (module.isPresent()) {
JLA.addEnableNativeAccess(module.get());
} else {
warnUnknownModule(ENABLE_NATIVE_ACCESS, name);
}
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -110,6 +110,13 @@ public final class ModuleLoaderMap {
return Modules.platformModules; return Modules.platformModules;
} }
/**
* Returns the names of the modules defined to the application loader which perform native access.
*/
public static Set<String> nativeAccessModules() {
return Modules.nativeAccessModules;
}
private static class Modules { private static class Modules {
// list of boot modules is generated at build time. // list of boot modules is generated at build time.
private static final Set<String> bootModules = private static final Set<String> bootModules =
@ -118,6 +125,10 @@ public final class ModuleLoaderMap {
// list of platform modules is generated at build time. // list of platform modules is generated at build time.
private static final Set<String> platformModules = private static final Set<String> platformModules =
Set.of(new String[] { "@@PLATFORM_MODULE_NAMES@@" }); Set.of(new String[] { "@@PLATFORM_MODULE_NAMES@@" });
// list of jdk modules is generated at build time.
private static final Set<String> nativeAccessModules =
Set.of(new String[] { "@@NATIVE_ACCESS_MODULE_NAMES@@" });
} }
/** /**