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