From 27a03e0dc3e08094aebc3524f68617f7e7fb5c5d Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 8 Mar 2024 11:21:24 +0000 Subject: [PATCH] 8327218: Add an ability to specify modules which should have native access enabled Co-authored-by: Maurizio Cimadamore Reviewed-by: mcimadamore, erikj, alanb, ihse --- make/conf/module-loader-map.conf | 49 ++++++++++++++++++- .../tools/module/GenModuleLoaderMap.java | 8 ++- .../gensrc/GensrcModuleLoaderMap.gmk | 9 ++-- .../share/classes/java/lang/Module.java | 6 +-- .../share/classes/java/lang/ModuleLayer.java | 20 +++++++- .../share/classes/java/lang/System.java | 3 ++ .../jdk/internal/access/JavaLangAccess.java | 8 ++- .../jdk/internal/module/ModuleBootstrap.java | 33 ++++++++----- .../jdk/internal/module/ModuleLoaderMap.java | 13 ++++- 9 files changed, 123 insertions(+), 26 deletions(-) diff --git a/make/conf/module-loader-map.conf b/make/conf/module-loader-map.conf index ca09d23b02b..5b72bf78aa0 100644 --- a/make/conf/module-loader-map.conf +++ b/make/conf/module-loader-map.conf @@ -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. # # This code is free software; you can redistribute it and/or modify it @@ -91,3 +91,50 @@ PLATFORM_MODULES= \ PLATFORM_MODULES_windows= \ 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 \ + # diff --git a/make/jdk/src/classes/build/tools/module/GenModuleLoaderMap.java b/make/jdk/src/classes/build/tools/module/GenModuleLoaderMap.java index c6c90e0fb59..aea74cc1dc0 100644 --- a/make/jdk/src/classes/build/tools/module/GenModuleLoaderMap.java +++ b/make/jdk/src/classes/build/tools/module/GenModuleLoaderMap.java @@ -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. * * 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 Stream bootModules = Stream.empty(); Stream platformModules = Stream.empty(); + Stream nativeAccessModules = Stream.empty(); Path outfile = null; Path source = null; for (int i=0; i < args.length; i++) { @@ -60,6 +61,9 @@ public class GenModuleLoaderMap { } else if (option.equals("-platform")) { String[] mns = arg.split(","); 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")) { outfile = Paths.get(arg); } else { @@ -84,6 +88,8 @@ public class GenModuleLoaderMap { line = patch(line, "@@BOOT_MODULE_NAMES@@", bootModules); } else if (line.contains("@@PLATFORM_MODULE_NAMES@@")) { 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); } diff --git a/make/modules/java.base/gensrc/GensrcModuleLoaderMap.gmk b/make/modules/java.base/gensrc/GensrcModuleLoaderMap.gmk index e248e680d46..4ec9ee587cc 100644 --- a/make/modules/java.base/gensrc/GensrcModuleLoaderMap.gmk +++ b/make/modules/java.base/gensrc/GensrcModuleLoaderMap.gmk @@ -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. # # This code is free software; you can redistribute it and/or modify it @@ -37,8 +37,9 @@ $(strip \ endef BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_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) ############################################################################ @@ -49,7 +50,9 @@ $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java: $(call MakeTargetDir) $(RM) $@ $@.tmp $(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 $@ TARGETS += $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java index 7157ace8c47..82dae27efa0 100644 --- a/src/java.base/share/classes/java/lang/Module.java +++ b/src/java.base/share/classes/java/lang/Module.java @@ -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. * * 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); Object[] packages = descriptor.packages().toArray(); defineModule0(this, isOpen, vs, loc, packages); - if (loader == null || loader == ClassLoaders.platformClassLoader()) { - // boot/builtin modules are always native - implAddEnableNativeAccess(); - } } diff --git a/src/java.base/share/classes/java/lang/ModuleLayer.java b/src/java.base/share/classes/java/lang/ModuleLayer.java index 814cdeb7e6d..3a13982c9b9 100644 --- a/src/java.base/share/classes/java/lang/ModuleLayer.java +++ b/src/java.base/share/classes/java/lang/ModuleLayer.java @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -881,6 +881,24 @@ public final class ModuleLayer { .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 diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 39ecb2a6436..bd77a3149ae 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2459,6 +2459,9 @@ public final class System { public Module addEnableNativeAccess(Module m) { return m.implAddEnableNativeAccess(); } + public boolean addEnableNativeAccess(ModuleLayer layer, String name) { + return layer.addEnableNativeAccess(name); + } public void addEnableNativeAccessToAllUnnamed() { Module.implAddEnableNativeAccessToAllUnnamed(); } diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 93815009a54..86fd4c8414d 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -269,6 +269,12 @@ public interface JavaLangAccess { */ 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. */ 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 0279c8438a0..b97b0a2de40 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, 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. * * 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 Set NATIVE_ACCESS_MODULES; + private static final Set USER_NATIVE_ACCESS_MODULES; + private static final Set JDK_NATIVE_ACCESS_MODULES; public static boolean hasEnableNativeAccessFlag() { return HAS_ENABLE_NATIVE_ACCESS_FLAG; } static { - NATIVE_ACCESS_MODULES = decodeEnableNativeAccess(); - HAS_ENABLE_NATIVE_ACCESS_FLAG = !NATIVE_ACCESS_MODULES.isEmpty(); + USER_NATIVE_ACCESS_MODULES = decodeEnableNativeAccess(); + 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) { - 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 moduleNames, boolean shouldWarn) { + for (String name : moduleNames) { if (name.equals("ALL-UNNAMED")) { JLA.addEnableNativeAccessToAllUnnamed(); - } else { - Optional module = layer.findModule(name); - if (module.isPresent()) { - JLA.addEnableNativeAccess(module.get()); - } else { - warnUnknownModule(ENABLE_NATIVE_ACCESS, name); - } + } else if (!JLA.addEnableNativeAccess(layer, name) && shouldWarn) { + warnUnknownModule(ENABLE_NATIVE_ACCESS, name); } } } diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java b/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java index a23a72dacec..a8b5eda709e 100644 --- a/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -110,6 +110,13 @@ public final class ModuleLoaderMap { return Modules.platformModules; } + /** + * Returns the names of the modules defined to the application loader which perform native access. + */ + public static Set nativeAccessModules() { + return Modules.nativeAccessModules; + } + private static class Modules { // list of boot modules is generated at build time. private static final Set bootModules = @@ -118,6 +125,10 @@ public final class ModuleLoaderMap { // list of platform modules is generated at build time. private static final Set platformModules = Set.of(new String[] { "@@PLATFORM_MODULE_NAMES@@" }); + + // list of jdk modules is generated at build time. + private static final Set nativeAccessModules = + Set.of(new String[] { "@@NATIVE_ACCESS_MODULE_NAMES@@" }); } /**