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 * @summary Basic test of jrt file system provider 27 * @run testng Basic 28 */ 29 30import java.io.InputStream; 31import java.io.IOException; 32import java.io.DataInputStream; 33import java.nio.file.DirectoryStream; 34import java.nio.file.InvalidPathException; 35import java.nio.file.Files; 36import java.nio.file.FileSystem; 37import java.nio.file.FileSystems; 38import java.nio.file.Path; 39import java.nio.file.PathMatcher; 40import java.nio.file.Paths; 41import java.net.URI; 42import java.util.Collections; 43import java.util.HashMap; 44import java.util.Iterator; 45import java.util.Map; 46import java.util.NoSuchElementException; 47import java.util.stream.Stream; 48 49import org.testng.annotations.AfterClass; 50import org.testng.annotations.BeforeClass; 51import org.testng.annotations.DataProvider; 52import org.testng.annotations.Test; 53 54import static org.testng.Assert.assertEquals; 55import static org.testng.Assert.assertNotEquals; 56import static org.testng.Assert.assertNotNull; 57import static org.testng.Assert.assertTrue; 58import static org.testng.Assert.assertFalse; 59 60/** 61 * Basic tests for jrt:/ file system provider. 62 */ 63 64public class Basic { 65 66 private FileSystem theFileSystem; 67 private FileSystem fs; 68 private boolean isExplodedBuild = false; 69 70 @BeforeClass 71 public void setup() { 72 theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/")); 73 Path modulesPath = Paths.get(System.getProperty("java.home"), 74 "lib", "modules"); 75 isExplodedBuild = Files.notExists(modulesPath); 76 if (isExplodedBuild) { 77 System.out.printf("%s doesn't exist.", modulesPath.toString()); 78 System.out.println(); 79 System.out.println("It is most probably an exploded build." 80 + " Skip non-default FileSystem testing."); 81 return; 82 } 83 84 Map<String, String> env = new HashMap<>(); 85 // set java.home property to be underlying java.home 86 // so that jrt-fs.jar loading is exercised. 87 env.put("java.home", System.getProperty("java.home")); 88 try { 89 fs = FileSystems.newFileSystem(URI.create("jrt:/"), env); 90 } catch (IOException ioExp) { 91 throw new RuntimeException(ioExp); 92 } 93 } 94 95 @AfterClass 96 public void tearDown() { 97 try { 98 fs.close(); 99 } catch (Exception ignored) {} 100 } 101 102 private FileSystem selectFileSystem(boolean theDefault) { 103 return theDefault? theFileSystem : fs; 104 } 105 106 // Checks that the given FileSystem is a jrt file system. 107 private void checkFileSystem(FileSystem fs) { 108 assertTrue(fs.provider().getScheme().equalsIgnoreCase("jrt")); 109 assertTrue(fs.isOpen()); 110 assertTrue(fs.isReadOnly()); 111 assertEquals(fs.getSeparator(), "/"); 112 113 // one root 114 Iterator<Path> roots = fs.getRootDirectories().iterator(); 115 assertTrue(roots.next().toString().equals("/")); 116 assertFalse(roots.hasNext()); 117 } 118 119 @Test 120 public void testGetFileSystem() { 121 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 122 checkFileSystem(fs); 123 124 // getFileSystem should return the same object each time 125 assertTrue(fs == FileSystems.getFileSystem(URI.create("jrt:/"))); 126 } 127 128 @Test(expectedExceptions = UnsupportedOperationException.class) 129 public void testCloseFileSystem() throws Exception { 130 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 131 fs.close(); // should throw UOE 132 } 133 134 @Test 135 public void testNewFileSystem() throws Exception { 136 FileSystem theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/")); 137 Map<String, ?> env = Collections.emptyMap(); 138 try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), env)) { 139 checkFileSystem(fs); 140 assertTrue(fs != theFileSystem); 141 } 142 } 143 144 @Test 145 public void testNewFileSystemWithJavaHome() throws Exception { 146 if (isExplodedBuild) { 147 System.out.println("Skip testNewFileSystemWithJavaHome" 148 + " since this is an exploded build"); 149 return; 150 } 151 152 Map<String, String> env = new HashMap<>(); 153 // set java.home property to be underlying java.home 154 // so that jrt-fs.jar loading is exercised. 155 env.put("java.home", System.getProperty("java.home")); 156 try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), env)) { 157 checkFileSystem(fs); 158 // jrt-fs.jar classes are loaded by another (non-boot) loader in this case 159 assertNotNull(fs.provider().getClass().getClassLoader()); 160 } 161 } 162 163 @DataProvider(name = "knownClassFiles") 164 private Object[][] knownClassFiles() { 165 return new Object[][] { 166 { "/modules/java.base/java/lang/Object.class", true }, 167 { "modules/java.base/java/lang/Object.class", true }, 168 { "/modules/java.base/java/lang/Object.class", false }, 169 { "modules/java.base/java/lang/Object.class", false }, 170 }; 171 } 172 173 @Test(dataProvider = "knownClassFiles") 174 public void testKnownClassFiles(String path, boolean theDefault) throws Exception { 175 if (isExplodedBuild && !theDefault) { 176 System.out.println("Skip testKnownClassFiles with non-default FileSystem"); 177 return; 178 } 179 180 FileSystem fs = selectFileSystem(theDefault); 181 Path classFile = fs.getPath(path); 182 183 assertTrue(Files.isRegularFile(classFile)); 184 assertTrue(Files.size(classFile) > 0L); 185 186 // check magic number 187 try (InputStream in = Files.newInputStream(classFile)) { 188 int magic = new DataInputStream(in).readInt(); 189 assertEquals(magic, 0xCAFEBABE); 190 } 191 } 192 193 @DataProvider(name = "knownDirectories") 194 private Object[][] knownDirectories() { 195 return new Object[][] { 196 { "/", true }, 197 { "." , true }, 198 { "./", true }, 199 { "/.", true }, 200 { "/./", true }, 201 { "/modules/java.base/..", true }, 202 { "/modules/java.base/../", true }, 203 { "/modules/java.base/../.", true }, 204 { "/modules/java.base", true }, 205 { "/modules/java.base/java/lang", true }, 206 { "modules/java.base/java/lang", true }, 207 { "/modules/java.base/java/lang/", true }, 208 { "modules/java.base/java/lang/", true }, 209 { "/", false }, 210 { "." , false }, 211 { "./", false }, 212 { "/.", false }, 213 { "/./", false }, 214 { "/modules/java.base/..", false }, 215 { "/modules/java.base/../", false }, 216 { "/modules/java.base/../.", false }, 217 { "/modules/java.base", false }, 218 { "/modules/java.base/java/lang", false }, 219 { "modules/java.base/java/lang", false }, 220 { "/modules/java.base/java/lang/", false }, 221 { "modules/java.base/java/lang/", false }, 222 }; 223 } 224 225 @Test(dataProvider = "knownDirectories") 226 public void testKnownDirectories(String path, boolean theDefault) throws Exception { 227 if (isExplodedBuild && !theDefault) { 228 System.out.println("Skip testKnownDirectories with non-default FileSystem"); 229 return; 230 } 231 232 FileSystem fs = selectFileSystem(theDefault); 233 Path dir = fs.getPath(path); 234 235 assertTrue(Files.isDirectory(dir)); 236 237 // directory should not be empty 238 try (Stream<Path> stream = Files.list(dir)) { 239 assertTrue(stream.count() > 0L); 240 } 241 try (Stream<Path> stream = Files.walk(dir)) { 242 assertTrue(stream.count() > 0L); 243 } 244 } 245 246 @DataProvider(name = "topLevelPkgDirs") 247 private Object[][] topLevelPkgDirs() { 248 return new Object[][] { 249 { "/java/lang" }, 250 { "java/lang" }, 251 { "/java/util" }, 252 { "java/util" }, 253 }; 254 } 255 256 @Test(dataProvider = "topLevelPkgDirs") 257 public void testNotExists(String path) throws Exception { 258 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 259 Path dir = fs.getPath(path); 260 261 // package directories should not be there at top level 262 assertTrue(Files.notExists(dir)); 263 } 264 265 /** 266 * Test the URI of every file in the jrt file system 267 */ 268 @Test 269 public void testToAndFromUri() throws Exception { 270 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 271 Path top = fs.getPath("/"); 272 try (Stream<Path> stream = Files.walk(top)) { 273 stream.forEach(path -> { 274 URI u = path.toUri(); 275 assertTrue(u.getScheme().equalsIgnoreCase("jrt")); 276 assertFalse(u.isOpaque()); 277 assertTrue(u.getAuthority() == null); 278 assertEquals(u.getPath(), path.toAbsolutePath().toString()); 279 Path p = Paths.get(u); 280 assertEquals(p, path); 281 }); 282 } 283 } 284 285 @Test 286 public void testDirectoryNames() throws Exception { 287 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 288 Path top = fs.getPath("/"); 289 // check that directory names do not have trailing '/' char 290 try (Stream<Path> stream = Files.walk(top)) { 291 stream.skip(1).filter(Files::isDirectory).forEach(path -> { 292 assertFalse(path.toString().endsWith("/")); 293 }); 294 } 295 } 296 297 @DataProvider(name = "pathPrefixs") 298 private Object[][] pathPrefixes() { 299 return new Object[][] { 300 { "/" }, 301 { "modules/java.base/java/lang" }, 302 { "./modules/java.base/java/lang" }, 303 { "/modules/java.base/java/lang" }, 304 { "/./modules/java.base/java/lang" }, 305 { "modules/java.base/java/lang/" }, 306 { "./modules/java.base/java/lang/" }, 307 { "/./modules/java.base/java/lang/" }, 308 }; 309 } 310 311 // @Test(dataProvider = "pathPrefixes") 312 public void testParentInDirList(String dir) throws Exception { 313 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 314 Path base = fs.getPath(dir); 315 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base)) { 316 for (Path entry: stream) { 317 assertTrue( entry.getParent().equals(base), 318 base.toString() + "-> " + entry.toString() ); 319 } 320 } 321 } 322 323 @DataProvider(name = "dirStreamStringFilterData") 324 private Object[][] dirStreamStringFilterData() { 325 return new Object[][] { 326 { "/modules/java.base/java/lang", "/reflect" }, 327 { "/modules/java.base/java/lang", "/Object.class" }, 328 { "/modules/java.base/java/util", "/stream" }, 329 { "/modules/java.base/java/util", "/List.class" }, 330 }; 331 } 332 333 @Test(dataProvider = "dirStreamStringFilterData") 334 public void testDirectoryStreamStringFilter(String dir, String filter) throws Exception { 335 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 336 Path base = fs.getPath(dir); 337 try (DirectoryStream<Path> stream = 338 Files.newDirectoryStream(base, p->!p.toString().endsWith(filter))) { 339 for (Path entry: stream) { 340 assertFalse(entry.toString().contains(filter), 341 "filtered path seen: " + filter); 342 } 343 } 344 345 // make sure without filter, we do see that matching entry! 346 boolean seen = false; 347 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base)) { 348 for (Path entry: stream) { 349 if (entry.toString().endsWith(filter)) { 350 seen = true; 351 break; 352 } 353 } 354 } 355 356 assertTrue(seen, "even without filter " + filter + " is missing"); 357 } 358 359 @DataProvider(name = "dirStreamFilterData") 360 private Object[][] dirStreamFilterData() { 361 return new Object[][] { 362 { 363 "/", 364 (DirectoryStream.Filter<Path>)(Files::isDirectory), 365 "isDirectory" 366 }, 367 { 368 "/modules/java.base/java/lang", 369 (DirectoryStream.Filter<Path>)(Files::isRegularFile), 370 "isFile" 371 } 372 }; 373 } 374 375 @Test(dataProvider = "dirStreamFilterData") 376 private void testDirectoryStreamFilter(String dir, DirectoryStream.Filter filter, 377 String name) throws Exception { 378 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 379 Path base = fs.getPath(dir); 380 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base, filter)) { 381 for (Path entry: stream) { 382 assertTrue(filter.accept(entry), "filtered path seen: " + name); 383 } 384 } 385 386 // make sure without filter, we do see that matching entry! 387 boolean seen = false; 388 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base)) { 389 for (Path entry: stream) { 390 if (filter.accept(entry)) { 391 seen = true; 392 break; 393 } 394 } 395 } 396 397 assertTrue(seen, "even without filter " + name + " is missing"); 398 } 399 400 @Test 401 private void testDirectoryStreamIterator() throws Exception { 402 // run the tests with null filter (no filter) 403 dirStreamIteratorTest(null); 404 // run the same tests with trivial "accept all" filter 405 dirStreamIteratorTest(p->true); 406 // two other non-trivial ones 407 dirStreamIteratorTest(Files::isDirectory); 408 dirStreamIteratorTest(Files::isRegularFile); 409 } 410 411 private void dirStreamIteratorTest(DirectoryStream.Filter<Path> filter) 412 throws Exception { 413 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 414 // This test assumes at least there are two elements in "java/lang" 415 // package with any filter passed. don't change to different path here! 416 Path dir = fs.getPath("/modules/java.base/java/lang"); 417 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 418 Iterator<Path> itr = stream.iterator(); 419 itr.hasNext(); 420 Path path1 = itr.next(); 421 // missing second hasNext call 422 Path path2 = itr.next(); 423 assertNotEquals(path1, path2); 424 } 425 426 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 427 Iterator<Path> itr = stream.iterator(); 428 // no hasNext calls at all 429 Path path1 = itr.next(); 430 Path path2 = itr.next(); 431 assertNotEquals(path1, path2); 432 } 433 434 int numEntries = 0; 435 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 436 Iterator<Path> itr = stream.iterator(); 437 while (itr.hasNext()) { 438 numEntries++; 439 itr.next(); 440 } 441 442 // reached EOF, next call should result in exception 443 try { 444 itr.next(); 445 throw new AssertionError("should have thrown exception"); 446 } catch (NoSuchElementException nsee) { 447 System.out.println("got NoSuchElementException as expected"); 448 } 449 } 450 451 // redundant hasNext calls 452 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 453 Iterator<Path> itr = stream.iterator(); 454 // any number of hasNext should definitely stay at first element 455 for (int i = 0; i < 2*numEntries; i++) { 456 itr.hasNext(); 457 } 458 459 for (int j = 0; j < numEntries; j++) { 460 itr.next(); 461 } 462 // exactly count number of entries! 463 assertFalse(itr.hasNext()); 464 } 465 } 466 467 @DataProvider(name = "hiddenPaths") 468 private Object[][] hiddenPaths() { 469 return new Object[][] { 470 { "/META-INF" }, 471 { "/META-INF/services" }, 472 { "/META-INF/services/java.nio.file.spi.FileSystemProvider" }, 473 { "/modules/java.base/packages.offsets" }, 474 { "/modules/java.instrument/packages.offsets" }, 475 { "/modules/jdk.zipfs/packages.offsets" }, 476 { "/modules/java.base/_the.java.base.vardeps" }, 477 { "/modules/java.base/_the.java.base_batch" }, 478 { "/java/lang" }, 479 { "/java/util" }, 480 }; 481 } 482 483 @Test(dataProvider = "hiddenPaths") 484 public void testHiddenPathsNotExposed(String path) throws Exception { 485 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 486 assertTrue(Files.notExists(fs.getPath(path)), path + " should not exist"); 487 } 488 489 @DataProvider(name = "pathGlobPatterns") 490 private Object[][] pathGlobPatterns() { 491 return new Object[][] { 492 { "/modules/*", "/modules/java.base", true }, 493 { "/modules/*", "/modules/java.base/java", false }, 494 { "/modules/j*", "/modules/java.base", true }, 495 { "/modules/J*", "/modules/java.base", false }, 496 { "**.class", "/modules/java.base/java/lang/Object.class", true }, 497 { "**.java", "/modules/java.base/java/lang/Object.class", false }, 498 { "**java/*", "/modules/java.base/java/lang", true }, 499 { "**java/lang/ref*", "/modules/java.base/java/lang/reflect", true }, 500 { "**java/lang/ref*", "/modules/java.base/java/lang/ref", true }, 501 { "**java/lang/ref?", "/modules/java.base/java/lang/ref", false }, 502 { "**java/lang/{ref,refl*}", "/modules/java.base/java/lang/ref", true }, 503 { "**java/lang/{ref,refl*}", "/modules/java.base/java/lang/reflect", true }, 504 { "**java/[a-u]?*/*.class", "/modules/java.base/java/util/Map.class", true }, 505 { "**java/util/[a-z]*.class", "/modules/java.base/java/util/TreeMap.class", false }, 506 }; 507 } 508 509 @Test(dataProvider = "pathGlobPatterns") 510 public void testGlobPathMatcher(String pattern, String path, 511 boolean expectMatch) throws Exception { 512 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 513 PathMatcher pm = fs.getPathMatcher("glob:" + pattern); 514 Path p = fs.getPath(path); 515 assertTrue(Files.exists(p), path); 516 assertTrue(!(pm.matches(p) ^ expectMatch), 517 p + (expectMatch? " should match " : " should not match ") + 518 pattern); 519 } 520 521 @DataProvider(name = "pathRegexPatterns") 522 private Object[][] pathRegexPatterns() { 523 return new Object[][] { 524 { "/modules/.*", "/modules/java.base", true }, 525 { "/modules/[^/]*", "/modules/java.base/java", false }, 526 { "/modules/j.*", "/modules/java.base", true }, 527 { "/modules/J.*", "/modules/java.base", false }, 528 { ".*\\.class", "/modules/java.base/java/lang/Object.class", true }, 529 { ".*\\.java", "/modules/java.base/java/lang/Object.class", false }, 530 { ".*java/.*", "/modules/java.base/java/lang", true }, 531 { ".*java/lang/ref.*", "/modules/java.base/java/lang/reflect", true }, 532 { ".*java/lang/ref.*", "/modules/java.base/java/lang/ref", true }, 533 { ".*/java/lang/ref.+", "/modules/java.base/java/lang/ref", false }, 534 { ".*/java/lang/(ref|refl.*)", "/modules/java.base/java/lang/ref", true }, 535 { ".*/java/lang/(ref|refl.*)", "/modules/java.base/java/lang/reflect", true }, 536 { ".*/java/[a-u]?.*/.*\\.class", "/modules/java.base/java/util/Map.class", true }, 537 { ".*/java/util/[a-z]*\\.class", "/modules/java.base/java/util/TreeMap.class", false }, 538 }; 539 } 540 541 @Test(dataProvider = "pathRegexPatterns") 542 public void testRegexPathMatcher(String pattern, String path, 543 boolean expectMatch) throws Exception { 544 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 545 PathMatcher pm = fs.getPathMatcher("regex:" + pattern); 546 Path p = fs.getPath(path); 547 assertTrue(Files.exists(p), path); 548 assertTrue(!(pm.matches(p) ^ expectMatch), 549 p + (expectMatch? " should match " : " should not match ") + 550 pattern); 551 } 552 553 @Test 554 public void testPackagesAndModules() throws Exception { 555 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 556 assertTrue(Files.isDirectory(fs.getPath("/packages"))); 557 assertTrue(Files.isDirectory(fs.getPath("/modules"))); 558 } 559 560 @DataProvider(name = "packagesSubDirs") 561 private Object[][] packagesSubDirs() { 562 return new Object[][] { 563 { "java.lang" }, 564 { "java.util" }, 565 { "java.nio" }, 566 { "jdk.nashorn.api.scripting" } 567 }; 568 } 569 570 @Test(dataProvider = "packagesSubDirs") 571 public void testPackagesSubDirs(String pkg) throws Exception { 572 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 573 assertTrue(Files.isDirectory(fs.getPath("/packages/" + pkg)), 574 pkg + " missing"); 575 } 576 577 @DataProvider(name = "packagesLinks") 578 private Object[][] packagesLinks() { 579 return new Object[][] { 580 { "/packages/java.lang/java.base" }, 581 { "/packages/java.lang/java.instrument" }, 582 { "/packages/java/java.base" }, 583 { "/packages/java/java.instrument" }, 584 { "/packages/java/java.rmi" }, 585 { "/packages/java/java.sql" }, 586 { "/packages/javax/java.base" }, 587 { "/packages/javax/java.sql" }, 588 { "/packages/javax/java.xml" }, 589 { "/packages/javax/java.management" }, 590 { "/packages/java.util/java.base" }, 591 { "/packages/jdk.nashorn.api.scripting/jdk.scripting.nashorn" }, 592 }; 593 } 594 595 @Test(dataProvider = "packagesLinks") 596 public void testPackagesLinks(String link) throws Exception { 597 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 598 Path path = fs.getPath(link); 599 assertTrue(Files.exists(path), link + " missing"); 600 assertTrue(Files.isSymbolicLink(path), path + " is not a link"); 601 path = Files.readSymbolicLink(path); 602 assertEquals(path.toString(), "/modules" + link.substring(link.lastIndexOf("/"))); 603 } 604 605 @DataProvider(name = "modulesSubDirs") 606 private Object[][] modulesSubDirs() { 607 return new Object[][] { 608 { "java.base" }, 609 { "java.sql" }, 610 { "jdk.scripting.nashorn" }, 611 }; 612 } 613 614 @Test(dataProvider = "modulesSubDirs") 615 public void testModulesSubDirs(String module) throws Exception { 616 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 617 Path path = fs.getPath("/modules/" + module); 618 assertTrue(Files.isDirectory(path), module + " missing"); 619 assertTrue(!Files.isSymbolicLink(path), path + " is a link"); 620 } 621 622 @DataProvider(name="linkChases") 623 private Object[][] linkChases() { 624 return new Object[][] { 625 { "/modules/java.base/java/lang" }, 626 { "/modules/java.base/java/util/Vector.class" }, 627 { "/modules/jdk.scripting.nashorn/jdk/nashorn" }, 628 { "/packages/java.lang/java.base/java/lang" }, 629 { "/packages/java.util/java.base/java/util/Vector.class" }, 630 }; 631 } 632 633 @Test(dataProvider = "linkChases") 634 public void testLinkChases(String link) throws Exception { 635 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 636 Path path = fs.getPath(link); 637 assertTrue(Files.exists(path), link); 638 } 639 640 @Test 641 public void testSymlinkDirList() throws Exception { 642 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 643 Path path = fs.getPath("/packages/java.lang/java.base"); 644 assertTrue(Files.isSymbolicLink(path)); 645 assertTrue(Files.isDirectory(path)); 646 647 boolean javaSeen = false, javaxSeen = false; 648 try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) { 649 for (Path p : stream) { 650 String str = p.toString(); 651 if (str.endsWith("/java")) { 652 javaSeen = true; 653 } else if (str.endsWith("javax")) { 654 javaxSeen = true; 655 } 656 } 657 } 658 assertTrue(javaSeen); 659 assertTrue(javaxSeen); 660 } 661 662 @Test 663 public void invalidPathTest() { 664 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 665 InvalidPathException ipe = null; 666 try { 667 boolean res = Files.exists(fs.getPath("/packages/\ud834\udd7b")); 668 assertFalse(res); 669 return; 670 } catch (InvalidPathException e) { 671 ipe = e; 672 } 673 assertTrue(ipe != null); 674 } 675 676 @DataProvider(name="packagesLinkedDirs") 677 private Object[][] packagesLinkedDirs() { 678 return new Object[][] { 679 { "/packages/java.lang/java.base/java/lang/ref" }, 680 { "/./packages/java.lang/java.base/java/lang/ref" }, 681 { "packages/java.lang/java.base/java/lang/ref" }, 682 { "/packages/../packages/java.lang/java.base/java/lang/ref" }, 683 { "/packages/java.lang/java.base/java/util/zip" }, 684 { "/./packages/java.lang/java.base/java/util/zip" }, 685 { "packages/java.lang/java.base/java/util/zip" }, 686 { "/packages/../packages/java.lang/java.base/java/util/zip" }, 687 { "/packages/com.oracle/java.xml.ws/com" }, 688 { "/./packages/com.oracle/java.xml.ws/com" }, 689 { "packages/com.oracle/java.xml.ws/com" }, 690 { "/packages/../packages/com.oracle/java.xml.ws/com" } 691 }; 692 } 693 694 // @bug 8141521: jrt file system's DirectoryStream reports child paths 695 // with wrong paths for directories under /packages 696 @Test(dataProvider = "packagesLinkedDirs") 697 public void dirStreamPackagesDirTest(String dirName) throws IOException { 698 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 699 Path path = fs.getPath(dirName); 700 701 int childCount = 0, dirPrefixOkayCount = 0; 702 try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(path)) { 703 for (Path child : dirStream) { 704 childCount++; 705 if (child.toString().startsWith(dirName)) { 706 dirPrefixOkayCount++; 707 } 708 } 709 } 710 711 assertTrue(childCount != 0); 712 assertEquals(dirPrefixOkayCount, childCount); 713 } 714 715 @Test 716 public void objectClassSizeTest() throws Exception { 717 String path = "/modules/java.base/java/lang/Object.class"; 718 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 719 Path classFile = fs.getPath(path); 720 721 assertTrue(Files.size(classFile) > 0L); 722 } 723} 724 725