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