23
24 /*
25 * @test
26 * @bug 8173777
27 * @summary tests for multi-module mode compilation
28 * @library /tools/lib
29 * @modules
30 * jdk.compiler/com.sun.tools.javac.api
31 * jdk.compiler/com.sun.tools.javac.code
32 * jdk.compiler/com.sun.tools.javac.main
33 * jdk.compiler/com.sun.tools.javac.processing
34 * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
35 * @run main XModuleTest
36 */
37
38 import java.nio.file.Files;
39 import java.nio.file.Path;
40 import java.util.Arrays;
41 import java.util.List;
42 import java.util.Set;
43
44 import javax.annotation.processing.AbstractProcessor;
45 import javax.annotation.processing.RoundEnvironment;
46 import javax.annotation.processing.SupportedAnnotationTypes;
47 import javax.lang.model.SourceVersion;
48 import javax.lang.model.element.ModuleElement;
49 import javax.lang.model.element.TypeElement;
50 import javax.lang.model.util.Elements;
51
52 import com.sun.tools.javac.code.Symtab;
53 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
54 import toolbox.JavacTask;
55 import toolbox.ModuleBuilder;
56 import toolbox.Task;
57 import toolbox.Task.Expect;
58
59 public class XModuleTest extends ModuleTestBase {
60
61 public static void main(String... args) throws Exception {
62 new XModuleTest().runTests();
150 checkFileExists(classes, "m3x/m3/Test.class");
151 checkFileExists(classes, "m4x/m4/Test.class");
152 }
153
154 @Test
155 public void testPatchModuleModuleSourcePathConflict(Path base) throws Exception {
156 //note: avoiding use of java.base, as that gets special handling on some places:
157 Path src = base.resolve("src");
158 Path m1 = src.resolve("m1x");
159 tb.writeJavaFiles(m1,
160 "module m1x { }",
161 "package m1; public class Test { }");
162 Path m2 = src.resolve("m2x");
163 tb.writeJavaFiles(m2,
164 "module m2x { }",
165 "package m2; public class Test { }");
166 Path classes = base.resolve("classes");
167 tb.createDirectories(classes);
168
169 List<String> log = new JavacTask(tb)
170 .options("--patch-module", "m1x=" + m1.toString(),
171 "--patch-module", "m2x=" + m2.toString(),
172 "--module-source-path", src.toString(),
173 "-XDrawDiagnostics")
174 .outdir(classes)
175 .files(findJavaFiles(src.resolve("m1x").resolve("m1"),
176 src.resolve("m2x").resolve("m2")))
177 .run(Expect.FAIL)
178 .writeAll()
179 .getOutputLines(Task.OutputKind.DIRECT);
180
181 List<String> expectedOut = Arrays.asList(
182 "Test.java:1:1: compiler.err.file.patched.and.msp",
183 "Test.java:1:1: compiler.err.file.patched.and.msp",
184 "module-info.java:1:1: compiler.err.file.patched.and.msp",
185 "- compiler.err.cant.access: m2x.module-info, (compiler.misc.cant.resolve.modules)",
186 "4 errors"
187 );
188
189 if (!expectedOut.equals(log))
190 throw new Exception("expected output not found: " + log);
191 }
192
193 @Test
194 public void testSourcePath(Path base) throws Exception {
195 //note: avoiding use of java.base, as that gets special handling on some places:
196 Path src = base.resolve("src");
197 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }");
198 Path srcPath = base.resolve("src-path");
199 tb.writeJavaFiles(srcPath, "package javax.lang.model.element; interface Other { }");
200 Path classes = base.resolve("classes");
201 tb.createDirectories(classes);
202
203 List<String> log = new JavacTask(tb)
204 .options("--patch-module", "java.compiler=" + src.toString(),
205 "-sourcepath", srcPath.toString(),
206 "-XDrawDiagnostics")
249 .outdir(classes)
250 .files(src.resolve("javax/lang/model/element/Extra.java"))
251 .run(Expect.FAIL)
252 .writeAll()
253 .getOutputLines(Task.OutputKind.DIRECT);
254
255 List<String> expectedOut = Arrays.asList(
256 "Extra.java:1:76: compiler.err.doesnt.exist: p",
257 "1 error"
258 );
259
260 if (!expectedOut.equals(log))
261 throw new Exception("expected output not found: " + log);
262 }
263
264 @Test
265 public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
266 //note: avoiding use of java.base, as that gets special handling on some places:
267 Path src = base.resolve("src");
268 tb.writeJavaFiles(src,
269 "package javax.lang.model.element; public interface Extra { }");
270 Path srcPath = base.resolve("src-path");
271 tb.writeJavaFiles(src,
272 "module java.compiler {}");
273 Path classes = base.resolve("classes");
274 tb.createDirectories(classes);
275
276 List<String> log = new JavacTask(tb)
277 .options("-XDrawDiagnostics",
278 "--patch-module", "java.compiler=" + src.toString())
279 .outdir(classes)
280 .files(findJavaFiles(src))
281 .run(Task.Expect.FAIL)
282 .writeAll()
283 .getOutputLines(Task.OutputKind.DIRECT);
284
285 List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.sourcepath",
286 "1 error");
287
288 if (!expected.equals(log))
289 throw new Exception("expected output not found: " + log);
290 }
291
292 @Test
293 public void testNoModuleInfoInClassOutput(Path base) throws Exception {
294 //note: avoiding use of java.base, as that gets special handling on some places:
295 Path srcMod = base.resolve("src-mod");
296 tb.writeJavaFiles(srcMod,
297 "module mod {}");
298 Path classes = base.resolve("classes");
299 tb.createDirectories(classes);
300
301 String logMod = new JavacTask(tb)
302 .options()
303 .outdir(classes)
304 .files(findJavaFiles(srcMod))
305 .run()
306 .writeAll()
307 .getOutput(Task.OutputKind.DIRECT);
308
309 if (!logMod.isEmpty())
310 throw new Exception("unexpected output found: " + logMod);
311
312 Path src = base.resolve("src");
313 tb.writeJavaFiles(src,
314 "package javax.lang.model.element; public interface Extra { }");
315 tb.createDirectories(classes);
316
317 List<String> log = new JavacTask(tb)
318 .options("-XDrawDiagnostics",
319 "--patch-module", "java.compiler=" + src.toString())
320 .outdir(classes)
321 .files(findJavaFiles(src))
322 .run(Task.Expect.FAIL)
323 .writeAll()
324 .getOutputLines(Task.OutputKind.DIRECT);
325
326 List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.classpath",
327 "1 error");
328
329 if (!expected.equals(log))
330 throw new Exception("expected output not found: " + log);
331 }
332
333 @Test
334 public void testWithModulePath(Path base) throws Exception {
335 Path modSrc = base.resolve("modSrc");
336 Path modules = base.resolve("modules");
337 new ModuleBuilder(tb, "m1")
338 .classes("package pkg1; public interface E { }")
339 .build(modSrc, modules);
340
341 Path src = base.resolve("src");
342 tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }");
343
344 new JavacTask(tb, Task.Mode.CMDLINE)
345 .options("--module-path", modules.toString(),
346 "--patch-module", "m1=" + src.toString())
479 }
480
481 @Override
482 public SourceVersion getSupportedSourceVersion() {
483 return SourceVersion.latest();
484 }
485
486 private static void assertNonNull(String msg, Object val) {
487 if (val == null) {
488 throw new AssertionError(msg);
489 }
490 }
491
492 private static void assertNull(String msg, Object val) {
493 if (val != null) {
494 throw new AssertionError(msg);
495 }
496 }
497 }
498
499 private void checkFileExists(Path dir, String path) {
500 Path toCheck = dir.resolve(path.replace("/", dir.getFileSystem().getSeparator()));
501
502 if (!Files.exists(toCheck)) {
503 throw new AssertionError(toCheck.toString() + " does not exist!");
504 }
505 }
506 }
|
23
24 /*
25 * @test
26 * @bug 8173777
27 * @summary tests for multi-module mode compilation
28 * @library /tools/lib
29 * @modules
30 * jdk.compiler/com.sun.tools.javac.api
31 * jdk.compiler/com.sun.tools.javac.code
32 * jdk.compiler/com.sun.tools.javac.main
33 * jdk.compiler/com.sun.tools.javac.processing
34 * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
35 * @run main XModuleTest
36 */
37
38 import java.nio.file.Files;
39 import java.nio.file.Path;
40 import java.util.Arrays;
41 import java.util.List;
42 import java.util.Set;
43 import java.util.stream.Collectors;
44
45 import javax.annotation.processing.AbstractProcessor;
46 import javax.annotation.processing.RoundEnvironment;
47 import javax.annotation.processing.SupportedAnnotationTypes;
48 import javax.lang.model.SourceVersion;
49 import javax.lang.model.element.ModuleElement;
50 import javax.lang.model.element.TypeElement;
51 import javax.lang.model.util.Elements;
52
53 import com.sun.tools.javac.code.Symtab;
54 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
55 import toolbox.JavacTask;
56 import toolbox.ModuleBuilder;
57 import toolbox.Task;
58 import toolbox.Task.Expect;
59
60 public class XModuleTest extends ModuleTestBase {
61
62 public static void main(String... args) throws Exception {
63 new XModuleTest().runTests();
151 checkFileExists(classes, "m3x/m3/Test.class");
152 checkFileExists(classes, "m4x/m4/Test.class");
153 }
154
155 @Test
156 public void testPatchModuleModuleSourcePathConflict(Path base) throws Exception {
157 //note: avoiding use of java.base, as that gets special handling on some places:
158 Path src = base.resolve("src");
159 Path m1 = src.resolve("m1x");
160 tb.writeJavaFiles(m1,
161 "module m1x { }",
162 "package m1; public class Test { }");
163 Path m2 = src.resolve("m2x");
164 tb.writeJavaFiles(m2,
165 "module m2x { }",
166 "package m2; public class Test { }");
167 Path classes = base.resolve("classes");
168 tb.createDirectories(classes);
169
170 List<String> log = new JavacTask(tb)
171 .options("--patch-module", "m1x=" + m2.toString(),
172 "--module-source-path", src.toString(),
173 "-XDrawDiagnostics")
174 .outdir(classes)
175 .files(findJavaFiles(src.resolve("m1x").resolve("m1"),
176 src.resolve("m2x").resolve("m2")))
177 .run(Expect.FAIL)
178 .writeAll()
179 .getOutputLines(Task.OutputKind.DIRECT);
180
181 List<String> expectedOut = Arrays.asList(
182 "Test.java:1:1: compiler.err.file.patched.and.msp: m1x, m2x",
183 "1 error"
184 );
185
186 if (!expectedOut.equals(log))
187 throw new Exception("expected output not found: " + log);
188 }
189
190 @Test
191 public void testSourcePath(Path base) throws Exception {
192 //note: avoiding use of java.base, as that gets special handling on some places:
193 Path src = base.resolve("src");
194 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }");
195 Path srcPath = base.resolve("src-path");
196 tb.writeJavaFiles(srcPath, "package javax.lang.model.element; interface Other { }");
197 Path classes = base.resolve("classes");
198 tb.createDirectories(classes);
199
200 List<String> log = new JavacTask(tb)
201 .options("--patch-module", "java.compiler=" + src.toString(),
202 "-sourcepath", srcPath.toString(),
203 "-XDrawDiagnostics")
246 .outdir(classes)
247 .files(src.resolve("javax/lang/model/element/Extra.java"))
248 .run(Expect.FAIL)
249 .writeAll()
250 .getOutputLines(Task.OutputKind.DIRECT);
251
252 List<String> expectedOut = Arrays.asList(
253 "Extra.java:1:76: compiler.err.doesnt.exist: p",
254 "1 error"
255 );
256
257 if (!expectedOut.equals(log))
258 throw new Exception("expected output not found: " + log);
259 }
260
261 @Test
262 public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
263 //note: avoiding use of java.base, as that gets special handling on some places:
264 Path src = base.resolve("src");
265 tb.writeJavaFiles(src,
266 "module java.compiler {}",
267 "package javax.lang.model.element; public interface Extra { }");
268 Path classes = base.resolve("classes");
269 tb.createDirectories(classes);
270
271 List<String> log;
272 List<String> expected;
273
274 log = new JavacTask(tb)
275 .options("-XDrawDiagnostics",
276 "--patch-module", "java.compiler=" + src.toString())
277 .outdir(classes)
278 .files(findJavaFiles(src))
279 .run(Task.Expect.FAIL)
280 .writeAll()
281 .getOutputLines(Task.OutputKind.DIRECT);
282
283 expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.sourcepath",
284 "1 error");
285
286 if (!expected.equals(log))
287 throw new Exception("expected output not found: " + log);
288
289 //multi-module mode:
290 log = new JavacTask(tb)
291 .options("-XDrawDiagnostics",
292 "--patch-module", "java.compiler=" + src.toString(),
293 "--module-source-path", "dummy")
294 .outdir(classes)
295 .files(findJavaFiles(src))
296 .run(Task.Expect.FAIL)
297 .writeAll()
298 .getOutputLines(Task.OutputKind.DIRECT);
299
300 expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.java",
301 "1 error");
302
303 if (!expected.equals(log))
304 throw new Exception("expected output not found: " + log);
305 }
306
307 @Test
308 public void testNoModuleInfoInClassOutput(Path base) throws Exception {
309 //note: avoiding use of java.base, as that gets special handling on some places:
310 Path srcMod = base.resolve("src-mod");
311 tb.writeJavaFiles(srcMod,
312 "module mod {}");
313 Path classes = base.resolve("classes").resolve("java.compiler");
314 tb.createDirectories(classes);
315
316 String logMod = new JavacTask(tb)
317 .options()
318 .outdir(classes)
319 .files(findJavaFiles(srcMod))
320 .run()
321 .writeAll()
322 .getOutput(Task.OutputKind.DIRECT);
323
324 if (!logMod.isEmpty())
325 throw new Exception("unexpected output found: " + logMod);
326
327 Path src = base.resolve("src");
328 tb.writeJavaFiles(src,
329 "package javax.lang.model.element; public interface Extra { }");
330 tb.createDirectories(classes);
331
332 List<String> log;
333 List<String> expected;
334
335 log = new JavacTask(tb)
336 .options("-XDrawDiagnostics",
337 "--patch-module", "java.compiler=" + src.toString())
338 .outdir(classes)
339 .files(findJavaFiles(src))
340 .run(Task.Expect.FAIL)
341 .writeAll()
342 .getOutputLines(Task.OutputKind.DIRECT);
343
344 expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.classoutput",
345 "1 error");
346
347 if (!expected.equals(log))
348 throw new Exception("expected output not found: " + log);
349
350 log = new JavacTask(tb)
351 .options("-XDrawDiagnostics",
352 "--patch-module", "java.compiler=" + src.toString(),
353 "--module-source-path", "dummy")
354 .outdir(classes.getParent())
355 .files(findJavaFiles(src))
356 .run(Task.Expect.FAIL)
357 .writeAll()
358 .getOutputLines(Task.OutputKind.DIRECT);
359
360 expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.class",
361 "1 error");
362
363 if (!expected.equals(log))
364 throw new Exception("expected output not found: " + log);
365 }
366
367 @Test
368 public void testWithModulePath(Path base) throws Exception {
369 Path modSrc = base.resolve("modSrc");
370 Path modules = base.resolve("modules");
371 new ModuleBuilder(tb, "m1")
372 .classes("package pkg1; public interface E { }")
373 .build(modSrc, modules);
374
375 Path src = base.resolve("src");
376 tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }");
377
378 new JavacTask(tb, Task.Mode.CMDLINE)
379 .options("--module-path", modules.toString(),
380 "--patch-module", "m1=" + src.toString())
513 }
514
515 @Override
516 public SourceVersion getSupportedSourceVersion() {
517 return SourceVersion.latest();
518 }
519
520 private static void assertNonNull(String msg, Object val) {
521 if (val == null) {
522 throw new AssertionError(msg);
523 }
524 }
525
526 private static void assertNull(String msg, Object val) {
527 if (val != null) {
528 throw new AssertionError(msg);
529 }
530 }
531 }
532
533 @Test
534 public void testSingleModeIncremental(Path base) throws Exception {
535 //note: avoiding use of java.base, as that gets special handling on some places:
536 Path src = base.resolve("src");
537 tb.writeJavaFiles(src,
538 "package javax.lang.model.element; public interface Extra extends Element { }",
539 "package javax.lang.model.element; public interface Extra2 extends Extra { }");
540 Path classes = base.resolve("classes");
541 tb.createDirectories(classes);
542
543 Thread.sleep(2000); //ensure newer timestamps on classfiles:
544
545 new JavacTask(tb)
546 .options("--patch-module", "java.compiler=" + src.toString())
547 .outdir(classes)
548 .files(findJavaFiles(src))
549 .run()
550 .writeAll()
551 .getOutput(Task.OutputKind.DIRECT);
552
553 List<String> log = new JavacTask(tb)
554 .options("--patch-module", "java.compiler=" + src.toString(),
555 "-verbose")
556 .outdir(classes)
557 .files(findJavaFiles(src.resolve("javax/lang/model/element/Extra2.java"
558 .replace("/", src.getFileSystem().getSeparator()))))
559 .run()
560 .writeAll()
561 .getOutputLines(Task.OutputKind.DIRECT)
562 .stream()
563 .filter(l -> l.contains("parsing"))
564 .collect(Collectors.toList());
565
566 boolean parsesExtra2 = log.stream()
567 .anyMatch(l -> l.contains("Extra2.java"));
568 boolean parsesExtra = log.stream()
569 .anyMatch(l -> l.contains("Extra.java"));
570
571 if (!parsesExtra2 || parsesExtra) {
572 throw new AssertionError("Unexpected output: " + log);
573 }
574 }
575
576 @Test
577 public void testComplexMSPAndPatch(Path base) throws Exception {
578 //note: avoiding use of java.base, as that gets special handling on some places:
579 Path src1 = base.resolve("src1");
580 Path src1ma = src1.resolve("ma");
581 tb.writeJavaFiles(src1ma,
582 "module ma { exports ma; }",
583 "package ma; public class C1 { public static void method() { } }",
584 "package ma.impl; public class C2 { }");
585 Path src1mb = src1.resolve("mb");
586 tb.writeJavaFiles(src1mb,
587 "module mb { requires ma; }",
588 "package mb.impl; public class C2 { public static void method() { } }");
589 Path src1mc = src1.resolve("mc");
590 tb.writeJavaFiles(src1mc,
591 "module mc { }");
592 Path classes1 = base.resolve("classes1");
593 tb.createDirectories(classes1);
594 tb.cleanDirectory(classes1);
595
596 new JavacTask(tb)
597 .options("--module-source-path", src1.toString())
598 .files(findJavaFiles(src1))
599 .outdir(classes1)
600 .run()
601 .writeAll();
602
603 //patching:
604 Path src2 = base.resolve("src2");
605 Path src2ma = src2.resolve("ma");
606 tb.writeJavaFiles(src2ma,
607 "package ma.impl; public class C2 { public static void extra() { ma.C1.method(); } }",
608 "package ma.impl; public class C3 { public void test() { C2.extra(); } }");
609 Path src2mb = src2.resolve("mb");
610 tb.writeJavaFiles(src2mb,
611 "package mb.impl; public class C3 { public void test() { C2.method(); ma.C1.method(); ma.impl.C2.extra(); } }");
612 Path src2mc = src2.resolve("mc");
613 tb.writeJavaFiles(src2mc,
614 "package mc.impl; public class C2 { public static void test() { } }",
615 //will require --add-reads ma:
616 "package mc.impl; public class C3 { public static void test() { ma.impl.C2.extra(); } }");
617 Path src2mt = src2.resolve("mt");
618 tb.writeJavaFiles(src2mt,
619 "module mt { requires ma; requires mb; }",
620 "package mt.impl; public class C2 { public static void test() { mb.impl.C2.method(); ma.impl.C2.extra(); } }",
621 "package mt.impl; public class C3 { public static void test() { C2.test(); mc.impl.C2.test(); } }");
622 Path classes2 = base.resolve("classes2");
623 tb.createDirectories(classes2);
624 tb.cleanDirectory(classes2);
625
626 Thread.sleep(2000); //ensure newer timestamps on classfiles:
627
628 new JavacTask(tb)
629 .options("--module-path", classes1.toString(),
630 "--patch-module", "ma=" + src2ma.toString(),
631 "--patch-module", "mb=" + src2mb.toString(),
632 "--add-exports", "ma/ma.impl=mb",
633 "--patch-module", "mc=" + src2mc.toString(),
634 "--add-reads", "mc=ma",
635 "--add-exports", "ma/ma.impl=mc",
636 "--add-exports", "ma/ma.impl=mt",
637 "--add-exports", "mb/mb.impl=mt",
638 "--add-exports", "mc/mc.impl=mt",
639 "--add-reads", "mt=mc",
640 "--module-source-path", src2.toString())
641 .outdir(classes2)
642 .files(findJavaFiles(src2))
643 .run()
644 .writeAll();
645
646 //incremental compilation (C2 mustn't be compiled, C3 must):
647 tb.writeJavaFiles(src2ma,
648 "package ma.impl; public class C3 { public void test() { ma.C1.method(); C2.extra(); } }");
649 tb.writeJavaFiles(src2mt,
650 "package mt.impl; public class C3 { public static void test() { mc.impl.C2.test(); C2.test(); } }");
651
652 List<String> log = new JavacTask(tb)
653 .options("--module-path", classes1.toString(),
654 "--patch-module", "ma=" + src2ma.toString(),
655 "--patch-module", "mb=" + src2mb.toString(),
656 "--add-exports", "ma/ma.impl=mb",
657 "--patch-module", "mc=" + src2mc.toString(),
658 "--add-reads", "mc=ma",
659 "--add-exports", "ma/ma.impl=mc",
660 "--add-exports", "ma/ma.impl=mt",
661 "--add-exports", "mb/mb.impl=mt",
662 "--add-exports", "mc/mc.impl=mt",
663 "--add-reads", "mt=mc",
664 "--module-source-path", src2.toString(),
665 "--add-modules", "mc",
666 "-verbose")
667 .outdir(classes2)
668 .files(src2ma.resolve("ma").resolve("impl").resolve("C3.java"),
669 src2mt.resolve("mt").resolve("impl").resolve("C3.java"))
670 .run()
671 .writeAll()
672 .getOutputLines(Task.OutputKind.DIRECT)
673 .stream()
674 .filter(l -> l.contains("parsing"))
675 .collect(Collectors.toList());
676
677 boolean parsesC3 = log.stream()
678 .anyMatch(l -> l.contains("C3.java"));
679 boolean parsesC2 = log.stream()
680 .anyMatch(l -> l.contains("C2.java"));
681
682 if (!parsesC3 || parsesC2) {
683 throw new AssertionError("Unexpected output: " + log);
684 }
685 }
686
687 private void checkFileExists(Path dir, String path) {
688 Path toCheck = dir.resolve(path.replace("/", dir.getFileSystem().getSeparator()));
689
690 if (!Files.exists(toCheck)) {
691 throw new AssertionError(toCheck.toString() + " does not exist!");
692 }
693 }
694 }
|