| /* | |
| * 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 | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| /* | |
| * @test | |
| * @summary Basic test for Enable-Native-Access attribute in the | |
| * manifest of a main application JAR | |
| * @library /test/lib | |
| * @requires jdk.foreign.linker != "UNSUPPORTED" | |
| * @requires !vm.musl | |
| * | |
| * @enablePreview | |
| * @build TestEnableNativeAccessJarManifest | |
| * panama_module/* | |
| * org.openjdk.foreigntest.unnamed.PanamaMainUnnamedModule | |
| * @run testng/native TestEnableNativeAccessJarManifest | |
| */ | |
| import java.nio.file.Files; | |
| import java.nio.file.Path; | |
| import java.nio.file.Paths; | |
| import java.util.List; | |
| import java.util.ArrayList; | |
| import java.util.jar.Attributes; | |
| import java.util.jar.Manifest; | |
| import jdk.test.lib.process.OutputAnalyzer; | |
| import jdk.test.lib.process.ProcessTools; | |
| import jdk.test.lib.util.JarUtils; | |
| import org.testng.annotations.Test; | |
| import org.testng.annotations.DataProvider; | |
| public class TestEnableNativeAccessJarManifest extends TestEnableNativeAccessBase { | |
| private static final String REINVOKER = "TestEnableNativeAccessJarManifest$Reinvoker"; | |
| static record Attribute(String name, String value) {} | |
| @Test(dataProvider = "cases") | |
| public void testEnableNativeAccessInJarManifest(String action, String cls, Result expectedResult, | |
| List<Attribute> attributes, List<String> vmArgs, List<String> programArgs) throws Exception { | |
| Manifest man = new Manifest(); | |
| Attributes attrs = man.getMainAttributes(); | |
| attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); | |
| attrs.put(Attributes.Name.MAIN_CLASS, cls); | |
| for (Attribute attrib : attributes) { | |
| attrs.put(new Attributes.Name(attrib.name()), attrib.value()); | |
| } | |
| // create the JAR file with Test1 and Test2 | |
| Path jarfile = Paths.get(action + ".jar"); | |
| Files.deleteIfExists(jarfile); | |
| Path classes = Paths.get(System.getProperty("test.classes", "")); | |
| JarUtils.createJarFile(jarfile, man, classes, Paths.get(cls.replace('.', '/') + ".class")); | |
| // java -jar test.jar | |
| List<String> command = new ArrayList<>(List.of( | |
| "-Djava.library.path=" + System.getProperty("java.library.path") | |
| )); | |
| command.addAll(vmArgs); | |
| command.add("-jar"); | |
| command.add(jarfile.toString()); | |
| command.addAll(programArgs); | |
| OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(command.toArray(String[]::new)) | |
| .outputTo(System.out) | |
| .errorTo(System.out); | |
| checkResult(expectedResult, outputAnalyzer); | |
| } | |
| @DataProvider | |
| public Object[][] cases() { | |
| return new Object[][] { | |
| // simple cases where a jar contains a single main class with no dependencies | |
| { "panama_no_unnamed_module_native_access", UNNAMED, successWithWarning("ALL-UNNAMED"), | |
| List.of(), List.of(), List.of() }, | |
| { "panama_unnamed_module_native_access", UNNAMED, successNoWarning(), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), List.of(), List.of() }, | |
| { "panama_unnamed_module_native_access_invalid", UNNAMED, | |
| failWithError("Error: illegal value \"asdf\" for Enable-Native-Access manifest attribute. Only ALL-UNNAMED is allowed"), | |
| List.of(new Attribute("Enable-Native-Access", "asdf")), List.of(), List.of() }, | |
| // more complex cases where a jar invokes a module on the module path that does native access | |
| { "panama_enable_native_access_false", REINVOKER, successWithWarning("panama_module"), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), | |
| List.of("-p", MODULE_PATH, "--add-modules=panama_module"), | |
| List.of(PANAMA_MAIN_CLS) }, | |
| { "panama_enable_native_access_reflection_false", REINVOKER, successWithWarning("panama_module"), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), | |
| List.of("-p", MODULE_PATH, "--add-modules=panama_module"), | |
| List.of(PANAMA_REFLECTION_CLS) }, | |
| { "panama_enable_native_access_invoke_false", REINVOKER, successWithWarning("panama_module"), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), | |
| List.of("-p", MODULE_PATH, "--add-modules=panama_module"), | |
| List.of(PANAMA_INVOKE_CLS) }, | |
| { "panama_enable_native_access_true", REINVOKER, successNoWarning(), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), | |
| List.of("-p", MODULE_PATH, "--add-modules=panama_module", "--enable-native-access=panama_module"), | |
| List.of(PANAMA_MAIN_CLS) }, | |
| { "panama_enable_native_access_reflection_true", REINVOKER, successNoWarning(), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), | |
| List.of("-p", MODULE_PATH, "--add-modules=panama_module", "--enable-native-access=panama_module"), | |
| List.of(PANAMA_REFLECTION_CLS) }, | |
| { "panama_enable_native_access_invoke_true", REINVOKER, successNoWarning(), | |
| List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), | |
| List.of("-p", MODULE_PATH, "--add-modules=panama_module", "--enable-native-access=panama_module"), | |
| List.of(PANAMA_INVOKE_CLS) } | |
| }; | |
| } | |
| public class Reinvoker { | |
| public static void main(String[] args) throws Throwable { | |
| Class<?> realMainClass = Class.forName(args[0]); | |
| realMainClass.getMethod("main", String[].class).invoke(null, (Object) new String[0]); | |
| } | |
| } | |
| } |