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