ModuleReaderTest.java revision 16909:085c764a3e5b
1215976Sjmallett/* 2232812Sjmallett * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3215976Sjmallett * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4215976Sjmallett * 5215976Sjmallett * This code is free software; you can redistribute it and/or modify it 6215976Sjmallett * under the terms of the GNU General Public License version 2 only, as 7215976Sjmallett * published by the Free Software Foundation. 8215976Sjmallett * 9215976Sjmallett * This code is distributed in the hope that it will be useful, but WITHOUT 10215976Sjmallett * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11215976Sjmallett * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12215976Sjmallett * version 2 for more details (a copy is included in the LICENSE file that 13215976Sjmallett * accompanied this code). 14215976Sjmallett * 15215976Sjmallett * You should have received a copy of the GNU General Public License version 16215976Sjmallett * 2 along with this work; if not, write to the Free Software Foundation, 17215976Sjmallett * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18232812Sjmallett * 19215976Sjmallett * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20215976Sjmallett * or visit www.oracle.com if you need additional information or have any 21215976Sjmallett * questions. 22215976Sjmallett */ 23215976Sjmallett 24215976Sjmallett/** 25215976Sjmallett * @test 26215976Sjmallett * @library /lib/testlibrary 27215976Sjmallett * @modules java.base/jdk.internal.module 28215976Sjmallett * jdk.compiler 29232812Sjmallett * @build ModuleReaderTest CompilerUtils JarUtils 30215976Sjmallett * @run testng ModuleReaderTest 31215976Sjmallett * @summary Basic tests for java.lang.module.ModuleReader 32215976Sjmallett */ 33215976Sjmallett 34215976Sjmallettimport java.io.File; 35215976Sjmallettimport java.io.IOException; 36215976Sjmallettimport java.io.InputStream; 37215976Sjmallettimport java.lang.module.ModuleFinder; 38215976Sjmallettimport java.lang.module.ModuleReader; 39215976Sjmallettimport java.lang.module.ModuleReference; 40215976Sjmallettimport java.lang.reflect.Module; 41215976Sjmallettimport java.net.URI; 42215976Sjmallettimport java.net.URL; 43215976Sjmallettimport java.net.URLConnection; 44215976Sjmallettimport java.nio.ByteBuffer; 45215976Sjmallettimport java.nio.file.Files; 46232812Sjmallettimport java.nio.file.Path; 47215976Sjmallettimport java.nio.file.Paths; 48215976Sjmallettimport java.util.Arrays; 49215976Sjmallettimport java.util.HashSet; 50215976Sjmallettimport java.util.List; 51215976Sjmallettimport java.util.Optional; 52215976Sjmallettimport java.util.Set; 53215976Sjmallettimport java.util.stream.Collectors; 54215976Sjmallettimport java.util.spi.ToolProvider; 55215976Sjmallett 56232812Sjmallettimport jdk.internal.module.ModulePath; 57232812Sjmallett 58232812Sjmallettimport org.testng.annotations.BeforeTest; 59232812Sjmallettimport org.testng.annotations.Test; 60232812Sjmallettimport static org.testng.Assert.*; 61232812Sjmallett 62232812Sjmallett@Test 63232812Sjmallettpublic class ModuleReaderTest { 64232812Sjmallett 65232812Sjmallett private static final String TEST_SRC = System.getProperty("test.src"); 66232812Sjmallett 67232812Sjmallett private static final Path USER_DIR = Paths.get(System.getProperty("user.dir")); 68232812Sjmallett private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 69232812Sjmallett private static final Path MODS_DIR = Paths.get("mods"); 70232812Sjmallett 71232812Sjmallett // the module name of the base module 72215976Sjmallett private static final String BASE_MODULE = "java.base"; 73232812Sjmallett 74232812Sjmallett // the module name of the test module 75232812Sjmallett private static final String TEST_MODULE = "m"; 76232812Sjmallett 77215976Sjmallett // resources in the base module 78232812Sjmallett private static final String[] BASE_RESOURCES = { 79215976Sjmallett "java/lang/Object.class" 80232812Sjmallett }; 81232812Sjmallett 82232812Sjmallett // (directory) resources that may be in the base module 83232812Sjmallett private static final String[] MAYBE_BASE_RESOURCES = { 84232812Sjmallett "java", 85232812Sjmallett "java/", 86232812Sjmallett "java/lang", 87232812Sjmallett "java/lang/", 88232812Sjmallett }; 89215976Sjmallett 90215976Sjmallett // resource names that should not be found in the base module 91232812Sjmallett private static final String[] NOT_BASE_RESOURCES = { 92232812Sjmallett "NotFound", 93215976Sjmallett "/java", 94232812Sjmallett "//java", 95232812Sjmallett "/java/lang", 96215976Sjmallett "//java/lang", 97215976Sjmallett "java//lang", 98232812Sjmallett "/java/lang/Object.class", 99232812Sjmallett "//java/lang/Object.class", 100232812Sjmallett "java/lang/Object.class/", 101232812Sjmallett "java//lang//Object.class", 102232812Sjmallett "./java/lang/Object.class", 103232812Sjmallett "java/./lang/Object.class", 104215976Sjmallett "java/lang/./Object.class", 105232812Sjmallett "../java/lang/Object.class", 106232812Sjmallett "java/../lang/Object.class", 107215976Sjmallett "java/lang/../Object.class", 108215976Sjmallett }; 109232812Sjmallett 110232812Sjmallett // resources in test module (can't use module-info.class as a test 111232812Sjmallett // resource as it will be modified by the jmod tool) 112232812Sjmallett private static final String[] TEST_RESOURCES = { 113232812Sjmallett "p/Main.class" 114215976Sjmallett }; 115232812Sjmallett 116215976Sjmallett // (directory) resources that may be in the test module 117215976Sjmallett private static final String[] MAYBE_TEST_RESOURCES = { 118215976Sjmallett "p", 119215976Sjmallett "p/" 120215976Sjmallett }; 121 122 // resource names that should not be found in the test module 123 private static final String[] NOT_TEST_RESOURCES = { 124 "NotFound", 125 "/p", 126 "//p", 127 "/p/Main.class", 128 "//p/Main.class", 129 "p/Main.class/", 130 "p//Main.class", 131 "./p/Main.class", 132 "p/./Main.class", 133 "../p/Main.class", 134 "p/../p/Main.class" 135 }; 136 137 138 @BeforeTest 139 public void compileTestModule() throws Exception { 140 141 // javac -d mods/$TESTMODULE src/$TESTMODULE/** 142 boolean compiled 143 = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE), 144 MODS_DIR.resolve(TEST_MODULE)); 145 assertTrue(compiled, "test module did not compile"); 146 } 147 148 149 /** 150 * Test ModuleReader to module in runtime image 151 */ 152 public void testImage() throws IOException { 153 154 ModuleFinder finder = ModuleFinder.ofSystem(); 155 ModuleReference mref = finder.find(BASE_MODULE).get(); 156 ModuleReader reader = mref.open(); 157 158 try (reader) { 159 160 for (String name : BASE_RESOURCES) { 161 byte[] expectedBytes; 162 Module baseModule = Object.class.getModule(); 163 try (InputStream in = baseModule.getResourceAsStream(name)) { 164 expectedBytes = in.readAllBytes(); 165 } 166 167 testFind(reader, name, expectedBytes); 168 testOpen(reader, name, expectedBytes); 169 testRead(reader, name, expectedBytes); 170 testList(reader, name); 171 } 172 173 // test resources that may be in the base module 174 for (String name : MAYBE_BASE_RESOURCES) { 175 Optional<URI> ouri = reader.find(name); 176 ouri.ifPresent(uri -> { 177 if (name.endsWith("/")) 178 assertTrue(uri.toString().endsWith("/")); 179 }); 180 } 181 182 // test "not found" in java.base module 183 for (String name : NOT_BASE_RESOURCES) { 184 assertFalse(reader.find(name).isPresent()); 185 assertFalse(reader.open(name).isPresent()); 186 assertFalse(reader.read(name).isPresent()); 187 } 188 189 // test nulls 190 try { 191 reader.find(null); 192 assertTrue(false); 193 } catch (NullPointerException expected) { } 194 195 try { 196 reader.open(null); 197 assertTrue(false); 198 } catch (NullPointerException expected) { } 199 200 try { 201 reader.read(null); 202 assertTrue(false); 203 } catch (NullPointerException expected) { } 204 205 try { 206 reader.release(null); 207 assertTrue(false); 208 } catch (NullPointerException expected) { } 209 210 } 211 212 // test closed ModuleReader 213 try { 214 reader.open(BASE_RESOURCES[0]); 215 assertTrue(false); 216 } catch (IOException expected) { } 217 218 219 try { 220 reader.read(BASE_RESOURCES[0]); 221 assertTrue(false); 222 } catch (IOException expected) { } 223 } 224 225 226 /** 227 * Test ModuleReader to exploded module 228 */ 229 public void testExplodedModule() throws IOException { 230 test(MODS_DIR); 231 } 232 233 234 /** 235 * Test ModuleReader to modular JAR 236 */ 237 public void testModularJar() throws IOException { 238 Path dir = Files.createTempDirectory(USER_DIR, "mlib"); 239 240 // jar cf mlib/${TESTMODULE}.jar -C mods . 241 JarUtils.createJarFile(dir.resolve("m.jar"), 242 MODS_DIR.resolve(TEST_MODULE)); 243 244 test(dir); 245 } 246 247 248 /** 249 * Test ModuleReader to JMOD 250 */ 251 public void testJMod() throws IOException { 252 Path dir = Files.createTempDirectory(USER_DIR, "mlib"); 253 254 // jmod create --class-path mods/${TESTMODULE} mlib/${TESTMODULE}.jmod 255 String cp = MODS_DIR.resolve(TEST_MODULE).toString(); 256 String jmod = dir.resolve("m.jmod").toString(); 257 String[] args = { "create", "--class-path", cp, jmod }; 258 ToolProvider jmodTool = ToolProvider.findFirst("jmod") 259 .orElseThrow(() -> 260 new RuntimeException("jmod tool not found") 261 ); 262 assertEquals(jmodTool.run(System.out, System.out, args), 0); 263 264 test(dir); 265 } 266 267 268 /** 269 * The test module is found on the given module path. Open a ModuleReader 270 * to the test module and test the reader. 271 */ 272 void test(Path mp) throws IOException { 273 274 ModuleFinder finder = ModulePath.of(Runtime.version(), true, mp); 275 ModuleReference mref = finder.find(TEST_MODULE).get(); 276 ModuleReader reader = mref.open(); 277 278 try (reader) { 279 280 // test resources in test module 281 for (String name : TEST_RESOURCES) { 282 byte[] expectedBytes 283 = Files.readAllBytes(MODS_DIR 284 .resolve(TEST_MODULE) 285 .resolve(name.replace('/', File.separatorChar))); 286 287 testFind(reader, name, expectedBytes); 288 testOpen(reader, name, expectedBytes); 289 testRead(reader, name, expectedBytes); 290 testList(reader, name); 291 } 292 293 // test resources that may be in the test module 294 for (String name : MAYBE_TEST_RESOURCES) { 295 System.out.println(name); 296 Optional<URI> ouri = reader.find(name); 297 ouri.ifPresent(uri -> { 298 if (name.endsWith("/")) 299 assertTrue(uri.toString().endsWith("/")); 300 }); 301 } 302 303 // test "not found" in test module 304 for (String name : NOT_TEST_RESOURCES) { 305 assertFalse(reader.find(name).isPresent()); 306 assertFalse(reader.open(name).isPresent()); 307 assertFalse(reader.read(name).isPresent()); 308 } 309 310 // test nulls 311 try { 312 reader.find(null); 313 assertTrue(false); 314 } catch (NullPointerException expected) { } 315 316 try { 317 reader.open(null); 318 assertTrue(false); 319 } catch (NullPointerException expected) { } 320 321 try { 322 reader.read(null); 323 assertTrue(false); 324 } catch (NullPointerException expected) { } 325 326 try { 327 reader.release(null); 328 throw new RuntimeException(); 329 } catch (NullPointerException expected) { } 330 331 } 332 333 // test closed ModuleReader 334 try { 335 reader.open(TEST_RESOURCES[0]); 336 assertTrue(false); 337 } catch (IOException expected) { } 338 339 340 try { 341 reader.read(TEST_RESOURCES[0]); 342 assertTrue(false); 343 } catch (IOException expected) { } 344 345 try { 346 reader.list(); 347 assertTrue(false); 348 } catch (IOException expected) { } 349 } 350 351 /** 352 * Test ModuleReader#find 353 */ 354 void testFind(ModuleReader reader, String name, byte[] expectedBytes) 355 throws IOException 356 { 357 Optional<URI> ouri = reader.find(name); 358 assertTrue(ouri.isPresent()); 359 360 URL url = ouri.get().toURL(); 361 if (!url.getProtocol().equalsIgnoreCase("jmod")) { 362 URLConnection uc = url.openConnection(); 363 uc.setUseCaches(false); 364 try (InputStream in = uc.getInputStream()) { 365 byte[] bytes = in.readAllBytes(); 366 assertTrue(Arrays.equals(bytes, expectedBytes)); 367 } 368 } 369 } 370 371 /** 372 * Test ModuleReader#open 373 */ 374 void testOpen(ModuleReader reader, String name, byte[] expectedBytes) 375 throws IOException 376 { 377 Optional<InputStream> oin = reader.open(name); 378 assertTrue(oin.isPresent()); 379 380 InputStream in = oin.get(); 381 try (in) { 382 byte[] bytes = in.readAllBytes(); 383 assertTrue(Arrays.equals(bytes, expectedBytes)); 384 } 385 } 386 387 /** 388 * Test ModuleReader#read 389 */ 390 void testRead(ModuleReader reader, String name, byte[] expectedBytes) 391 throws IOException 392 { 393 Optional<ByteBuffer> obb = reader.read(name); 394 assertTrue(obb.isPresent()); 395 396 ByteBuffer bb = obb.get(); 397 try { 398 int rem = bb.remaining(); 399 assertTrue(rem == expectedBytes.length); 400 byte[] bytes = new byte[rem]; 401 bb.get(bytes); 402 assertTrue(Arrays.equals(bytes, expectedBytes)); 403 } finally { 404 reader.release(bb); 405 } 406 } 407 408 /** 409 * Test ModuleReader#list 410 */ 411 void testList(ModuleReader reader, String name) throws IOException { 412 List<String> list = reader.list().collect(Collectors.toList()); 413 Set<String> names = new HashSet<>(list); 414 assertTrue(names.size() == list.size()); // no duplicates 415 416 assertTrue(names.contains("module-info.class")); 417 assertTrue(names.contains(name)); 418 419 // all resources should be locatable via find 420 for (String e : names) { 421 assertTrue(reader.find(e).isPresent()); 422 } 423 } 424 425} 426