1 /* 2 * Copyright (c) 2015, 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 * @modules java.base/jdk.internal.module 27 * @build ModuleFinderTest 28 * @run testng ModuleFinderTest 29 * @summary Basic tests for java.lang.module.ModuleFinder 30 */ 31 32 import java.io.File; 33 import java.io.OutputStream; 34 import java.lang.module.FindException; 35 import java.lang.module.InvalidModuleDescriptorException; 36 import java.lang.module.ModuleDescriptor; 37 import java.lang.module.ModuleFinder; 38 import java.lang.module.ModuleReference; 39 import java.nio.file.Files; 40 import java.nio.file.Path; 41 import java.nio.file.Paths; 42 import java.util.Optional; 43 import java.util.Set; 44 import java.util.jar.JarEntry; 45 import java.util.jar.JarOutputStream; 46 import java.util.stream.Collectors; 47 48 import jdk.internal.module.ModuleInfoWriter; 49 50 import org.testng.annotations.Test; 51 import static org.testng.Assert.*; 52 53 @Test 54 public class ModuleFinderTest { 55 56 private static final Path USER_DIR 57 = Paths.get(System.getProperty("user.dir")); 58 59 60 /** 61 * Test ModuleFinder.ofSystem 62 */ 63 public void testOfSystem() { 64 ModuleFinder finder = ModuleFinder.ofSystem(); 65 66 assertTrue(finder.find("java.se").isPresent()); 67 assertTrue(finder.find("java.base").isPresent()); 68 assertFalse(finder.find("java.rhubarb").isPresent()); 69 70 Set<String> names = finder.findAll().stream() 71 .map(ModuleReference::descriptor) 72 .map(ModuleDescriptor::name) 73 .collect(Collectors.toSet()); 74 assertTrue(names.contains("java.se")); 75 assertTrue(names.contains("java.base")); 76 assertFalse(names.contains("java.rhubarb")); 77 } 78 79 80 /** 81 * Test ModuleFinder.of with no entries 82 */ 83 public void testOfNoEntries() { 84 ModuleFinder finder = ModuleFinder.of(); 85 assertTrue(finder.findAll().isEmpty()); 86 assertFalse(finder.find("java.rhubarb").isPresent()); 87 } 88 89 90 /** 91 * Test ModuleFinder.of with one directory of modules 92 */ 93 public void testOfOneDirectory() throws Exception { 94 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 95 createExplodedModule(dir.resolve("m1"), "m1"); 96 createModularJar(dir.resolve("m2.jar"), "m2"); 97 98 ModuleFinder finder = ModuleFinder.of(dir); 99 assertTrue(finder.findAll().size() == 2); 100 assertTrue(finder.find("m1").isPresent()); 101 assertTrue(finder.find("m2").isPresent()); 102 assertFalse(finder.find("java.rhubarb").isPresent()); 103 } 104 105 106 /** 107 * Test ModuleFinder.of with two directories 108 */ 109 public void testOfTwoDirectories() throws Exception { 110 Path dir1 = Files.createTempDirectory(USER_DIR, "mods1"); 111 createExplodedModule(dir1.resolve("m1"), "m1@1.0"); 112 createModularJar(dir1.resolve("m2.jar"), "m2@1.0"); 113 114 Path dir2 = Files.createTempDirectory(USER_DIR, "mods2"); 115 createExplodedModule(dir2.resolve("m1"), "m1@2.0"); 116 createModularJar(dir2.resolve("m2.jar"), "m2@2.0"); 117 createExplodedModule(dir2.resolve("m3"), "m3"); 118 createModularJar(dir2.resolve("m4.jar"), "m4"); 119 120 ModuleFinder finder = ModuleFinder.of(dir1, dir2); 121 assertTrue(finder.findAll().size() == 4); 122 assertTrue(finder.find("m1").isPresent()); 123 assertTrue(finder.find("m2").isPresent()); 124 assertTrue(finder.find("m3").isPresent()); 125 assertTrue(finder.find("m4").isPresent()); 126 assertFalse(finder.find("java.rhubarb").isPresent()); 127 128 // check that m1@1.0 (and not m1@2.0) is found 129 ModuleDescriptor m1 = finder.find("m1").get().descriptor(); 130 assertEquals(m1.version().get().toString(), "1.0"); 131 132 // check that m2@1.0 (and not m2@2.0) is found 133 ModuleDescriptor m2 = finder.find("m2").get().descriptor(); 134 assertEquals(m2.version().get().toString(), "1.0"); 135 } 136 137 138 /** 139 * Test ModuleFinder.of with one JAR file 140 */ 141 public void testOfOneJarFile() throws Exception { 142 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 143 Path jar1 = createModularJar(dir.resolve("m1.jar"), "m1"); 144 145 ModuleFinder finder = ModuleFinder.of(jar1); 146 assertTrue(finder.findAll().size() == 1); 147 assertTrue(finder.find("m1").isPresent()); 148 assertFalse(finder.find("java.rhubarb").isPresent()); 149 } 150 151 152 /** 153 * Test ModuleFinder.of with two JAR files 154 */ 155 public void testOfTwoJarFiles() throws Exception { 156 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 157 158 Path jar1 = createModularJar(dir.resolve("m1.jar"), "m1"); 159 Path jar2 = createModularJar(dir.resolve("m2.jar"), "m2"); 160 161 ModuleFinder finder = ModuleFinder.of(jar1, jar2); 162 assertTrue(finder.findAll().size() == 2); 163 assertTrue(finder.find("m1").isPresent()); 164 assertTrue(finder.find("m2").isPresent()); 165 assertFalse(finder.find("java.rhubarb").isPresent()); 166 } 167 168 169 /** 170 * Test ModuleFinder.of with many JAR files 171 */ 172 public void testOfManyJarFiles() throws Exception { 173 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 174 175 Path jar1 = createModularJar(dir.resolve("m1@1.0.jar"), "m1@1.0"); 176 Path jar2 = createModularJar(dir.resolve("m2@1.0.jar"), "m2"); 177 Path jar3 = createModularJar(dir.resolve("m1@2.0.jar"), "m1@2.0"); // shadowed 178 Path jar4 = createModularJar(dir.resolve("m3@1.0.jar"), "m3"); 179 180 ModuleFinder finder = ModuleFinder.of(jar1, jar2, jar3, jar4); 181 assertTrue(finder.findAll().size() == 3); 182 assertTrue(finder.find("m1").isPresent()); 183 assertTrue(finder.find("m2").isPresent()); 184 assertTrue(finder.find("m3").isPresent()); 185 assertFalse(finder.find("java.rhubarb").isPresent()); 186 187 // check that m1@1.0 (and not m1@2.0) is found 188 ModuleDescriptor m1 = finder.find("m1").get().descriptor(); 189 assertEquals(m1.version().get().toString(), "1.0"); 190 } 191 192 193 /** 194 * Test ModuleFinder.of with one exploded module. 195 */ 196 public void testOfOneExplodedModule() throws Exception { 197 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 198 Path m1_dir = createExplodedModule(dir.resolve("m1"), "m1"); 199 200 ModuleFinder finder = ModuleFinder.of(m1_dir); 201 assertTrue(finder.findAll().size() == 1); 202 assertTrue(finder.find("m1").isPresent()); 203 assertFalse(finder.find("java.rhubarb").isPresent()); 204 } 205 206 207 /** 208 * Test ModuleFinder.of with two exploded modules. 209 */ 210 public void testOfTwoExplodedModules() throws Exception { 211 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 212 Path m1_dir = createExplodedModule(dir.resolve("m1"), "m1"); 213 Path m2_dir = createExplodedModule(dir.resolve("m2"), "m2"); 214 215 ModuleFinder finder = ModuleFinder.of(m1_dir, m2_dir); 216 assertTrue(finder.findAll().size() == 2); 217 assertTrue(finder.find("m1").isPresent()); 218 assertTrue(finder.find("m2").isPresent()); 219 assertFalse(finder.find("java.rhubarb").isPresent()); 220 } 221 222 223 /** 224 * Test ModuleFinder.of with a mix of module directories and JAR files. 225 */ 226 public void testOfMixDirectoriesAndJars() throws Exception { 227 228 // directory with m1@1.0 and m2@1.0 229 Path dir1 = Files.createTempDirectory(USER_DIR, "mods1"); 230 createExplodedModule(dir1.resolve("m1"), "m1@1.0"); 231 createModularJar(dir1.resolve("m2.jar"), "m2@1.0"); 232 233 // JAR files: m1@2.0, m2@2.0, m3@2.0, m4@2.0 234 Path dir2 = Files.createTempDirectory(USER_DIR, "mods2"); 235 Path jar1 = createModularJar(dir2.resolve("m1.jar"), "m1@2.0"); 236 Path jar2 = createModularJar(dir2.resolve("m2.jar"), "m2@2.0"); 237 Path jar3 = createModularJar(dir2.resolve("m3.jar"), "m3@2.0"); 238 Path jar4 = createModularJar(dir2.resolve("m4.jar"), "m4@2.0"); 239 240 // directory with m3@3.0 and m4@3.0 241 Path dir3 = Files.createTempDirectory(USER_DIR, "mods3"); 242 createExplodedModule(dir3.resolve("m3"), "m3@3.0"); 243 createModularJar(dir3.resolve("m4.jar"), "m4@3.0"); 244 245 // JAR files: m5 and m6 246 Path dir4 = Files.createTempDirectory(USER_DIR, "mods4"); 247 Path jar5 = createModularJar(dir4.resolve("m5.jar"), "m5@4.0"); 248 Path jar6 = createModularJar(dir4.resolve("m6.jar"), "m6@4.0"); 249 250 251 ModuleFinder finder 252 = ModuleFinder.of(dir1, jar1, jar2, jar3, jar4, dir3, jar5, jar6); 253 assertTrue(finder.findAll().size() == 6); 254 assertTrue(finder.find("m1").isPresent()); 255 assertTrue(finder.find("m2").isPresent()); 256 assertTrue(finder.find("m3").isPresent()); 257 assertTrue(finder.find("m4").isPresent()); 258 assertTrue(finder.find("m5").isPresent()); 259 assertTrue(finder.find("m6").isPresent()); 260 assertFalse(finder.find("java.rhubarb").isPresent()); 261 262 // m1 and m2 should be located in dir1 263 ModuleDescriptor m1 = finder.find("m1").get().descriptor(); 264 assertEquals(m1.version().get().toString(), "1.0"); 265 ModuleDescriptor m2 = finder.find("m2").get().descriptor(); 266 assertEquals(m2.version().get().toString(), "1.0"); 267 268 // m3 and m4 should be located in JAR files 269 ModuleDescriptor m3 = finder.find("m3").get().descriptor(); 270 assertEquals(m3.version().get().toString(), "2.0"); 271 ModuleDescriptor m4 = finder.find("m4").get().descriptor(); 272 assertEquals(m4.version().get().toString(), "2.0"); 273 274 // m5 and m6 should be located in JAR files 275 ModuleDescriptor m5 = finder.find("m5").get().descriptor(); 276 assertEquals(m5.version().get().toString(), "4.0"); 277 ModuleDescriptor m6 = finder.find("m6").get().descriptor(); 278 assertEquals(m6.version().get().toString(), "4.0"); 279 } 280 281 282 /** 283 * Test ModuleFinder.of with a mix of module directories and exploded 284 * modules. 285 */ 286 public void testOfMixDirectoriesAndExplodedModules() throws Exception { 287 // directory with m1@1.0 and m2@1.0 288 Path dir1 = Files.createTempDirectory(USER_DIR, "mods1"); 289 createExplodedModule(dir1.resolve("m1"), "m1@1.0"); 290 createModularJar(dir1.resolve("m2.jar"), "m2@1.0"); 291 292 // exploded modules: m1@2.0, m2@2.0, m3@2.0, m4@2.0 293 Path dir2 = Files.createTempDirectory(USER_DIR, "mods2"); 294 Path m1_dir = createExplodedModule(dir2.resolve("m1"), "m1@2.0"); 295 Path m2_dir = createExplodedModule(dir2.resolve("m2"), "m2@2.0"); 296 Path m3_dir = createExplodedModule(dir2.resolve("m3"), "m3@2.0"); 297 Path m4_dir = createExplodedModule(dir2.resolve("m4"), "m4@2.0"); 298 299 ModuleFinder finder = ModuleFinder.of(dir1, m1_dir, m2_dir, m3_dir, m4_dir); 300 assertTrue(finder.findAll().size() == 4); 301 assertTrue(finder.find("m1").isPresent()); 302 assertTrue(finder.find("m2").isPresent()); 303 assertTrue(finder.find("m3").isPresent()); 304 assertTrue(finder.find("m4").isPresent()); 305 assertFalse(finder.find("java.rhubarb").isPresent()); 306 307 // m1 and m2 should be located in dir1 308 ModuleDescriptor m1 = finder.find("m1").get().descriptor(); 309 assertEquals(m1.version().get().toString(), "1.0"); 310 ModuleDescriptor m2 = finder.find("m2").get().descriptor(); 311 assertEquals(m2.version().get().toString(), "1.0"); 312 313 // m3 and m4 should be located in dir2 314 ModuleDescriptor m3 = finder.find("m3").get().descriptor(); 315 assertEquals(m3.version().get().toString(), "2.0"); 316 ModuleDescriptor m4 = finder.find("m4").get().descriptor(); 317 assertEquals(m4.version().get().toString(), "2.0"); 318 } 319 320 321 /** 322 * Test ModuleFinder with a JAR file containing a mix of class and 323 * non-class resources. 324 */ 325 public void testOfOneJarFileWithResources() throws Exception { 326 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 327 Path jar = createModularJar(dir.resolve("m.jar"), "m", 328 "LICENSE", 329 "README", 330 "WEB-INF/tags", 331 "p/Type.class", 332 "p/resources/m.properties", 333 "q-/Type.class", // not a legal package name 334 "q-/resources/m/properties"); 335 336 ModuleFinder finder = ModuleFinder.of(jar); 337 Optional<ModuleReference> mref = finder.find("m"); 338 assertTrue(mref.isPresent(), "m1 not found"); 339 340 ModuleDescriptor descriptor = mref.get().descriptor(); 341 342 assertTrue(descriptor.packages().size() == 2); 343 assertTrue(descriptor.packages().contains("p")); 344 assertTrue(descriptor.packages().contains("p.resources")); 345 } 346 347 348 /** 349 * Test ModuleFinder with an exploded module containing a mix of class 350 * and non-class resources 351 */ 352 public void testOfOneExplodedModuleWithResources() throws Exception { 353 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 354 Path m_dir = createExplodedModule(dir.resolve("m"), "m", 355 "LICENSE", 356 "README", 357 "WEB-INF/tags", 358 "p/Type.class", 359 "p/resources/m.properties", 360 "q-/Type.class", // not a legal package name 361 "q-/resources/m/properties"); 362 363 ModuleFinder finder = ModuleFinder.of(m_dir); 364 Optional<ModuleReference> mref = finder.find("m"); 365 assertTrue(mref.isPresent(), "m not found"); 366 367 ModuleDescriptor descriptor = mref.get().descriptor(); 368 369 assertTrue(descriptor.packages().size() == 2); 370 assertTrue(descriptor.packages().contains("p")); 371 assertTrue(descriptor.packages().contains("p.resources")); 372 } 373 374 375 /** 376 * Test ModuleModule with a JAR file containing a .class file in the top 377 * level directory. 378 */ 379 public void testOfOneJarFileWithTopLevelClass() throws Exception { 380 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 381 Path jar = createModularJar(dir.resolve("m.jar"), "m", "Mojo.class"); 382 383 ModuleFinder finder = ModuleFinder.of(jar); 384 try { 385 finder.find("m"); 386 assertTrue(false); 387 } catch (FindException e) { 388 assertTrue(e.getCause() instanceof InvalidModuleDescriptorException); 389 } 390 391 finder = ModuleFinder.of(jar); 392 try { 393 finder.findAll(); 394 assertTrue(false); 395 } catch (FindException e) { 396 assertTrue(e.getCause() instanceof InvalidModuleDescriptorException); 397 } 398 } 399 400 /** 401 * Test ModuleModule with a JAR file containing a .class file in the top 402 * level directory. 403 */ 404 public void testOfOneExplodedModuleWithTopLevelClass() throws Exception { 405 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 406 Path m_dir = createExplodedModule(dir.resolve("m"), "m", "Mojo.class"); 407 408 ModuleFinder finder = ModuleFinder.of(m_dir); 409 try { 410 finder.find("m"); 411 assertTrue(false); 412 } catch (FindException e) { 413 assertTrue(e.getCause() instanceof InvalidModuleDescriptorException); 414 } 415 416 finder = ModuleFinder.of(m_dir); 417 try { 418 finder.findAll(); 419 assertTrue(false); 420 } catch (FindException e) { 421 assertTrue(e.getCause() instanceof InvalidModuleDescriptorException); 422 } 423 } 424 425 426 /** 427 * Test ModuleFinder.of with a path to a file that does not exist. 428 */ 429 public void testOfWithDoesNotExistEntry() throws Exception { 430 Path dir1 = Files.createTempDirectory(USER_DIR, "mods1"); 431 432 Path dir2 = Files.createTempDirectory(USER_DIR, "mods2"); 433 createModularJar(dir2.resolve("m2.jar"), "m2@1.0"); 434 435 Files.delete(dir1); 436 437 ModuleFinder finder = ModuleFinder.of(dir1, dir2); 438 439 assertTrue(finder.find("m2").isPresent()); 440 assertTrue(finder.findAll().size() == 1); 441 assertFalse(finder.find("java.rhubarb").isPresent()); 442 } 443 444 445 /** 446 * Test ModuleFinder.of with a file path to an unrecognized file type. 447 */ 448 public void testOfWithUnrecognizedEntry() throws Exception { 449 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 450 Path mod = Files.createTempFile(dir, "m", ".junk"); 451 452 ModuleFinder finder = ModuleFinder.of(mod); 453 try { 454 finder.find("java.rhubarb"); 455 assertTrue(false); 456 } catch (FindException e) { 457 // expected 458 } 459 460 finder = ModuleFinder.of(mod); 461 try { 462 finder.findAll(); 463 assertTrue(false); 464 } catch (FindException e) { 465 // expected 466 } 467 } 468 469 470 /** 471 * Test ModuleFinder.of with a file path to a directory containing a file 472 * that will not be recognized as a module. 473 */ 474 public void testOfWithUnrecognizedEntryInDirectory1() throws Exception { 475 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 476 Files.createTempFile(dir, "m", ".junk"); 477 478 ModuleFinder finder = ModuleFinder.of(dir); 479 assertFalse(finder.find("java.rhubarb").isPresent()); 480 481 finder = ModuleFinder.of(dir); 482 assertTrue(finder.findAll().isEmpty()); 483 } 484 485 486 /** 487 * Test ModuleFinder.of with a file path to a directory containing a file 488 * that will not be recognized as a module. 489 */ 490 public void testOfWithUnrecognizedEntryInDirectory2() throws Exception { 491 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 492 createModularJar(dir.resolve("m1.jar"), "m1"); 493 Files.createTempFile(dir, "m2", ".junk"); 494 495 ModuleFinder finder = ModuleFinder.of(dir); 496 assertTrue(finder.find("m1").isPresent()); 497 assertFalse(finder.find("m2").isPresent()); 498 499 finder = ModuleFinder.of(dir); 500 assertTrue(finder.findAll().size() == 1); 501 } 502 503 504 /** 505 * Test ModuleFinder.of with a directory that contains two 506 * versions of the same module 507 */ 508 public void testOfDuplicateModulesInDirectory() throws Exception { 509 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 510 createModularJar(dir.resolve("m1@1.0.jar"), "m1"); 511 createModularJar(dir.resolve("m1@2.0.jar"), "m1"); 512 513 ModuleFinder finder = ModuleFinder.of(dir); 514 try { 515 finder.find("m1"); 516 assertTrue(false); 517 } catch (FindException expected) { } 518 519 finder = ModuleFinder.of(dir); 520 try { 521 finder.findAll(); 522 assertTrue(false); 523 } catch (FindException expected) { } 524 } 525 526 527 /** 528 * Test ModuleFinder.of with a truncated module-info.class 529 */ 530 public void testOfWithTruncatedModuleInfo() throws Exception { 531 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 532 533 // create an empty <dir>/rhubarb/module-info.class 534 Path subdir = Files.createDirectory(dir.resolve("rhubarb")); 535 Files.createFile(subdir.resolve("module-info.class")); 536 537 ModuleFinder finder = ModuleFinder.of(dir); 538 try { 539 finder.find("rhubarb"); 540 assertTrue(false); 541 } catch (FindException e) { 542 assertTrue(e.getCause() instanceof InvalidModuleDescriptorException); 543 } 544 545 finder = ModuleFinder.of(dir); 546 try { 547 finder.findAll(); 548 assertTrue(false); 549 } catch (FindException e) { 550 assertTrue(e.getCause() instanceof InvalidModuleDescriptorException); 551 } 552 } 553 554 555 /** 556 * Test ModuleFinder.compose with no module finders 557 */ 558 public void testComposeOfNone() throws Exception { 559 ModuleFinder finder = ModuleFinder.of(); 560 assertTrue(finder.findAll().isEmpty()); 561 assertFalse(finder.find("java.rhubarb").isPresent()); 562 } 563 564 565 /** 566 * Test ModuleFinder.compose with one module finder 567 */ 568 public void testComposeOfOne() throws Exception { 569 Path dir = Files.createTempDirectory(USER_DIR, "mods"); 570 createModularJar(dir.resolve("m1.jar"), "m1"); 571 createModularJar(dir.resolve("m2.jar"), "m2"); 572 573 ModuleFinder finder1 = ModuleFinder.of(dir); 574 575 ModuleFinder finder = ModuleFinder.compose(finder1); 576 assertTrue(finder.findAll().size() == 2); 577 assertTrue(finder.find("m1").isPresent()); 578 assertTrue(finder.find("m2").isPresent()); 579 assertFalse(finder.find("java.rhubarb").isPresent()); 580 } 581 582 583 /** 584 * Test ModuleFinder.compose with two module finders 585 */ 586 public void testComposeOfTwo() throws Exception { 587 Path dir1 = Files.createTempDirectory(USER_DIR, "mods1"); 588 createModularJar(dir1.resolve("m1.jar"), "m1@1.0"); 589 createModularJar(dir1.resolve("m2.jar"), "m2@1.0"); 590 591 Path dir2 = Files.createTempDirectory(USER_DIR, "mods2"); 592 createModularJar(dir2.resolve("m1.jar"), "m1@2.0"); 593 createModularJar(dir2.resolve("m2.jar"), "m2@2.0"); 594 createModularJar(dir2.resolve("m3.jar"), "m3"); 595 createModularJar(dir2.resolve("m4.jar"), "m4"); 596 597 ModuleFinder finder1 = ModuleFinder.of(dir1); 598 ModuleFinder finder2 = ModuleFinder.of(dir2); 599 600 ModuleFinder finder = ModuleFinder.compose(finder1, finder2); 601 assertTrue(finder.findAll().size() == 4); 602 assertTrue(finder.find("m1").isPresent()); 603 assertTrue(finder.find("m2").isPresent()); 604 assertTrue(finder.find("m3").isPresent()); 605 assertTrue(finder.find("m4").isPresent()); 606 assertFalse(finder.find("java.rhubarb").isPresent()); 607 608 // check that m1@1.0 is found 609 ModuleDescriptor m1 = finder.find("m1").get().descriptor(); 610 assertEquals(m1.version().get().toString(), "1.0"); 611 612 // check that m2@1.0 is found 613 ModuleDescriptor m2 = finder.find("m2").get().descriptor(); 614 assertEquals(m2.version().get().toString(), "1.0"); 615 } 616 617 618 /** 619 * Test ModuleFinder.compose with three module finders 620 */ 621 public void testComposeOfThree() throws Exception { 622 Path dir1 = Files.createTempDirectory(USER_DIR, "mods1"); 623 createModularJar(dir1.resolve("m1.jar"), "m1@1.0"); 624 createModularJar(dir1.resolve("m2.jar"), "m2@1.0"); 625 626 Path dir2 = Files.createTempDirectory(USER_DIR, "mods2"); 627 createModularJar(dir2.resolve("m1.jar"), "m1@2.0"); 628 createModularJar(dir2.resolve("m2.jar"), "m2@2.0"); 629 createModularJar(dir2.resolve("m3.jar"), "m3@2.0"); 630 createModularJar(dir2.resolve("m4.jar"), "m4@2.0"); 631 632 Path dir3 = Files.createTempDirectory(USER_DIR, "mods3"); 633 createModularJar(dir3.resolve("m3.jar"), "m3@3.0"); 634 createModularJar(dir3.resolve("m4.jar"), "m4@3.0"); 635 createModularJar(dir3.resolve("m5.jar"), "m5"); 636 createModularJar(dir3.resolve("m6.jar"), "m6"); 637 638 ModuleFinder finder1 = ModuleFinder.of(dir1); 639 ModuleFinder finder2 = ModuleFinder.of(dir2); 640 ModuleFinder finder3 = ModuleFinder.of(dir3); 641 642 ModuleFinder finder = ModuleFinder.compose(finder1, finder2, finder3); 643 assertTrue(finder.findAll().size() == 6); 644 assertTrue(finder.find("m1").isPresent()); 645 assertTrue(finder.find("m2").isPresent()); 646 assertTrue(finder.find("m3").isPresent()); 647 assertTrue(finder.find("m4").isPresent()); 648 assertTrue(finder.find("m5").isPresent()); 649 assertTrue(finder.find("m6").isPresent()); 650 assertFalse(finder.find("java.rhubarb").isPresent()); 651 652 // check that m1@1.0 is found 653 ModuleDescriptor m1 = finder.find("m1").get().descriptor(); 654 assertEquals(m1.version().get().toString(), "1.0"); 655 656 // check that m2@1.0 is found 657 ModuleDescriptor m2 = finder.find("m2").get().descriptor(); 658 assertEquals(m2.version().get().toString(), "1.0"); 659 660 // check that m3@2.0 is found 661 ModuleDescriptor m3 = finder.find("m3").get().descriptor(); 662 assertEquals(m3.version().get().toString(), "2.0"); 663 664 // check that m4@2.0 is found 665 ModuleDescriptor m4 = finder.find("m4").get().descriptor(); 666 assertEquals(m4.version().get().toString(), "2.0"); 667 } 668 669 670 /** 671 * Test null handling 672 */ 673 public void testNulls() { 674 675 // ofSystem 676 try { 677 ModuleFinder.ofSystem().find(null); 678 assertTrue(false); 679 } catch (NullPointerException expected) { } 680 681 // of 682 Path dir = Paths.get("d"); 683 try { 684 ModuleFinder.of().find(null); 685 assertTrue(false); 686 } catch (NullPointerException expected) { } 687 try { 688 ModuleFinder.of((Path)null); 689 assertTrue(false); 690 } catch (NullPointerException expected) { } 691 try { 692 ModuleFinder.of((Path[])null); 693 assertTrue(false); 694 } catch (NullPointerException expected) { } 695 try { 696 ModuleFinder.of(dir, null); 697 assertTrue(false); 698 } catch (NullPointerException expected) { } 699 try { 700 ModuleFinder.of(null, dir); 701 assertTrue(false); 702 } catch (NullPointerException expected) { } 703 704 // compose 705 ModuleFinder finder = ModuleFinder.of(); 706 try { 707 ModuleFinder.compose((ModuleFinder)null); 708 assertTrue(false); 709 } catch (NullPointerException expected) { } 710 try { 711 ModuleFinder.compose((ModuleFinder[])null); 712 assertTrue(false); 713 } catch (NullPointerException expected) { } 714 try { 715 ModuleFinder.compose(finder, null); 716 assertTrue(false); 717 } catch (NullPointerException expected) { } 718 try { 719 ModuleFinder.compose(null, finder); 720 assertTrue(false); 721 } catch (NullPointerException expected) { } 722 723 } 724 725 726 /** 727 * Parses a string of the form {@code name[@version]} and returns a 728 * ModuleDescriptor with that name and version. The ModuleDescriptor 729 * will have a requires on java.base. 730 */ 731 static ModuleDescriptor newModuleDescriptor(String mid) { 732 String mn; 733 String vs; 734 int i = mid.indexOf("@"); 735 if (i == -1) { 736 mn = mid; 737 vs = null; 738 } else { 739 mn = mid.substring(0, i); 740 vs = mid.substring(i+1); 741 } 742 ModuleDescriptor.Builder builder 743 = ModuleDescriptor.newModule(mn).requires("java.base"); 744 if (vs != null) 745 builder.version(vs); 746 return builder.build(); 747 } 748 749 /** 750 * Creates an exploded module in the given directory and containing a 751 * module descriptor with the given module name/version. 752 */ 753 static Path createExplodedModule(Path dir, String mid, String... entries) 754 throws Exception 755 { 756 ModuleDescriptor descriptor = newModuleDescriptor(mid); 757 Files.createDirectories(dir); 758 Path mi = dir.resolve("module-info.class"); 759 try (OutputStream out = Files.newOutputStream(mi)) { 760 ModuleInfoWriter.write(descriptor, out); 761 } 762 763 for (String entry : entries) { 764 Path file = dir.resolve(entry.replace('/', File.separatorChar)); 765 Files.createDirectories(file.getParent()); 766 Files.createFile(file); 767 } 768 769 return dir; 770 } 771 772 /** 773 * Creates a JAR file with the given file path and containing a module 774 * descriptor with the given module name/version. 775 */ 776 static Path createModularJar(Path file, String mid, String ... entries) 777 throws Exception 778 { 779 ModuleDescriptor descriptor = newModuleDescriptor(mid); 780 try (OutputStream out = Files.newOutputStream(file)) { 781 try (JarOutputStream jos = new JarOutputStream(out)) { 782 783 JarEntry je = new JarEntry("module-info.class"); 784 jos.putNextEntry(je); 785 ModuleInfoWriter.write(descriptor, jos); 786 jos.closeEntry(); 787 788 for (String entry : entries) { 789 je = new JarEntry(entry); 790 jos.putNextEntry(je); 791 jos.closeEntry(); 792 } 793 } 794 795 } 796 return file; 797 } 798 799 } 800