1 /*
2 * Copyright (c) 2013, 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 * @bug 8142968 8158456 8298875
27 * @modules java.base/jdk.internal.access
28 * java.base/jdk.internal.module
29 * @library /test/lib
30 * @run testng ModuleDescriptorTest
31 * @summary Basic test for java.lang.module.ModuleDescriptor and its builder
32 */
33
34 import java.io.ByteArrayOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.lang.module.InvalidModuleDescriptorException;
38 import java.lang.module.ModuleDescriptor;
39 import java.lang.module.ModuleDescriptor.Builder;
40 import java.lang.module.ModuleDescriptor.Exports;
41 import java.lang.module.ModuleDescriptor.Opens;
42 import java.lang.module.ModuleDescriptor.Requires;
43 import java.lang.module.ModuleDescriptor.Provides;
44 import java.lang.module.ModuleDescriptor.Requires.Modifier;
45 import java.lang.module.ModuleDescriptor.Version;
46 import java.nio.ByteBuffer;
47 import java.util.ArrayList;
48 import java.util.Collections;
49 import java.util.EnumSet;
50 import java.util.HashSet;
51 import java.util.Iterator;
52 import java.util.List;
53 import java.util.Objects;
54 import java.util.Set;
55 import java.util.stream.Collectors;
56
57 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
58
59 import jdk.internal.access.JavaLangModuleAccess;
60 import jdk.internal.access.SharedSecrets;
61 import java.lang.classfile.ClassFile;
62 import java.lang.classfile.ClassFileVersion;
63 import java.lang.classfile.ClassTransform;
64 import java.lang.classfile.attribute.ModuleAttribute;
65 import java.lang.constant.PackageDesc;
66 import java.lang.constant.ModuleDesc;
67 import jdk.test.lib.util.ModuleInfoWriter;
68 import org.testng.annotations.DataProvider;
69 import org.testng.annotations.Test;
70 import static org.testng.Assert.*;
71
72 @Test
73 public class ModuleDescriptorTest {
74 private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
75
76 @DataProvider(name = "invalidNames")
77 public Object[][] invalidNames() {
78 return new Object[][]{
79
80 { null, null },
81 { "1", null },
82 { "1foo", null },
83 { ".foo", null },
84 { "foo.", null },
85 { "[foo]", null },
86 { "foo.1", null },
87 { "1foo.bar", null },
88 { "foo.1bar", null },
89 { "foo.[bar]", null },
90 { "foo..bar", null },
91 { "foo.bar.1", null },
92 { "foo.bar.1gus", null },
93 { "foo.bar.[gus]", null },
94
95 { "class", null },
96 { "interface", null },
97 { "true", null },
98 { "false", null },
99 { "null", null },
100
101 { "x.class", null },
102 { "x.interface", null },
103 { "x.true", null },
104 { "x.false", null },
105 { "x.null", null },
106
107 { "class.x", null },
108 { "interface.x", null },
109 { "true.x", null },
110 { "false.x", null },
111 { "null.x", null },
112
113 { "x.class.x", null },
114 { "x.interface.x", null },
115 { "x.true.x", null },
116 { "x.false.x", null },
117 { "x.null.x", null },
118
119 { "_", null },
120
121 };
122 }
123
124
125 // requires
126
127 private Requires requires(Set<Modifier> mods, String mn) {
128 return requires(mods, mn, null);
129 }
130
131 private Requires requires(Set<Modifier> mods, String mn, Version v) {
132 Builder builder = ModuleDescriptor.newModule("m");
133 if (v == null) {
134 builder.requires(mods, mn);
135 } else {
136 builder.requires(mods, mn, v);
137 }
138 Set<Requires> requires = builder.build().requires();
139 assertTrue(requires.size() == 2);
140 Iterator<Requires> iterator = requires.iterator();
141 Requires r = iterator.next();
142 if (r.name().equals("java.base")) {
143 r = iterator.next();
144 } else {
145 Requires other = iterator.next();
146 assertEquals(other.name(), "java.base");
147 }
148 return r;
149 }
150
151 private Requires requires(String mn) {
152 return requires(Collections.emptySet(), mn);
153 }
154
155 public void testRequiresWithRequires() {
156 Requires r1 = requires("foo");
157 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").requires(r1).build();
158 assertEquals(descriptor.requires().size(), 2);
159 var iterator = descriptor.requires().iterator();
160 Requires r2 = iterator.next();
161 if (r2.name().equals("java.base")) {
162 r2 = iterator.next();
163 }
164 assertEquals(r1, r2);
165 }
166
167 public void testRequiresWithNoModifiers() {
168 Requires r = requires(EnumSet.noneOf(Requires.Modifier.class), "foo");
169 assertEquals(r, r);
170 assertTrue(r.compareTo(r) == 0);
171 assertTrue(r.modifiers().isEmpty());
172 assertEquals(r.name(), "foo");
173 assertFalse(r.compiledVersion().isPresent());
174 }
175
176 public void testRequiresWithOneModifier() {
177 Requires r = requires(EnumSet.of(TRANSITIVE), "foo");
178 assertEquals(r, r);
179 assertTrue(r.compareTo(r) == 0);
180 assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE));
181 assertEquals(r.name(), "foo");
182 assertFalse(r.compiledVersion().isPresent());
183 }
184
185 public void testRequiresWithTwoModifiers() {
186 Requires r = requires(EnumSet.of(TRANSITIVE, SYNTHETIC), "foo");
187 assertEquals(r, r);
188 assertTrue(r.compareTo(r) == 0);
189 assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, SYNTHETIC));
190 assertEquals(r.name(), "foo");
191 assertFalse(r.compiledVersion().isPresent());
192 }
193
194 public void testRequiresWithAllModifiers() {
195 Requires r = requires(EnumSet.allOf(Modifier.class), "foo");
196 assertEquals(r, r);
197 assertTrue(r.compareTo(r) == 0);
198 assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, STATIC, SYNTHETIC, MANDATED));
199 assertEquals(r.name(), "foo");
200 assertFalse(r.compiledVersion().isPresent());
201 }
202
203 public void testRequiresWithCompiledVersion() {
204 Version v = Version.parse("1.0");
205 Requires r = requires(Set.of(), "foo", v);
206 assertEquals(r, r);
207 assertTrue(r.compareTo(r) == 0);
208 assertEquals(r.modifiers(), Set.of());
209 assertEquals(r.name(), "foo");
210 assertTrue(r.compiledVersion().isPresent());
211 assertEquals(r.compiledVersion().get().toString(), "1.0");
212 }
213
214 @Test(expectedExceptions = IllegalStateException.class)
215 public void testRequiresWithDuplicatesRequires() {
216 Requires r = requires("foo");
217 ModuleDescriptor.newModule("m").requires(r).requires(r);
218 }
219
220 @Test(expectedExceptions = IllegalArgumentException.class)
221 public void testRequiresSelfWithRequires() {
222 Requires r = requires("foo");
223 ModuleDescriptor.newModule("foo").requires(r);
224 }
225
226 @Test(expectedExceptions = IllegalArgumentException.class)
227 public void testRequiresSelfWithNoModifier() {
228 ModuleDescriptor.newModule("m").requires("m");
229 }
230
231 @Test(expectedExceptions = IllegalArgumentException.class)
232 public void testRequiresSelfWithOneModifier() {
233 ModuleDescriptor.newModule("m").requires(Set.of(TRANSITIVE), "m");
234 }
235
236 @Test(expectedExceptions = IllegalArgumentException.class)
237 public void testRequiresSelfWithAllModifiers() {
238 ModuleDescriptor.newModule("m").requires(EnumSet.allOf(Modifier.class), "m");
239 }
240
241 @Test(dataProvider = "invalidNames",
242 expectedExceptions = IllegalArgumentException.class )
243 public void testRequiresWithBadModuleName(String mn, String ignore) {
244 requires(EnumSet.noneOf(Modifier.class), mn);
245 }
246
247 @Test(expectedExceptions = NullPointerException.class)
248 public void testRequiresWithNullRequires() {
249 ModuleDescriptor.newModule("m").requires((Requires) null);
250 }
251
252 @Test(expectedExceptions = NullPointerException.class)
253 public void testRequiresWithNullModifiers() {
254 ModuleDescriptor.newModule("m").requires(null, "foo");
255 }
256
257 @Test(expectedExceptions = NullPointerException.class)
258 public void testRequiresWithNullVersion() {
259 ModuleDescriptor.newModule("m").requires(Set.of(), "foo", null);
260 }
261
262 public void testRequiresCompare() {
263 Requires r1 = requires(EnumSet.noneOf(Modifier.class), "foo");
264 Requires r2 = requires(EnumSet.noneOf(Modifier.class), "bar");
265 int n = "foo".compareTo("bar");
266 assertTrue(r1.compareTo(r2) == n);
267 assertTrue(r2.compareTo(r1) == -n);
268 }
269
270 public void testRequiresCompareWithDifferentModifiers() {
271 Requires r1 = requires(EnumSet.of(TRANSITIVE), "foo");
272 Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
273 int n = Integer.compare(1 << TRANSITIVE.ordinal(), 1 << SYNTHETIC.ordinal());
274 assertTrue(r1.compareTo(r2) == n);
275 assertTrue(r2.compareTo(r1) == -n);
276 }
277
278 public void testRequiresCompareWithSameModifiers() {
279 Requires r1 = requires(EnumSet.of(SYNTHETIC), "foo");
280 Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
281 assertTrue(r1.compareTo(r2) == 0);
282 assertTrue(r2.compareTo(r1) == 0);
283 }
284
285 public void testRequiresCompareWithSameCompiledVersion() {
286 Requires r1 = requires(Set.of(), "foo", Version.parse("2.0"));
287 Requires r2 = requires(Set.of(), "foo", Version.parse("2.0"));
288 assertTrue(r1.compareTo(r2) == 0);
289 assertTrue(r2.compareTo(r1) == 0);
290 }
291
292 public void testRequiresCompareWithDifferentCompiledVersion() {
293 Requires r1 = requires(Set.of(), "foo", Version.parse("1.0"));
294 Requires r2 = requires(Set.of(), "foo", Version.parse("2.0"));
295 assertTrue(r1.compareTo(r2) < 0);
296 assertTrue(r2.compareTo(r1) > 0);
297 }
298
299 public void testRequiresEqualsAndHashCode() {
300 Requires r1 = requires("foo");
301 Requires r2 = requires("foo");
302 assertEquals(r1, r2);
303 assertTrue(r1.hashCode() == r2.hashCode());
304
305 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
306 r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
307 assertEquals(r1, r2);
308 assertTrue(r1.hashCode() == r2.hashCode());
309
310 r1 = requires("foo");
311 r2 = requires("bar");
312 assertNotEquals(r1, r2);
313
314 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
315 r2 = requires(Set.of(), "foo");
316 assertNotEquals(r1, r2);
317
318 Version v1 = Version.parse("1.0");
319 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
320 r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
321 assertEquals(r1, r2);
322 assertTrue(r1.hashCode() == r2.hashCode());
323
324 Version v2 = Version.parse("2.0");
325 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
326 r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v2);
327 assertNotEquals(r1, r2);
328 }
329
330 public void testRequiresToString() {
331 Requires r = requires(EnumSet.noneOf(Modifier.class), "foo");
332 assertTrue(r.toString().contains("foo"));
333 }
334
335
336 // exports
337
338 private Exports exports(Set<Exports.Modifier> mods, String pn) {
339 return ModuleDescriptor.newModule("foo")
340 .exports(mods, pn)
341 .build()
342 .exports()
343 .iterator()
344 .next();
345 }
346
347 private Exports exports(String pn) {
348 return exports(Set.of(), pn);
349 }
350
351 private Exports exports(Set<Exports.Modifier> mods, String pn, String target) {
352 return ModuleDescriptor.newModule("foo")
353 .exports(mods, pn, Set.of(target))
354 .build()
355 .exports()
356 .iterator()
357 .next();
358 }
359
360 private Exports exports(String pn, String target) {
361 return exports(Set.of(), pn, target);
362 }
363
364
365 public void testExportsExports() {
366 Exports e1 = exports("p");
367 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").exports(e1).build();
368 Exports e2 = descriptor.exports().iterator().next();
369 assertEquals(e1, e2);
370 }
371
372 public void testExportsToAll() {
373 Exports e = exports("p");
374 assertEquals(e, e);
375 assertTrue(e.modifiers().isEmpty());
376 assertEquals(e.source(), "p");
377 assertFalse(e.isQualified());
378 assertTrue(e.targets().isEmpty());
379 }
380
381 public void testExportsToTarget() {
382 Exports e = exports("p", "bar");
383 assertEquals(e, e);
384 assertTrue(e.modifiers().isEmpty());
385 assertEquals(e.source(), "p");
386 assertTrue(e.isQualified());
387 assertTrue(e.targets().size() == 1);
388 assertTrue(e.targets().contains("bar"));
389 }
390
391 public void testExportsToTargets() {
392 Set<String> targets = new HashSet<>();
393 targets.add("bar");
394 targets.add("gus");
395 Exports e
396 = ModuleDescriptor.newModule("foo")
397 .exports("p", targets)
398 .build()
399 .exports()
400 .iterator()
401 .next();
402 assertEquals(e, e);
403 assertTrue(e.modifiers().isEmpty());
404 assertEquals(e.source(), "p");
405 assertTrue(e.isQualified());
406 assertTrue(e.targets().size() == 2);
407 assertTrue(e.targets().contains("bar"));
408 assertTrue(e.targets().contains("gus"));
409 }
410
411 public void testExportsToAllWithModifier() {
412 Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
413 assertEquals(e, e);
414 assertTrue(e.modifiers().size() == 1);
415 assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
416 assertEquals(e.source(), "p");
417 assertFalse(e.isQualified());
418 assertTrue(e.targets().isEmpty());
419 }
420
421 public void testExportsToTargetWithModifier() {
422 Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", "bar");
423 assertEquals(e, e);
424 assertTrue(e.modifiers().size() == 1);
425 assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
426 assertEquals(e.source(), "p");
427 assertTrue(e.isQualified());
428 assertTrue(e.targets().size() == 1);
429 assertTrue(e.targets().contains("bar"));
430 }
431
432 @Test(expectedExceptions = IllegalStateException.class)
433 public void testExportsWithDuplicate1() {
434 Exports e = exports("p");
435 ModuleDescriptor.newModule("foo").exports(e).exports(e);
436 }
437
438 @Test(expectedExceptions = IllegalStateException.class)
439 public void testExportsWithDuplicate2() {
440 ModuleDescriptor.newModule("foo").exports("p").exports("p");
441 }
442
443 @Test(expectedExceptions = IllegalArgumentException.class )
444 public void testExportsWithEmptySet() {
445 ModuleDescriptor.newModule("foo").exports("p", Collections.emptySet());
446 }
447
448 @Test(dataProvider = "invalidNames",
449 expectedExceptions = IllegalArgumentException.class )
450 public void testExportsWithBadName(String pn, String ignore) {
451 ModuleDescriptor.newModule("foo").exports(pn);
452 }
453
454 @Test(expectedExceptions = NullPointerException.class )
455 public void testExportsWithNullExports() {
456 ModuleDescriptor.newModule("foo").exports((Exports) null);
457 }
458
459 @Test(expectedExceptions = NullPointerException.class )
460 public void testExportsWithNullTargets() {
461 ModuleDescriptor.newModule("foo").exports("p", (Set<String>) null);
462 }
463
464 public void testExportsCompare() {
465 Exports e1 = exports("p");
466 Exports e2 = exports("p");
467 assertEquals(e1, e2);
468 assertTrue(e1.hashCode() == e2.hashCode());
469 assertTrue(e1.compareTo(e2) == 0);
470 assertTrue(e2.compareTo(e1) == 0);
471 }
472
473 public void testExportsCompareWithSameModifiers() {
474 Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
475 Exports e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
476 assertEquals(e1, e2);
477 assertTrue(e1.hashCode() == e2.hashCode());
478 assertTrue(e1.compareTo(e2) == 0);
479 assertTrue(e2.compareTo(e1) == 0);
480 }
481
482 public void testExportsCompareWithDifferentModifiers() {
483 Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
484 Exports e2 = exports("p");
485 assertNotEquals(e1, e2);
486 assertTrue(e1.compareTo(e2) == 1);
487 assertTrue(e2.compareTo(e1) == -1);
488 }
489
490 public void testExportsCompareWithSameTargets() {
491 Exports e1 = exports("p", "x");
492 Exports e2 = exports("p", "x");
493 assertEquals(e1, e2);
494 assertTrue(e1.hashCode() == e2.hashCode());
495 assertTrue(e1.compareTo(e2) == 0);
496 assertTrue(e2.compareTo(e1) == 0);
497 }
498
499 public void testExportsCompareWithDifferentTargets() {
500 Exports e1 = exports("p", "y");
501 Exports e2 = exports("p", "x");
502 assertNotEquals(e1, e2);
503 assertTrue(e1.compareTo(e2) == 1);
504 assertTrue(e2.compareTo(e1) == -1);
505 }
506
507 public void testExportsToString() {
508 String s = ModuleDescriptor.newModule("foo")
509 .exports("p1", Set.of("bar"))
510 .build()
511 .exports()
512 .iterator()
513 .next()
514 .toString();
515 assertTrue(s.contains("p1"));
516 assertTrue(s.contains("bar"));
517 }
518
519
520 // opens
521
522 private Opens opens(Set<Opens.Modifier> mods, String pn) {
523 return ModuleDescriptor.newModule("foo")
524 .opens(mods, pn)
525 .build()
526 .opens()
527 .iterator()
528 .next();
529 }
530
531 private Opens opens(String pn) {
532 return opens(Set.of(), pn);
533 }
534
535 private Opens opens(Set<Opens.Modifier> mods, String pn, String target) {
536 return ModuleDescriptor.newModule("foo")
537 .opens(mods, pn, Set.of(target))
538 .build()
539 .opens()
540 .iterator()
541 .next();
542 }
543
544 private Opens opens(String pn, String target) {
545 return opens(Set.of(), pn, target);
546 }
547
548 public void testOpensOpens() {
549 Opens o1 = opens("p");
550 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").opens(o1).build();
551 Opens o2 = descriptor.opens().iterator().next();
552 assertEquals(o1, o2);
553 }
554
555 public void testOpensToAll() {
556 Opens o = opens("p");
557 assertEquals(o, o);
558 assertTrue(o.modifiers().isEmpty());
559 assertEquals(o.source(), "p");
560 assertFalse(o.isQualified());
561 assertTrue(o.targets().isEmpty());
562 }
563
564
565 public void testOpensToTarget() {
566 Opens o = opens("p", "bar");
567 assertEquals(o, o);
568 assertTrue(o.modifiers().isEmpty());
569 assertEquals(o.source(), "p");
570 assertTrue(o.isQualified());
571 assertTrue(o.targets().size() == 1);
572 assertTrue(o.targets().contains("bar"));
573 }
574
575 public void testOpensToTargets() {
576 Set<String> targets = new HashSet<>();
577 targets.add("bar");
578 targets.add("gus");
579 Opens o = ModuleDescriptor.newModule("foo")
580 .opens("p", targets)
581 .build()
582 .opens()
583 .iterator()
584 .next();
585 assertEquals(o, o);
586 assertTrue(o.modifiers().isEmpty());
587 assertEquals(o.source(), "p");
588 assertTrue(o.isQualified());
589 assertTrue(o.targets().size() == 2);
590 assertTrue(o.targets().contains("bar"));
591 assertTrue(o.targets().contains("gus"));
592 }
593
594 @Test(expectedExceptions = IllegalStateException.class)
595 public void testOpensWithDuplicate1() {
596 Opens o = opens("p");
597 ModuleDescriptor.newModule("foo").opens(o).opens(o);
598 }
599
600 @Test(expectedExceptions = IllegalStateException.class)
601 public void testOpensWithDuplicate2() {
602 ModuleDescriptor.newModule("foo").opens("p").opens("p");
603 }
604
605 @Test(expectedExceptions = IllegalArgumentException.class )
606 public void testOpensWithEmptySet() {
607 ModuleDescriptor.newModule("foo").opens("p", Collections.emptySet());
608 }
609
610 @Test(dataProvider = "invalidNames",
611 expectedExceptions = IllegalArgumentException.class )
612 public void testOpensWithBadName(String pn, String ignore) {
613 ModuleDescriptor.newModule("foo").opens(pn);
614 }
615
616 @Test(expectedExceptions = NullPointerException.class )
617 public void testOpensWithNullExports() {
618 ModuleDescriptor.newModule("foo").opens((Opens) null);
619 }
620
621 @Test(expectedExceptions = NullPointerException.class )
622 public void testOpensWithNullTargets() {
623 ModuleDescriptor.newModule("foo").opens("p", (Set<String>) null);
624 }
625
626 public void testOpensCompare() {
627 Opens o1 = opens("p");
628 Opens o2 = opens("p");
629 assertEquals(o1, o2);
630 assertTrue(o1.hashCode() == o2.hashCode());
631 assertTrue(o1.compareTo(o2) == 0);
632 assertTrue(o2.compareTo(o1) == 0);
633 }
634
635 public void testOpensCompareWithSameModifiers() {
636 Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
637 Opens o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
638 assertEquals(o1, o2);
639 assertTrue(o1.hashCode() == o2.hashCode());
640 assertTrue(o1.compareTo(o2) == 0);
641 assertTrue(o2.compareTo(o1) == 0);
642 }
643
644 public void testOpensCompareWithDifferentModifiers() {
645 Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
646 Opens o2 = opens("p");
647 assertNotEquals(o1, o2);
648 assertTrue(o1.compareTo(o2) == 1);
649 assertTrue(o2.compareTo(o1) == -1);
650 }
651
652 public void testOpensCompareWithSameTargets() {
653 Opens o1 = opens("p", "x");
654 Opens o2 = opens("p", "x");
655 assertEquals(o1, o2);
656 assertTrue(o1.hashCode() == o2.hashCode());
657 assertTrue(o1.compareTo(o2) == 0);
658 assertTrue(o2.compareTo(o1) == 0);
659 }
660
661 public void testOpensCompareWithDifferentTargets() {
662 Opens o1 = opens("p", "y");
663 Opens o2 = opens("p", "x");
664 assertNotEquals(o1, o2);
665 assertTrue(o1.compareTo(o2) == 1);
666 assertTrue(o2.compareTo(o1) == -1);
667 }
668
669 public void testOpensToString() {
670 String s = ModuleDescriptor.newModule("foo")
671 .opens("p1", Set.of("bar"))
672 .build()
673 .opens()
674 .iterator()
675 .next()
676 .toString();
677 assertTrue(s.contains("p1"));
678 assertTrue(s.contains("bar"));
679 }
680
681
682 // uses
683
684 public void testUses() {
685 Set<String> uses
686 = ModuleDescriptor.newModule("foo")
687 .uses("p.S")
688 .uses("q.S")
689 .build()
690 .uses();
691 assertTrue(uses.size() == 2);
692 assertTrue(uses.contains("p.S"));
693 assertTrue(uses.contains("q.S"));
694 }
695
696 @Test(expectedExceptions = IllegalStateException.class)
697 public void testUsesWithDuplicate() {
698 ModuleDescriptor.newModule("foo").uses("p.S").uses("p.S");
699 }
700
701 @Test(expectedExceptions = IllegalArgumentException.class)
702 public void testUsesWithSimpleIdentifier() {
703 ModuleDescriptor.newModule("foo").uses("S");
704 }
705
706 @Test(dataProvider = "invalidNames",
707 expectedExceptions = IllegalArgumentException.class )
708 public void testUsesWithBadName(String service, String ignore) {
709 ModuleDescriptor.newModule("foo").uses(service);
710 }
711
712
713 // provides
714
715 private Provides provides(String st, String pc) {
716 return ModuleDescriptor.newModule("foo")
717 .provides(st, List.of(pc))
718 .build()
719 .provides()
720 .iterator()
721 .next();
722 }
723
724 private Provides provides(String st, List<String> pns) {
725 return ModuleDescriptor.newModule("foo")
726 .provides(st, pns)
727 .build()
728 .provides()
729 .iterator()
730 .next();
731 }
732
733 public void testProvidesWithProvides() {
734 Provides p1 = provides("p.S", "q.S1");
735 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m")
736 .provides(p1)
737 .build();
738 Provides p2 = descriptor.provides().iterator().next();
739 assertEquals(p1, p2);
740 }
741
742
743 public void testProvides() {
744 Set<Provides> set = ModuleDescriptor.newModule("foo")
745 .provides("p.S", List.of("q.P1", "q.P2"))
746 .build()
747 .provides();
748 assertTrue(set.size() == 1);
749
750 Provides p = set.iterator().next();
751 assertEquals(p, p);
752 assertEquals(p.service(), "p.S");
753 assertTrue(p.providers().size() == 2);
754 assertEquals(p.providers().get(0), "q.P1");
755 assertEquals(p.providers().get(1), "q.P2");
756 }
757
758 @Test(expectedExceptions = IllegalStateException.class )
759 public void testProvidesWithDuplicateProvides() {
760 Provides p = provides("p.S", "q.S2");
761 ModuleDescriptor.newModule("m").provides("p.S", List.of("q.S1")).provides(p);
762 }
763
764 @Test(expectedExceptions = IllegalArgumentException.class )
765 public void testProvidesWithEmptySet() {
766 ModuleDescriptor.newModule("foo").provides("p.Service", Collections.emptyList());
767 }
768
769 @Test(expectedExceptions = IllegalArgumentException.class )
770 public void testProvidesWithSimpleIdentifier1() {
771 ModuleDescriptor.newModule("foo").provides("S", List.of("q.P"));
772 }
773
774 @Test(expectedExceptions = IllegalArgumentException.class )
775 public void testProvidesWithSimpleIdentifier2() {
776 ModuleDescriptor.newModule("foo").provides("p.S", List.of("P"));
777 }
778
779 @Test(dataProvider = "invalidNames",
780 expectedExceptions = IllegalArgumentException.class )
781 public void testProvidesWithBadService(String service, String ignore) {
782 ModuleDescriptor.newModule("foo").provides(service, List.of("p.Provider"));
783 }
784
785 @Test(dataProvider = "invalidNames",
786 expectedExceptions = IllegalArgumentException.class )
787 public void testProvidesWithBadProvider(String provider, String ignore) {
788 List<String> names = new ArrayList<>(); // allows nulls
789 names.add(provider);
790 ModuleDescriptor.newModule("foo").provides("p.Service", names);
791 }
792
793 @Test(expectedExceptions = NullPointerException.class )
794 public void testProvidesWithNullProvides() {
795 ModuleDescriptor.newModule("foo").provides((Provides) null);
796 }
797
798 @Test(expectedExceptions = NullPointerException.class )
799 public void testProvidesWithNullProviders() {
800 ModuleDescriptor.newModule("foo").provides("p.S", (List<String>) null);
801 }
802
803 public void testProvidesCompare() {
804 Provides p1 = provides("p.S", "q.S1");
805 Provides p2 = provides("p.S", "q.S1");
806 assertEquals(p1, p2);
807 assertTrue(p1.hashCode() == p2.hashCode());
808 assertTrue(p1.compareTo(p2) == 0);
809 assertTrue(p2.compareTo(p1) == 0);
810 }
811
812 public void testProvidesCompareWithDifferentService() {
813 Provides p1 = provides("p.S2", "q.S1");
814 Provides p2 = provides("p.S1", "q.S1");
815 assertNotEquals(p1, p2);
816 assertTrue(p1.compareTo(p2) == 1);
817 assertTrue(p2.compareTo(p1) == -1);
818 }
819
820 public void testProvidesCompareWithDifferentProviders1() {
821 Provides p1 = provides("p.S", "q.S2");
822 Provides p2 = provides("p.S", "q.S1");
823 assertNotEquals(p1, p2);
824 assertTrue(p1.compareTo(p2) == 1);
825 assertTrue(p2.compareTo(p1) == -1);
826 }
827
828 public void testProvidesCompareWithDifferentProviders2() {
829 Provides p1 = provides("p.S", List.of("q.S1", "q.S2"));
830 Provides p2 = provides("p.S", "q.S1");
831 assertNotEquals(p1, p2);
832 assertTrue(p1.compareTo(p2) == 1);
833 assertTrue(p2.compareTo(p1) == -1);
834 }
835
836 // packages
837
838 public void testPackages1() {
839 Set<String> packages = ModuleDescriptor.newModule("foo")
840 .packages(Set.of("p", "q"))
841 .build()
842 .packages();
843 assertTrue(packages.size() == 2);
844 assertTrue(packages.contains("p"));
845 assertTrue(packages.contains("q"));
846 }
847
848 public void testPackages2() {
849 Set<String> packages = ModuleDescriptor.newModule("foo")
850 .packages(Set.of("p"))
851 .packages(Set.of("q"))
852 .build()
853 .packages();
854 assertTrue(packages.size() == 2);
855 assertTrue(packages.contains("p"));
856 assertTrue(packages.contains("q"));
857 }
858
859
860 public void testPackagesWithEmptySet() {
861 Set<String> packages = ModuleDescriptor.newModule("foo")
862 .packages(Collections.emptySet())
863 .build()
864 .packages();
865 assertTrue(packages.size() == 0);
866 }
867
868 public void testPackagesDuplicate() {
869 Set<String> packages = ModuleDescriptor.newModule("foo")
870 .packages(Set.of("p"))
871 .packages(Set.of("p"))
872 .build()
873 .packages();
874 assertTrue(packages.size() == 1);
875 assertTrue(packages.contains("p"));
876 }
877
878 public void testPackagesAndExportsPackage1() {
879 Set<String> packages = ModuleDescriptor.newModule("foo")
880 .packages(Set.of("p"))
881 .exports("p")
882 .build()
883 .packages();
884 assertTrue(packages.size() == 1);
885 assertTrue(packages.contains("p"));
886 }
887
888 public void testPackagesAndExportsPackage2() {
889 Set<String> packages = ModuleDescriptor.newModule("foo")
890 .exports("p")
891 .packages(Set.of("p"))
892 .build()
893 .packages();
894 assertTrue(packages.size() == 1);
895 assertTrue(packages.contains("p"));
896 }
897
898 public void testPackagesAndOpensPackage1() {
899 Set<String> packages = ModuleDescriptor.newModule("foo")
900 .packages(Set.of("p"))
901 .opens("p")
902 .build()
903 .packages();
904 assertTrue(packages.size() == 1);
905 assertTrue(packages.contains("p"));
906 }
907
908 public void testPackagesAndOpensPackage2() {
909 Set<String> packages = ModuleDescriptor.newModule("foo")
910 .opens("p")
911 .packages(Set.of("p"))
912 .build()
913 .packages();
914 assertTrue(packages.size() == 1);
915 assertTrue(packages.contains("p"));
916 }
917
918 public void testPackagesAndProvides1() {
919 Set<String> packages = ModuleDescriptor.newModule("foo")
920 .packages(Set.of("p"))
921 .provides("q.S", List.of("p.T"))
922 .build()
923 .packages();
924 assertTrue(packages.size() == 1);
925 assertTrue(packages.contains("p"));
926 }
927
928 public void testPackagesAndProvides2() {
929 Set<String> packages = ModuleDescriptor.newModule("foo")
930 .provides("q.S", List.of("p.T"))
931 .packages(Set.of("p"))
932 .build()
933 .packages();
934 assertTrue(packages.size() == 1);
935 assertTrue(packages.contains("p"));
936 }
937
938 public void testPackagesAndMainClass1() {
939 Set<String> packages = ModuleDescriptor.newModule("foo")
940 .packages(Set.of("p"))
941 .mainClass("p.Main")
942 .build()
943 .packages();
944 assertTrue(packages.size() == 1);
945 assertTrue(packages.contains("p"));
946 }
947
948 public void testPackagesAndMainClass2() {
949 Set<String> packages = ModuleDescriptor.newModule("foo")
950 .mainClass("p.Main")
951 .packages(Set.of("p"))
952 .build()
953 .packages();
954 assertTrue(packages.size() == 1);
955 assertTrue(packages.contains("p"));
956 }
957
958 public void testPackagesAndAll() {
959 Set<String> packages = ModuleDescriptor.newModule("foo")
960 .exports("p1")
961 .opens("p2")
962 .packages(Set.of("p3"))
963 .provides("q.S", List.of("p4.T"))
964 .mainClass("p5.Main")
965 .build()
966 .packages();
967 assertTrue(Objects.equals(packages, Set.of("p1", "p2", "p3", "p4", "p5")));
968 }
969
970 @Test(dataProvider = "invalidNames",
971 expectedExceptions = IllegalArgumentException.class )
972 public void testPackagesWithBadName(String pn, String ignore) {
973 Set<String> pkgs = new HashSet<>(); // allows nulls
974 pkgs.add(pn);
975 ModuleDescriptor.newModule("foo").packages(pkgs);
976 }
977
978 // name
979
980 public void testModuleName() {
981 String mn = ModuleDescriptor.newModule("foo").build().name();
982 assertEquals(mn, "foo");
983 }
984
985 @Test(dataProvider = "invalidNames",
986 expectedExceptions = IllegalArgumentException.class )
987 public void testBadModuleName(String mn, String ignore) {
988 ModuleDescriptor.newModule(mn);
989 }
990
991
992 // version
993
994 public void testVersion1() {
995 Version v1 = Version.parse("1.0");
996 Version v2 = ModuleDescriptor.newModule("foo")
997 .version(v1)
998 .build()
999 .version()
1000 .get();
1001 assertEquals(v1, v2);
1002 }
1003
1004 public void testVersion2() {
1005 String vs = "1.0";
1006 Version v1 = ModuleDescriptor.newModule("foo")
1007 .version(vs)
1008 .build()
1009 .version()
1010 .get();
1011 Version v2 = Version.parse(vs);
1012 assertEquals(v1, v2);
1013 }
1014
1015 @Test(expectedExceptions = NullPointerException.class )
1016 public void testNullVersion1() {
1017 ModuleDescriptor.newModule("foo").version((Version) null);
1018 }
1019
1020 @Test(expectedExceptions = IllegalArgumentException.class )
1021 public void testNullVersion2() {
1022 ModuleDescriptor.newModule("foo").version((String) null);
1023 }
1024
1025 @Test(expectedExceptions = IllegalArgumentException.class )
1026 public void testEmptyVersion() {
1027 ModuleDescriptor.newModule("foo").version("");
1028 }
1029
1030
1031 @DataProvider(name = "unparseableVersions")
1032 public Object[][] unparseableVersions() {
1033 return new Object[][]{
1034
1035 { null, "A1" }, // no version < unparseable
1036 { "A1", "A2" }, // unparseable < unparseable
1037 { "A1", "1.0" }, // unparseable < parseable
1038
1039 };
1040 }
1041
1042 /**
1043 * Basic test for unparseable module versions
1044 */
1045 @Test(dataProvider = "unparseableVersions")
1046 public void testUnparseableModuleVersion(String vs1, String vs2) {
1047 ModuleDescriptor descriptor1 = newModule("m", vs1);
1048 ModuleDescriptor descriptor2 = newModule("m", vs2);
1049
1050 if (vs1 != null && !isParsableVersion(vs1)) {
1051 assertFalse(descriptor1.version().isPresent());
1052 assertTrue(descriptor1.rawVersion().isPresent());
1053 assertEquals(descriptor1.rawVersion().get(), vs1);
1054 }
1055
1056 if (vs2 != null && !isParsableVersion(vs2)) {
1057 assertFalse(descriptor2.version().isPresent());
1058 assertTrue(descriptor2.rawVersion().isPresent());
1059 assertEquals(descriptor2.rawVersion().get(), vs2);
1060 }
1061
1062 assertFalse(descriptor1.equals(descriptor2));
1063 assertFalse(descriptor2.equals(descriptor1));
1064 assertTrue(descriptor1.compareTo(descriptor2) == -1);
1065 assertTrue(descriptor2.compareTo(descriptor1) == 1);
1066 }
1067
1068 /**
1069 * Basic test for requiring a module with an unparseable version recorded
1070 * at compile version.
1071 */
1072 @Test(dataProvider = "unparseableVersions")
1073 public void testUnparseableCompiledVersion(String vs1, String vs2) {
1074 Requires r1 = newRequires("m", vs1);
1075 Requires r2 = newRequires("m", vs2);
1076
1077 if (vs1 != null && !isParsableVersion(vs1)) {
1078 assertFalse(r1.compiledVersion().isPresent());
1079 assertTrue(r1.rawCompiledVersion().isPresent());
1080 assertEquals(r1.rawCompiledVersion().get(), vs1);
1081 }
1082
1083 if (vs2 != null && !isParsableVersion(vs2)) {
1084 assertFalse(r2.compiledVersion().isPresent());
1085 assertTrue(r2.rawCompiledVersion().isPresent());
1086 assertEquals(r2.rawCompiledVersion().get(), vs2);
1087 }
1088
1089 assertFalse(r1.equals(r2));
1090 assertFalse(r2.equals(r1));
1091 assertTrue(r1.compareTo(r2) == -1);
1092 assertTrue(r2.compareTo(r1) == 1);
1093 }
1094
1095 private ModuleDescriptor newModule(String name, String vs) {
1096 Builder builder = JLMA.newModuleBuilder(name, false, Set.of());
1097 if (vs != null)
1098 builder.version(vs);
1099 builder.requires("java.base");
1100 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(builder.build());
1101 return ModuleDescriptor.read(bb);
1102 }
1103
1104 private Requires newRequires(String name, String vs) {
1105 Builder builder = JLMA.newModuleBuilder("foo", false, Set.of());
1106 if (vs == null) {
1107 builder.requires(name);
1108 } else {
1109 JLMA.requires(builder, Set.of(), name, vs);
1110 }
1111 Set<ModuleDescriptor.Requires> requires = builder.build().requires();
1112 Iterator<ModuleDescriptor.Requires> iterator = requires.iterator();
1113 ModuleDescriptor.Requires r = iterator.next();
1114 if (r.name().equals("java.base")) {
1115 r = iterator.next();
1116 }
1117 return r;
1118 }
1119
1120 private boolean isParsableVersion(String vs) {
1121 try {
1122 Version.parse(vs);
1123 return true;
1124 } catch (IllegalArgumentException e) {
1125 return false;
1126 }
1127 }
1128
1129
1130 // toNameAndVersion
1131
1132 public void testToNameAndVersion() {
1133 ModuleDescriptor md1 = ModuleDescriptor.newModule("foo").build();
1134 assertEquals(md1.toNameAndVersion(), "foo");
1135
1136 ModuleDescriptor md2 = ModuleDescriptor.newModule("foo").version("1.0").build();
1137 assertEquals(md2.toNameAndVersion(), "foo@1.0");
1138 }
1139
1140
1141 // open modules
1142
1143 public void testOpenModule() {
1144 ModuleDescriptor descriptor = ModuleDescriptor.newOpenModule("foo")
1145 .requires("bar")
1146 .exports("p")
1147 .provides("p.Service", List.of("q.ServiceImpl"))
1148 .build();
1149
1150 // modifiers
1151 assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.OPEN));
1152 assertTrue(descriptor.isOpen());
1153
1154 // requires
1155 assertTrue(descriptor.requires().size() == 2);
1156 Set<String> names = descriptor.requires()
1157 .stream()
1158 .map(Requires::name)
1159 .collect(Collectors.toSet());
1160 assertEquals(names, Set.of("bar", "java.base"));
1161
1162 // packages
1163 assertEquals(descriptor.packages(), Set.of("p", "q"));
1164
1165 // exports
1166 assertTrue(descriptor.exports().size() == 1);
1167 names = descriptor.exports()
1168 .stream()
1169 .map(Exports::source)
1170 .collect(Collectors.toSet());
1171 assertEquals(names, Set.of("p"));
1172
1173 // opens
1174 assertTrue(descriptor.opens().isEmpty());
1175 }
1176
1177 @Test(expectedExceptions = IllegalStateException.class)
1178 public void testOpensOnOpenModule1() {
1179 ModuleDescriptor.newOpenModule("foo").opens("p");
1180 }
1181
1182 @Test(expectedExceptions = IllegalStateException.class)
1183 public void testOpensOnOpenModule2() {
1184 ModuleDescriptor.newOpenModule("foo").opens("p", Set.of("bar"));
1185 }
1186
1187 public void testIsOpen() {
1188 assertFalse(ModuleDescriptor.newModule("m").build().isOpen());
1189 assertFalse(ModuleDescriptor.newAutomaticModule("m").build().isOpen());
1190 assertTrue(ModuleDescriptor.newOpenModule("m").build().isOpen());
1191 }
1192
1193
1194 // automatic modules
1195
1196 public void testAutomaticModule() {
1197 ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo")
1198 .packages(Set.of("p"))
1199 .provides("p.Service", List.of("q.ServiceImpl"))
1200 .build();
1201
1202 // modifiers
1203 assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC));
1204 assertTrue(descriptor.isAutomatic());
1205
1206 // requires
1207 assertTrue(descriptor.requires().size() == 1);
1208 Set<String> names = descriptor.requires()
1209 .stream()
1210 .map(Requires::name)
1211 .collect(Collectors.toSet());
1212 assertEquals(names, Set.of("java.base"));
1213
1214 // packages
1215 assertEquals(descriptor.packages(), Set.of("p", "q"));
1216 assertTrue(descriptor.exports().isEmpty());
1217 assertTrue(descriptor.opens().isEmpty());
1218 }
1219
1220 @Test(expectedExceptions = IllegalStateException.class)
1221 public void testRequiresOnAutomaticModule() {
1222 ModuleDescriptor.newAutomaticModule("foo").requires("java.base");
1223 }
1224
1225 @Test(expectedExceptions = IllegalStateException.class)
1226 public void testExportsOnAutomaticModule1() {
1227 ModuleDescriptor.newAutomaticModule("foo").exports("p");
1228 }
1229
1230 @Test(expectedExceptions = IllegalStateException.class)
1231 public void testExportsOnAutomaticModule2() {
1232 ModuleDescriptor.newAutomaticModule("foo").exports("p", Set.of("bar"));
1233 }
1234
1235 @Test(expectedExceptions = IllegalStateException.class)
1236 public void testOpensOnAutomaticModule1() {
1237 ModuleDescriptor.newAutomaticModule("foo").opens("p");
1238 }
1239
1240 @Test(expectedExceptions = IllegalStateException.class)
1241 public void testOpensOnAutomaticModule2() {
1242 ModuleDescriptor.newAutomaticModule("foo").opens("p", Set.of("bar"));
1243 }
1244
1245 @Test(expectedExceptions = IllegalStateException.class)
1246 public void testUsesOnAutomaticModule() {
1247 ModuleDescriptor.newAutomaticModule("foo").uses("p.Service");
1248 }
1249
1250 public void testIsAutomatic() {
1251 ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("foo").build();
1252 assertFalse(descriptor1.isAutomatic());
1253
1254 ModuleDescriptor descriptor2 = ModuleDescriptor.newOpenModule("foo").build();
1255 assertFalse(descriptor2.isAutomatic());
1256
1257 ModuleDescriptor descriptor3 = ModuleDescriptor.newAutomaticModule("foo").build();
1258 assertTrue(descriptor3.isAutomatic());
1259 }
1260
1261
1262 // newModule with modifiers
1263
1264 public void testNewModuleToBuildAutomaticModule() {
1265 Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC);
1266 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
1267 assertTrue(descriptor.modifiers().equals(ms));
1268 assertTrue(descriptor.isAutomatic());
1269 }
1270
1271 public void testNewModuleToBuildOpenModule() {
1272 Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.OPEN);
1273 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
1274 assertTrue(descriptor.modifiers().equals(ms));
1275 assertTrue(descriptor.isOpen());
1276
1277 ms = Set.of(ModuleDescriptor.Modifier.OPEN, ModuleDescriptor.Modifier.SYNTHETIC);
1278 descriptor = ModuleDescriptor.newModule("foo", ms).build();
1279 assertTrue(descriptor.modifiers().equals(ms));
1280 assertTrue(descriptor.isOpen());
1281 }
1282
1283 @Test(expectedExceptions = IllegalArgumentException.class)
1284 public void testNewModuleToBuildAutomaticAndOpenModule() {
1285 Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC,
1286 ModuleDescriptor.Modifier.OPEN);
1287 ModuleDescriptor.newModule("foo", ms);
1288 }
1289
1290
1291 // mainClass
1292
1293 public void testMainClass() {
1294 String mainClass
1295 = ModuleDescriptor.newModule("foo").mainClass("p.Main").build().mainClass().get();
1296 assertEquals(mainClass, "p.Main");
1297 }
1298
1299 @Test(expectedExceptions = IllegalArgumentException.class)
1300 public void testMainClassWithSimpleIdentifier() {
1301 ModuleDescriptor.newModule("foo").mainClass("Main");
1302 }
1303
1304 @Test(dataProvider = "invalidNames",
1305 expectedExceptions = IllegalArgumentException.class )
1306 public void testMainClassWithBadName(String mainClass, String ignore) {
1307 Builder builder = ModuleDescriptor.newModule("foo");
1308 builder.mainClass(mainClass);
1309 }
1310
1311
1312 // reads
1313
1314 private static InputStream EMPTY_INPUT_STREAM = new InputStream() {
1315 @Override
1316 public int read() {
1317 return -1;
1318 }
1319 };
1320
1321 private static InputStream FAILING_INPUT_STREAM = new InputStream() {
1322 @Override
1323 public int read() throws IOException {
1324 throw new IOException();
1325 }
1326 };
1327
1328 /**
1329 * Basic test reading module-info.class
1330 */
1331 public void testRead() throws Exception {
1332 Module base = Object.class.getModule();
1333
1334 try (InputStream in = base.getResourceAsStream("module-info.class")) {
1335 ModuleDescriptor descriptor = ModuleDescriptor.read(in);
1336 assertTrue(in.read() == -1); // all bytes read
1337 assertEquals(descriptor.name(), "java.base");
1338 }
1339
1340 try (InputStream in = base.getResourceAsStream("module-info.class")) {
1341 ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1342 ModuleDescriptor descriptor = ModuleDescriptor.read(bb);
1343 assertFalse(bb.hasRemaining()); // no more remaining bytes
1344 assertEquals(descriptor.name(), "java.base");
1345 }
1346 }
1347
1348 /**
1349 * Test ModuleDescriptor with a packager finder
1350 */
1351 public void testReadsWithPackageFinder() throws Exception {
1352 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
1353 .requires("java.base")
1354 .build();
1355
1356 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1357 ModuleInfoWriter.write(descriptor, baos);
1358 ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1359
1360 descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1361
1362 assertTrue(descriptor.packages().size() == 2);
1363 assertTrue(descriptor.packages().contains("p"));
1364 assertTrue(descriptor.packages().contains("q"));
1365 }
1366
1367 /**
1368 * Test ModuleDescriptor with a packager finder that doesn't return the
1369 * complete set of packages.
1370 */
1371 public void testReadsWithBadPackageFinder() throws Exception {
1372 ByteBuffer bb = ByteBuffer.wrap(ClassFile.of().buildModule(
1373 ModuleAttribute.of(
1374 ModuleDesc.of("foo"),
1375 mb -> mb.requires(ModuleDesc.of("java.base"), 0, null)
1376 .exports(PackageDesc.of("p"), 0))));
1377
1378 // package finder returns a set that doesn't include p
1379 assertThrows(InvalidModuleDescriptorException.class,
1380 () -> ModuleDescriptor.read(bb, () -> Set.of("q")));
1381 }
1382
1383 @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1384 public void testReadFromEmptyInputStream() throws Exception {
1385 ModuleDescriptor.read(EMPTY_INPUT_STREAM);
1386 }
1387
1388 @Test(expectedExceptions = IOException.class)
1389 public void testReadFromFailingInputStream() throws Exception {
1390 ModuleDescriptor.read(FAILING_INPUT_STREAM);
1391 }
1392
1393 @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1394 public void testReadFromEmptyBuffer() {
1395 ByteBuffer bb = ByteBuffer.allocate(0);
1396 ModuleDescriptor.read(bb);
1397 }
1398
1399 /**
1400 * Test ModuleDescriptor.read reading a module-info for java.base that has a non-0
1401 * length requires table.
1402 */
1403 public void testReadOfJavaBaseWithRequires() {
1404 ModuleDescriptor descriptor = ModuleDescriptor.newModule("java.base")
1405 .requires("other")
1406 .build();
1407 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1408 assertThrows(InvalidModuleDescriptorException.class,
1409 () -> ModuleDescriptor.read(bb));
1410 }
1411
1412 /**
1413 * Test ModuleDescriptor.read reading a module-info with a zero length requires table
1414 * (no entry for java.base).
1415 */
1416 public void testReadWithEmptyRequires() {
1417 // use non-strict builder to create module that does not require java.base
1418 ModuleDescriptor descriptor = JLMA.newModuleBuilder("m", false, Set.of()).build();
1419 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1420 assertThrows(InvalidModuleDescriptorException.class,
1421 () -> ModuleDescriptor.read(bb));
1422 }
1423
1424 /**
1425 * Test ModuleDescriptor.read reading a module-info with a non-zero length requires
1426 * table that does not have entry for java.base.
1427 */
1428 public void testReadWithNoRequiresBase() {
1429 // use non-strict builder to create module that does not require java.base
1430 ModuleDescriptor descriptor = JLMA.newModuleBuilder("m1", false, Set.of())
1431 .requires("m2")
1432 .build();
1433 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1434 assertThrows(InvalidModuleDescriptorException.class,
1435 () -> ModuleDescriptor.read(bb));
1436 }
1437
1438 /**
1439 * Test ModuleDescriptor.read reading a module-info with a requires entry for
1440 * java.base with the ACC_SYNTHETIC flag set.
1441 */
1442 public void testReadWithSynethticRequiresBase() {
1443 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m")
1444 .requires(Set.of(SYNTHETIC), "java.base")
1445 .build();
1446 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1447 assertThrows(InvalidModuleDescriptorException.class,
1448 () -> ModuleDescriptor.read(bb));
1449 }
1450
1451 /**
1452 * Test ModuleDescriptor.read with a null parameter.
1453 */
1454 public void testReadWithNull() throws Exception {
1455 Module base = Object.class.getModule();
1456
1457 assertThrows(NullPointerException.class,
1458 () -> ModuleDescriptor.read((InputStream) null));
1459 assertThrows(NullPointerException.class,
1460 () -> ModuleDescriptor.read((ByteBuffer) null));
1461
1462 try (InputStream in = base.getResourceAsStream("module-info.class")) {
1463 assertThrows(NullPointerException.class,
1464 () -> ModuleDescriptor.read(in, null));
1465
1466 ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1467 assertThrows(NullPointerException.class,
1468 () -> ModuleDescriptor.read(bb, null));
1469 }
1470 }
1471
1472
1473 // equals/hashCode/compareTo/toString
1474
1475 public void testEqualsAndHashCode() {
1476 ModuleDescriptor md1 = ModuleDescriptor.newModule("m").build();
1477 ModuleDescriptor md2 = ModuleDescriptor.newModule("m").build();
1478 assertEquals(md1, md1);
1479 assertEquals(md1.hashCode(), md2.hashCode());
1480 assertTrue(md1.compareTo(md2) == 0);
1481 assertTrue(md2.compareTo(md1) == 0);
1482 }
1483
1484 @DataProvider(name = "sortedModuleDescriptors")
1485 public Object[][] sortedModuleDescriptors() {
1486 return new Object[][]{
1487
1488 { ModuleDescriptor.newModule("m2").build(),
1489 ModuleDescriptor.newModule("m1").build()
1490 },
1491
1492 { ModuleDescriptor.newModule("m").version("2").build(),
1493 ModuleDescriptor.newModule("m").version("1").build()
1494 },
1495
1496 { ModuleDescriptor.newModule("m").version("1").build(),
1497 ModuleDescriptor.newModule("m").build()
1498 },
1499
1500 { ModuleDescriptor.newOpenModule("m").build(),
1501 ModuleDescriptor.newModule("m").build()
1502 },
1503
1504 };
1505 }
1506
1507 @Test(dataProvider = "sortedModuleDescriptors")
1508 public void testCompare(ModuleDescriptor md1, ModuleDescriptor md2) {
1509 assertNotEquals(md1, md2);
1510 assertTrue(md1.compareTo(md2) == 1);
1511 assertTrue(md2.compareTo(md1) == -1);
1512 }
1513
1514 public void testToString() {
1515 String s = ModuleDescriptor.newModule("m1")
1516 .requires("m2")
1517 .exports("p1")
1518 .build()
1519 .toString();
1520 assertTrue(s.contains("m1"));
1521 assertTrue(s.contains("m2"));
1522 assertTrue(s.contains("p1"));
1523 }
1524
1525 public void testRequiresTransitiveJavaBaseNotPermitted1() throws Exception {
1526 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
1527 .requires(Set.of(Modifier.TRANSITIVE), "java.base")
1528 .build();
1529
1530 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1531 ModuleInfoWriter.write(descriptor, baos);
1532 ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1533
1534 ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1535 }
1536
1537 public void testRequiresTransitiveJavaBaseNotPermitted2() throws Exception {
1538 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
1539 .requires(Set.of(Modifier.TRANSITIVE), "java.base")
1540 .build();
1541
1542 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1543 ModuleInfoWriter.write(descriptor, baos);
1544 byte[] bytecode = baos.toByteArray();
1545 ByteBuffer bb = ByteBuffer.wrap(bytecode);
1546 setClassFileVersion(bb, ClassFile.JAVA_21_VERSION, -1);
1547
1548 ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1549 }
1550
1551 public void testRequiresTransitiveJavaBasePermitted() throws Exception {
1552 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
1553 .requires(Set.of(Modifier.TRANSITIVE), "java.base")
1554 .build();
1555
1556 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1557 ModuleInfoWriter.write(descriptor, baos);
1558 byte[] bytecode = baos.toByteArray();
1559 ByteBuffer bb = ByteBuffer.wrap(bytecode);
1560 setClassFileVersion(bb, -1, ClassFile.PREVIEW_MINOR_VERSION);
1561
1562 descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1563
1564 assertEquals(descriptor.requires().size(), 1);
1565 Requires javaBase = descriptor.requires().iterator().next();
1566 assertEquals(javaBase.name(), "java.base");
1567 assertEquals(javaBase.modifiers(), Set.of(Modifier.TRANSITIVE));
1568 }
1569
1570 /**Change the classfile versions of the provided classfile to the provided
1571 * values.
1572 *
1573 * @param bytecode the classfile content to modify
1574 * @param major the major classfile version to set,
1575 * -1 if the existing version should be kept
1576 * @param minor the minor classfile version to set,
1577 * -1 if the existing version should be kept
1578 */
1579 private void setClassFileVersion(ByteBuffer bb, int major, int minor) {
1580 if (minor != (-1)) {
1581 bb.putShort(4, (short) minor);
1582 }
1583 if (major != (-1)) {
1584 bb.putShort(6, (short) major);
1585 }
1586 }
1587 }