1 /* 2 * Copyright (c) 2014, 2018, 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 * @library /test/lib 27 * @modules jdk.compiler 28 * @build AddExportsTest jdk.test.lib.compiler.CompilerUtils 29 * @run testng AddExportsTest 30 * @summary Basic tests for java --add-exports 31 */ 32 33 import java.nio.file.Path; 34 import java.nio.file.Paths; 35 import java.util.stream.Stream; 36 37 import jdk.test.lib.compiler.CompilerUtils; 38 import jdk.test.lib.process.OutputAnalyzer; 39 import static jdk.test.lib.process.ProcessTools.*; 40 41 import org.testng.annotations.BeforeTest; 42 import org.testng.annotations.DataProvider; 43 import org.testng.annotations.Test; 44 import static org.testng.Assert.*; 45 46 47 @Test 48 public class AddExportsTest { 49 50 private static final String TEST_SRC = System.getProperty("test.src"); 51 52 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 53 private static final Path MODS_DIR = Paths.get("mods"); 54 55 // test module m1 that uses Unsafe 56 private static final String TEST1_MODULE = "m1"; 57 private static final String TEST1_MAIN_CLASS = "jdk.test1.Main"; 58 59 60 61 // test module m3 uses m4 internals 62 private static final String TEST3_MODULE = "m3"; 63 private static final String TEST3_MAIN_CLASS = "jdk.test3.Main"; 64 private static final String TEST4_MODULE = "m4"; 65 66 67 @BeforeTest 68 public void compileTestModules() throws Exception { 69 70 // javac -d mods/m1 src/m1/** 71 boolean compiled = CompilerUtils.compile( 72 SRC_DIR.resolve(TEST1_MODULE), 73 MODS_DIR.resolve(TEST1_MODULE), 74 "--add-exports", "java.base/jdk.internal.misc=m1"); 75 assertTrue(compiled, "module " + TEST1_MODULE + " did not compile"); 76 77 78 79 // javac -d mods/m3 src/m3/** 80 compiled = CompilerUtils.compile( 81 SRC_DIR.resolve(TEST3_MODULE), 82 MODS_DIR.resolve(TEST3_MODULE)); 83 assertTrue(compiled, "module " + TEST3_MODULE + " did not compile"); 84 85 // javac -d mods/m4 src/m4/** 86 compiled = CompilerUtils.compile( 87 SRC_DIR.resolve(TEST4_MODULE), 88 MODS_DIR.resolve(TEST4_MODULE)); 89 assertTrue(compiled, "module " + TEST4_MODULE + " did not compile"); 90 } 91 92 /** 93 * Sanity check with -version 94 */ 95 public void testSanity() throws Exception { 96 97 int exitValue 98 = executeTestJava("--add-exports", "java.base/jdk.internal.reflect=ALL-UNNAMED", 99 "-version") 100 .outputTo(System.out) 101 .errorTo(System.out) 102 .getExitValue(); 103 104 assertTrue(exitValue == 0); 105 } 106 107 108 /** 109 * Run class path application that uses jdk.internal.misc.Unsafe 110 */ 111 public void testUnnamedModule() throws Exception { 112 113 // java --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ 114 // -cp mods/$TESTMODULE jdk.test.UsesUnsafe 115 116 String classpath = MODS_DIR.resolve(TEST1_MODULE).toString(); 117 int exitValue 118 = executeTestJava("--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", 119 "-cp", classpath, 120 TEST1_MAIN_CLASS) 121 .outputTo(System.out) 122 .errorTo(System.out) 123 .getExitValue(); 124 125 assertTrue(exitValue == 0); 126 } 127 128 129 /** 130 * Run named module that uses jdk.internal.misc.Unsafe 131 */ 132 public void testNamedModule() throws Exception { 133 134 // java --add-exports java.base/jdk.internal.misc=test \ 135 // --module-path mods -m $TESTMODULE/$MAIN_CLASS 136 137 String mid = TEST1_MODULE + "/" + TEST1_MAIN_CLASS; 138 int exitValue = 139 executeTestJava("--add-exports", "java.base/jdk.internal.misc=" + TEST1_MODULE, 140 "--module-path", MODS_DIR.toString(), 141 "-m", mid) 142 .outputTo(System.out) 143 .errorTo(System.out) 144 .getExitValue(); 145 146 assertTrue(exitValue == 0); 147 } 148 149 150 151 /** 152 * Test --add-exports with module that is added to the set of root modules 153 * with --add-modules. 154 */ 155 public void testWithAddMods() throws Exception { 156 157 // java --add-exports m4/jdk.test4=m3 --module-path mods -m ... 158 String mid = TEST3_MODULE + "/" + TEST3_MAIN_CLASS; 159 int exitValue = executeTestJava( 160 "--add-exports", "m4/jdk.test4=m3", 161 "--module-path", MODS_DIR.toString(), 162 "--add-modules", TEST4_MODULE, 163 "-m", mid) 164 .outputTo(System.out) 165 .errorTo(System.out) 166 .getExitValue(); 167 168 assertTrue(exitValue == 0); 169 } 170 171 172 /** 173 * --add-exports and --add-opens allows duplicates 174 */ 175 public void testWithDuplicateOption() throws Exception { 176 177 int exitValue 178 = executeTestJava("--add-exports", "java.base/jdk.internal.reflect=ALL-UNNAMED", 179 "--add-exports", "java.base/jdk.internal.reflect=ALL-UNNAMED", 180 "--add-opens", "java.base/java.util=ALL-UNNAMED", 181 "--add-opens", "java.base/java.util=ALL-UNNAMED", 182 "-version") 183 .outputTo(System.out) 184 .errorTo(System.out) 185 .getExitValue(); 186 187 assertTrue(exitValue == 0); 188 } 189 190 191 private OutputAnalyzer execJava(String... options) { 192 try { 193 return executeTestJava(options); 194 } catch (Exception e) { 195 throw new Error(e); 196 } 197 } 198 199 /** 200 * Exercise --add-exports and --add-opens with unknown values. 201 * Warning is emitted. 202 */ 203 @Test(dataProvider = "unknownvalues") 204 public void testWithUnknownValue(String value, String ignore) { 205 Stream.of("--add-exports", "--add-opens") 206 .forEach(option -> { 207 // --add-exports $VALUE -version 208 int exitValue = execJava(option, value, "-version") 209 .stderrShouldMatch("WARNING: .*.monkey.*") 210 .outputTo(System.out) 211 .errorTo(System.out) 212 .getExitValue(); 213 214 assertTrue(exitValue == 0); 215 }); 216 } 217 218 219 @DataProvider(name = "unknownvalues") 220 public Object[][] unknownValues() { 221 return new Object[][]{ 222 223 { "java.base/jdk.internal.misc=sun.monkey", null }, // unknown target 224 { "java.monkey/sun.monkey=ALL-UNNAMED", null }, // unknown module 225 { "java.base/sun.monkey=ALL-UNNAMED", null }, // unknown package 226 { "java.monkey/sun.monkey=ALL-UNNAMED", null }, // unknown module/package 227 228 }; 229 } 230 231 232 /** 233 * Exercise --add-exports and --add-opens with bad values 234 */ 235 @Test(dataProvider = "badvalues") 236 public void testWithBadValue(String value, String ignore) { 237 Stream.of("--add-exports", "--add-opens") 238 .forEach(option -> { 239 // --add-exports $VALUE -version 240 int exitValue = execJava(option, value, "-version") 241 .outputTo(System.out) 242 .errorTo(System.out) 243 .getExitValue(); 244 245 assertTrue(exitValue != 0); 246 }); 247 } 248 249 @DataProvider(name = "badvalues") 250 public Object[][] badValues() { 251 return new Object[][]{ 252 253 { "java.base/jdk.internal.misc", null }, // missing target 254 { "java.base=ALL-UNNAMED", null }, // missing package 255 { "java.base/=ALL-UNNAMED", null } // missing package 256 257 }; 258 } 259 }