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