1 /* 2 * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @summary Basic test for Enable-Native-Access attribute in the 27 * manifest of a main application JAR 28 * @library /test/lib 29 * @requires !vm.musl 30 * 31 * @build TestEnableNativeAccessJarManifest 32 * panama_module/* 33 * org.openjdk.foreigntest.unnamed.PanamaMainUnnamedModule 34 * @run testng/othervm TestEnableNativeAccessJarManifest 35 */ 36 37 import java.nio.file.Files; 38 import java.nio.file.Path; 39 import java.nio.file.Paths; 40 import java.util.List; 41 import java.util.ArrayList; 42 import java.util.jar.Attributes; 43 import java.util.jar.Manifest; 44 45 import jdk.test.lib.process.OutputAnalyzer; 46 import jdk.test.lib.process.ProcessTools; 47 import jdk.test.lib.util.JarUtils; 48 49 import org.testng.annotations.Test; 50 import org.testng.annotations.DataProvider; 51 52 public class TestEnableNativeAccessJarManifest extends TestEnableNativeAccessBase { 53 54 private static final String REINVOKER = "TestEnableNativeAccessJarManifest$Reinvoker"; 55 56 static record Attribute(String name, String value) {} 57 58 @Test(dataProvider = "cases") 59 public void testEnableNativeAccessInJarManifest(String action, String cls, Result expectedResult, 60 List<Attribute> attributes, List<String> vmArgs, List<String> programArgs) throws Exception { 61 Manifest man = new Manifest(); 62 Attributes attrs = man.getMainAttributes(); 63 attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); 64 attrs.put(Attributes.Name.MAIN_CLASS, cls); 65 66 for (Attribute attrib : attributes) { 67 attrs.put(new Attributes.Name(attrib.name()), attrib.value()); 68 } 69 70 // create the JAR file with Test1 and Test2 71 Path jarfile = Paths.get(action + ".jar"); 72 Files.deleteIfExists(jarfile); 73 74 Path classes = Paths.get(System.getProperty("test.classes", "")); 75 JarUtils.createJarFile(jarfile, man, classes, Paths.get(cls.replace('.', '/') + ".class")); 76 77 // java -jar test.jar 78 List<String> command = new ArrayList<>(List.of( 79 "-Djava.library.path=" + System.getProperty("java.library.path") 80 )); 81 command.addAll(vmArgs); 82 command.add("-jar"); 83 command.add(jarfile.toString()); 84 command.addAll(programArgs); 85 OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(command.toArray(String[]::new)) 86 .outputTo(System.out) 87 .errorTo(System.out); 88 checkResult(expectedResult, outputAnalyzer); 89 } 90 91 @DataProvider 92 public Object[][] cases() { 93 return new Object[][] { 94 // simple cases where a jar contains a single main class with no dependencies 95 { "panama_no_unnamed_module_native_access", UNNAMED, successWithWarning("ALL-UNNAMED"), 96 List.of(), List.of(), List.of() }, 97 { "panama_unnamed_module_native_access", UNNAMED, successNoWarning(), 98 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), List.of(), List.of() }, 99 { "panama_unnamed_module_native_access_invalid", UNNAMED, failWithError("Only ALL-UNNAMED allowed as value for Enable-Native-Access"), 100 List.of(new Attribute("Enable-Native-Access", "asdf")), List.of(), List.of() }, 101 102 // more complex cases where a jar invokes a module on the module path that does native access 103 { "panama_enable_native_access_false", REINVOKER, successWithWarning("panama_module"), 104 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), 105 List.of("-p", MODULE_PATH, "--add-modules=panama_module"), 106 List.of(PANAMA_MAIN_CLS) }, 107 { "panama_enable_native_access_reflection_false", REINVOKER, successWithWarning("panama_module"), 108 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), 109 List.of("-p", MODULE_PATH, "--add-modules=panama_module"), 110 List.of(PANAMA_REFLECTION_CLS) }, 111 { "panama_enable_native_access_invoke_false", REINVOKER, successWithWarning("panama_module"), 112 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), 113 List.of("-p", MODULE_PATH, "--add-modules=panama_module"), 114 List.of(PANAMA_INVOKE_CLS) }, 115 116 { "panama_enable_native_access_true", REINVOKER, successNoWarning(), 117 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), 118 List.of("-p", MODULE_PATH, "--add-modules=panama_module", "--enable-native-access=panama_module"), 119 List.of(PANAMA_MAIN_CLS) }, 120 { "panama_enable_native_access_reflection_true", REINVOKER, successNoWarning(), 121 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), 122 List.of("-p", MODULE_PATH, "--add-modules=panama_module", "--enable-native-access=panama_module"), 123 List.of(PANAMA_REFLECTION_CLS) }, 124 { "panama_enable_native_access_invoke_true", REINVOKER, successNoWarning(), 125 List.of(new Attribute("Enable-Native-Access", "ALL-UNNAMED")), 126 List.of("-p", MODULE_PATH, "--add-modules=panama_module", "--enable-native-access=panama_module"), 127 List.of(PANAMA_INVOKE_CLS) } 128 }; 129 } 130 131 public class Reinvoker { 132 public static void main(String[] args) throws Throwable { 133 Class<?> realMainClass = Class.forName(args[0]); 134 realMainClass.getMethod("main", String[].class).invoke(null, (Object) new String[0]); 135 } 136 } 137 }