Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
26 * @bug 8154283 8167320 8171098 8172809 8173068 8173117 8176045 8177311
27 * @summary tests for multi-module mode compilation
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 * jdk.compiler/com.sun.tools.javac.util
35 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
39 import java.io.BufferedWriter;
40 import java.io.Writer;
41 import java.nio.file.Files;
42 import java.nio.file.Path;
43 import java.nio.file.Paths;
44 import java.util.Arrays;
45 import java.util.HashSet;
46 import java.util.List;
47 import java.util.Objects;
50 import javax.annotation.processing.AbstractProcessor;
51 import javax.annotation.processing.RoundEnvironment;
52 import javax.annotation.processing.SupportedAnnotationTypes;
53 import javax.annotation.processing.SupportedOptions;
54 import javax.lang.model.SourceVersion;
55 import javax.lang.model.element.Element;
56 import javax.lang.model.element.ModuleElement;
57 import javax.lang.model.element.ModuleElement.RequiresDirective;
58 import javax.lang.model.element.PackageElement;
59 import javax.lang.model.element.TypeElement;
60 import javax.lang.model.util.ElementFilter;
61 import javax.lang.model.util.Elements;
62 import javax.tools.JavaCompiler;
63 import javax.tools.JavaFileObject;
64 import javax.tools.StandardJavaFileManager;
65 import javax.tools.ToolProvider;
67 import com.sun.source.tree.CompilationUnitTree;
68 //import com.sun.source.util.JavacTask; // conflicts with toolbox.JavacTask
69 import com.sun.tools.javac.api.JavacTaskImpl;
70 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
71 import com.sun.tools.javac.code.Symtab;
73 import toolbox.JarTask;
74 import toolbox.JavacTask;
76 import toolbox.Task.Expect;
77 import toolbox.Task.OutputKind;
79 public class EdgeCases extends ModuleTestBase {
81 public static void main(String... args) throws Exception {
82 new EdgeCases().runTests();
86 public void testAddExportUndefinedModule(Path base) throws Exception {
87 Path src = base.resolve("src");
88 tb.writeJavaFiles(src, "package test; import undefPackage.Any; public class Test {}");
89 Path classes = base.resolve("classes");
90 tb.createDirectories(classes);
92 List<String> log = new JavacTask(tb)
93 .options("--add-exports", "undefModule/undefPackage=ALL-UNNAMED",
96 .files(findJavaFiles(src))
97 .run(Task.Expect.FAIL)
99 .getOutputLines(Task.OutputKind.DIRECT);
101 List<String> expected = Arrays.asList("- compiler.warn.module.for.option.not.found: --add-exports, undefModule",
102 "Test.java:1:34: compiler.err.doesnt.exist: undefPackage",
103 "1 error", "1 warning");
105 if (!expected.equals(log))
106 throw new Exception("expected output not found: " + log);
110 public void testModuleSymbolOutterMostClass(Path base) throws Exception {
111 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
112 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
113 Path moduleSrc = base.resolve("module-src");
114 Path m1 = moduleSrc.resolve("m1x");
116 tb.writeJavaFiles(m1, "module m1x { }");
118 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(moduleSrc));
119 com.sun.source.util.JavacTask task =
120 (com.sun.source.util.JavacTask) compiler.getTask(null, fm, null, null, null, files);
124 ModuleSymbol msym = (ModuleSymbol) task.getElements().getModuleElement("m1x");
126 msym.outermostClass();
131 public void testParseEnterAnalyze(Path base) throws Exception {
132 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
133 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
134 Path moduleSrc = base.resolve("module-src");
135 Path m1 = moduleSrc.resolve("m1x");
137 tb.writeJavaFiles(m1, "module m1x { }",
139 "package p; class T { }");
141 Path classes = base.resolve("classes");
142 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(moduleSrc));
143 List<String> options = Arrays.asList("-d", classes.toString(), "-Xpkginfo:always");
144 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fm, null, options, null, files);
146 Iterable<? extends CompilationUnitTree> parsed = task.parse();
147 Iterable<? extends Element> entered = task.enter(parsed);
148 Iterable<? extends Element> analyzed = task.analyze(entered);
149 Iterable<? extends JavaFileObject> generatedFiles = task.generate(analyzed);
151 Set<String> generated = new HashSet<>();
153 for (JavaFileObject jfo : generatedFiles) {
154 generated.add(jfo.getName());
157 Set<String> expected = new HashSet<>(
158 Arrays.asList(Paths.get("testParseEnterAnalyze", "classes", "p", "package-info.class").toString(),
159 Paths.get("testParseEnterAnalyze", "classes", "module-info.class").toString(),
160 Paths.get("testParseEnterAnalyze", "classes", "p", "T.class").toString())
163 if (!Objects.equals(expected, generated))
164 throw new AssertionError("Incorrect generated files: " + generated);
169 public void testModuleImplicitModuleBoundaries(Path base) throws Exception {
170 Path src = base.resolve("src");
171 Path src_m1 = src.resolve("m1x");
172 tb.writeJavaFiles(src_m1,
173 "module m1x { exports api1; }",
174 "package api1; public class Api1 { public void call() { } }");
175 Path src_m2 = src.resolve("m2x");
176 tb.writeJavaFiles(src_m2,
177 "module m2x { requires m1x; exports api2; }",
178 "package api2; public class Api2 { public static api1.Api1 get() { return null; } }");
179 Path src_m3 = src.resolve("m3x");
180 tb.writeJavaFiles(src_m3,
181 "module m3x { requires m2x; }",
182 "package test; public class Test { { api2.Api2.get().call(); api2.Api2.get().toString(); } }");
183 Path classes = base.resolve("classes");
184 tb.createDirectories(classes);
186 String log = new JavacTask(tb)
187 .options("-XDrawDiagnostics",
188 "--module-source-path", src.toString())
190 .files(findJavaFiles(src))
191 .run(Task.Expect.FAIL)
193 .getOutput(Task.OutputKind.DIRECT);
195 if (!log.contains("Test.java:1:52: compiler.err.not.def.access.class.intf.cant.access.reason: call(), api1.Api1, api1, (compiler.misc.not.def.access.does.not.read: m3x, api1, m1x)") ||
196 !log.contains("Test.java:1:76: compiler.err.not.def.access.class.intf.cant.access: toString(), java.lang.Object"))
197 throw new Exception("expected output not found");
201 public void testAssignClassToAutomaticModule(Path base) throws Exception {
202 //check that if a ClassSymbol belongs to an automatic module, it is properly assigned and not
203 //duplicated when being accessed through a classfile.
204 Path automaticSrc = base.resolve("automaticSrc");
205 tb.writeJavaFiles(automaticSrc, "package api1; public class Api1 {}");
206 Path automaticClasses = base.resolve("automaticClasses");
207 tb.createDirectories(automaticClasses);
209 String automaticLog = new JavacTask(tb)
210 .outdir(automaticClasses)
211 .files(findJavaFiles(automaticSrc))
214 .getOutput(Task.OutputKind.DIRECT);
216 if (!automaticLog.isEmpty())
217 throw new Exception("expected output not found: " + automaticLog);
219 Path modulePath = base.resolve("module-path");
221 Files.createDirectories(modulePath);
223 Path automaticJar = modulePath.resolve("a-1.0.jar");
225 new JarTask(tb, automaticJar)
226 .baseDir(automaticClasses)
227 .files("api1/Api1.class")
230 Path src = base.resolve("src");
231 Path src_m2 = src.resolve("m2x");
232 tb.writeJavaFiles(src_m2,
233 "module m2x { requires a; exports api2; }",
234 "package api2; public class Api2 { public static api1.Api1 get() { return null; } }");
235 Path src_m3 = src.resolve("m3x");
236 tb.writeJavaFiles(src_m3,
237 "module m3x { requires a; requires m2x; }",
238 "package test; public class Test { { api2.Api2.get(); api1.Api1 a1; } }");
239 Path classes = base.resolve("classes");
240 tb.createDirectories(classes);
243 .options("--module-path", modulePath.toString(),
244 "--module-source-path", src.toString())
246 .files(findJavaFiles(src_m2))
251 .options("--module-path", modulePath.toString(),
252 "--module-source-path", src.toString())
254 .files(findJavaFiles(src_m3))
260 public void testEmptyImplicitModuleInfo(Path base) throws Exception {
261 Path src = base.resolve("src");
262 Path src_m1 = src.resolve("m1x");
263 Files.createDirectories(src_m1);
264 try (Writer w = Files.newBufferedWriter(src_m1.resolve("module-info.java"))) {}
265 tb.writeJavaFiles(src_m1,
266 "package test; public class Test {}");
267 Path classes = base.resolve("classes");
268 tb.createDirectories(classes);
270 List<String> log = new JavacTask(tb)
271 .options("--source-path", src_m1.toString(),
274 .files(findJavaFiles(src_m1.resolve("test")))
275 .run(Task.Expect.FAIL)
277 .getOutputLines(OutputKind.DIRECT);
279 List<String> expected = Arrays.asList(
280 "- compiler.err.cant.access: module-info, (compiler.misc.bad.source.file.header: module-info.java, (compiler.misc.file.does.not.contain.module))",
283 if (!expected.equals(log)) {
284 throw new AssertionError("Unexpected output: " + log);
287 tb.writeJavaFiles(src_m1,
291 .options("--source-path", src_m1.toString())
293 .files(findJavaFiles(src_m1.resolve("test")))
300 public void testClassPackageClash(Path base) throws Exception {
301 Path src = base.resolve("src");
302 Path src_m1 = src.resolve("m1x");
303 tb.writeJavaFiles(src_m1,
304 "module m1x { exports test.m1x; }",
305 "package test.m1x;\n" +
306 "public class Test {}\n");
307 Path src_m2 = src.resolve("m2x");
308 tb.writeJavaFiles(src_m2,
309 "module m2x { requires m1x; }",
311 "public class m1x {}\n");
312 Path classes = base.resolve("classes");
313 tb.createDirectories(classes);
315 List<String> log = new JavacTask(tb)
316 .options("--module-source-path", src.toString(),
319 .files(findJavaFiles(src))
320 .run(Task.Expect.FAIL)
322 .getOutputLines(Task.OutputKind.DIRECT);
324 List<String> expected = Arrays.asList(
325 "m1x.java:2:8: compiler.err.clash.with.pkg.of.same.name: kindname.class, test.m1x",
329 if (!expected.equals(log)) {
330 throw new IllegalStateException(log.toString());
335 public void testImplicitJavaBase(Path base) throws Exception {
336 Path src = base.resolve("src");
337 Path src_java_base = src.resolve("java.base");
338 Files.createDirectories(src_java_base);
339 tb.writeJavaFiles(src_java_base, "module java.base { exports java.lang; }");
340 tb.writeJavaFiles(src_java_base,
341 "package java.lang; public class Object {}");
342 Path classes = base.resolve("classes");
343 tb.createDirectories(classes);
345 //module-info from source:
347 .options("-sourcepath", src_java_base.toString())
349 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
353 //module-info from class:
354 if (!Files.exists(classes.resolve("module-info.class"))) {
355 throw new AssertionError("module-info.class not created!");
360 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
364 //broken module-info.class:
365 Files.newOutputStream(classes.resolve("module-info.class")).close();
367 List<String> log = new JavacTask(tb)
368 .options("-XDrawDiagnostics")
370 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
373 .getOutputLines(OutputKind.DIRECT);
375 List<String> expected = Arrays.asList(
376 "- compiler.err.cant.access: <error>.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.illegal.start.of.class.file))",
379 if (!expected.equals(log)) {
380 throw new AssertionError("Unexpected output: " + log);
383 //broken module-info.java:
384 Files.delete(classes.resolve("module-info.class"));
386 try (Writer out = Files.newBufferedWriter(src_java_base.resolve("module-info.java"))) {
387 out.write("class Broken {}");
390 log = new JavacTask(tb)
391 .options("-sourcepath", src_java_base.toString(),
394 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
397 .getOutputLines(OutputKind.DIRECT);
399 expected = Arrays.asList("X");
401 if (expected.equals(log)) {
402 throw new AssertionError("Unexpected output: " + log);
407 public void testModuleInfoNameMismatchSource(Path base) throws Exception {
408 Path src = base.resolve("src");
409 Path m1 = src.resolve("m1x");
410 Files.createDirectories(m1);
411 tb.writeJavaFiles(m1, "module other { }",
412 "package test; public class Test {}");
413 Path classes = base.resolve("classes");
414 tb.createDirectories(classes);
416 List<String> log = new JavacTask(tb)
417 .options("--module-source-path", src.toString(),
420 .files(findJavaFiles(m1.resolve("test").resolve("Test.java")))
423 .getOutputLines(OutputKind.DIRECT);
425 List<String> expected = Arrays.asList(
426 "module-info.java:1:1: compiler.err.module.name.mismatch: other, m1x",
427 "- compiler.err.cant.access: m1x.module-info, (compiler.misc.cant.resolve.modules)",
430 if (!expected.equals(log)) {
431 throw new AssertionError("Unexpected output: " + log);
436 public void testModuleInfoNameMismatchClass(Path base) throws Exception {
437 Path src = base.resolve("src");
438 Files.createDirectories(src);
439 tb.writeJavaFiles(src, "module other { }",
440 "package test; public class Test {}");
441 Path classes = base.resolve("classes");
442 Path m1Classes = classes.resolve("m1x");
443 tb.createDirectories(m1Classes);
447 .files(findJavaFiles(src))
450 .getOutputLines(OutputKind.DIRECT);
452 Path src2 = base.resolve("src2");
453 Files.createDirectories(src2);
454 tb.writeJavaFiles(src2, "module use { requires m1x; }");
456 Path classes2 = base.resolve("classes2");
457 tb.createDirectories(classes2);
459 List<String> log = new JavacTask(tb)
460 .options("--module-path", classes.toString(),
463 .files(findJavaFiles(src2))
466 .getOutputLines(OutputKind.DIRECT);
468 List<String> expected = Arrays.asList(
469 "- compiler.err.cant.access: m1x.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.module.name.mismatch: other, m1x))",
470 "module-info.java:1:1: compiler.err.module.not.found: m1x",
473 if (!expected.equals(log)) {
474 throw new AssertionError("Unexpected output: " + log);
479 public void testGetDirectivesComplete(Path base) throws Exception {
480 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
481 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, null, null, null);
482 Symtab syms = Symtab.instance(task.getContext());
484 syms.java_base.getDirectives();
488 public void testPackageInModuleInfo(Path base) throws Exception {
489 Path src = base.resolve("src");
490 Files.createDirectories(src);
491 tb.writeJavaFiles(src, "package p; module foo { }");
492 Path classes = base.resolve("classes");
493 tb.createDirectories(classes);
495 List<String> log = new JavacTask(tb)
496 .options("-XDrawDiagnostics", "-XDshould-stop.ifError=FLOW")
498 .files(findJavaFiles(src))
501 .getOutputLines(OutputKind.DIRECT);
503 List<String> expected = Arrays.asList(
504 "module-info.java:1:1: compiler.err.no.pkg.in.module-info.java",
507 if (!expected.equals(log)) {
508 throw new AssertionError("Unexpected output: " + log);
513 public void testInvisibleClassVisiblePackageClash(Path base) throws Exception {
514 Path src = base.resolve("src");
515 Path src_m1 = src.resolve("m1x");
516 tb.writeJavaFiles(src_m1,
519 "import m1x.a.*; public class Test { A a; }\n",
521 "public class A { }\n");
522 Path src_m2 = src.resolve("m2x");
523 tb.writeJavaFiles(src_m2,
526 "public class a { public static class A { } }\n");
527 Path classes = base.resolve("classes");
528 tb.createDirectories(classes);
531 .options("--module-source-path", src.toString(),
534 .files(findJavaFiles(src))
540 public void testStripUnknownRequired(Path base) throws Exception {
541 Path src = base.resolve("src");
542 Path src_m1 = src.resolve("m1x");
543 tb.writeJavaFiles(src_m1,
545 Path src_m2 = src.resolve("m2x");
546 tb.writeJavaFiles(src_m2,
548 Path src_m3 = src.resolve("m3x");
549 tb.writeJavaFiles(src_m3,
551 Path src_m4 = src.resolve("m4x");
552 tb.writeJavaFiles(src_m4,
554 Path src_test = src.resolve("test");
555 tb.writeJavaFiles(src_test,
556 "module test { requires m1x; requires m2x; requires java.base; requires m3x; requires m4x; }");
557 Path src_compile = src.resolve("compile");
558 tb.writeJavaFiles(src_compile,
559 "module compile { exports p to test; }",
560 "package p; public class Test { }");
561 Path classes = base.resolve("classes");
562 tb.createDirectories(classes);
564 List<String> log = new JavacTask(tb)
565 .options("-processor", ListRequires.class.getName(),
566 "--module-source-path", src.toString(),
567 "--limit-modules", "compile",
568 "-XDaccessInternalAPI=true")
570 .files(findJavaFiles(src_compile))
573 .getOutputLines(Task.OutputKind.STDOUT);
575 List<String> expected = Arrays.asList(
581 if (!Objects.equals(log, expected))
582 throw new AssertionError("Unexpected output: " + log);
585 @SupportedAnnotationTypes("*")
586 @SupportedOptions("expectedEnclosedElements")
587 public static final class ListRequires extends AbstractProcessor {
592 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
594 ModuleElement compileE = processingEnv.getElementUtils().getModuleElement("compile");
595 ModuleElement testE = ElementFilter.exportsIn(compileE.getDirectives()).get(0).getTargetModules().get(0);
597 System.out.println("from directives:");
598 for (RequiresDirective rd : ElementFilter.requiresIn(testE.getDirectives())) {
599 System.out.println(rd.getDependency().getSimpleName());
602 System.out.println("from requires:");
603 for (RequiresDirective rd : ((ModuleSymbol) testE).requires) {
604 System.out.println(rd.getDependency().getSimpleName());
612 public SourceVersion getSupportedSourceVersion() {
613 return SourceVersion.latest();
619 public void testOnDemandCompletionModuleInfoJava(Path base) throws Exception {
620 Path src = base.resolve("src");
621 Path src_m1 = src.resolve("m1x");
622 tb.writeJavaFiles(src_m1,
623 "@Deprecated module m1x { }");
624 Path src_m2 = src.resolve("m2x");
625 tb.writeJavaFiles(src_m2,
626 "module m2x { requires m1x; }");
627 Path src_m3 = src.resolve("m3x");
628 tb.writeJavaFiles(src_m3,
629 "module m3x { requires m2x; requires m1x; }");
630 Path classes = base.resolve("classes");
631 tb.createDirectories(classes);
634 List<String> expected;
636 log = new JavacTask(tb)
637 .options("--module-source-path", src.toString())
639 .files(findJavaFiles(src_m1))
642 .getOutputLines(Task.OutputKind.DIRECT);
644 expected = Arrays.asList("");
646 if (!expected.equals(log)) {
647 throw new IllegalStateException(log.toString());
650 log = new JavacTask(tb)
651 .options("--module-source-path", src.toString(),
653 "-Xlint:deprecation")
655 .files(findJavaFiles(src_m3))
658 .getOutputLines(Task.OutputKind.DIRECT);
660 expected = Arrays.asList(
661 "module-info.java:1:23: compiler.warn.has.been.deprecated.module: m1x",
662 "module-info.java:1:37: compiler.warn.has.been.deprecated.module: m1x",
666 if (!expected.equals(log)) {
667 throw new IllegalStateException(log.toString());
672 public void testUnnamedPackage(Path base) throws Exception {
674 List<String> expected;
677 Path src8 = base.resolve("src8");
678 Files.createDirectories(src8);
679 tb.writeJavaFiles(src8,
680 "package test; public class Test {}");
681 Path classes = base.resolve("classes");
682 tb.createDirectories(classes);
684 out = new JavacTask(tb)
685 .options("--source-path", src8.toString(),
686 "-processor", UnnamedPackageProcessor.class.getName(),
689 .files(findJavaFiles(src8))
692 .getOutputLines(OutputKind.STDOUT);
694 expected = Arrays.asList("noModule");
696 if (!expected.equals(out)) {
697 throw new AssertionError("Unexpected output: " + out);
700 //-source 9, unnamed:
701 Path srcUnnamed = base.resolve("srcUnnamed");
702 Files.createDirectories(srcUnnamed);
703 tb.writeJavaFiles(srcUnnamed,
704 "public class Test {}");
705 Path classesUnnamed = base.resolve("classesUnnamed");
706 tb.createDirectories(classesUnnamed);
708 out = new JavacTask(tb)
709 .options("--source-path", srcUnnamed.toString(),
710 "-processor", UnnamedPackageProcessor.class.getName())
711 .outdir(classesUnnamed)
712 .files(findJavaFiles(srcUnnamed))
715 .getOutputLines(OutputKind.STDOUT);
717 expected = Arrays.asList("unnamedModule");
719 if (!expected.equals(out)) {
720 throw new AssertionError("Unexpected output: " + out);
724 Path srcNamed = base.resolve("srcNamed");
725 Files.createDirectories(srcNamed);
726 tb.writeJavaFiles(srcNamed,
728 "public class Test {}");
729 Path classesNamed = base.resolve("classesNamed");
730 tb.createDirectories(classesNamed);
732 out = new JavacTask(tb)
733 .options("--source-path", srcNamed.toString(),
735 "-processorpath", System.getProperty("test.class.path"),
736 "-processor", UnnamedPackageProcessor.class.getName())
737 .outdir(classesNamed)
738 .files(findJavaFiles(srcNamed))
741 .getOutputLines(OutputKind.STDOUT);
743 expected = Arrays.asList("m");
745 if (!expected.equals(out)) {
746 throw new AssertionError("Unexpected output: " + out);
749 //-source 9, conflict:
750 Path srcNamed2 = base.resolve("srcNamed2");
751 Path srcNamed2m1 = srcNamed2.resolve("m1x");
752 Files.createDirectories(srcNamed2m1);
753 tb.writeJavaFiles(srcNamed2m1,
755 "public class Test {}");
756 Path srcNamed2m2 = srcNamed2.resolve("m2x");
757 Files.createDirectories(srcNamed2m2);
758 tb.writeJavaFiles(srcNamed2m2,
760 "public class Test {}");
761 Path classesNamed2 = base.resolve("classesNamed2");
762 tb.createDirectories(classesNamed2);
764 out = new JavacTask(tb)
765 .options("--module-source-path", srcNamed2.toString(),
767 "-processorpath", System.getProperty("test.class.path"),
768 "-processor", UnnamedPackageProcessor.class.getName(),
769 "-XDshould-stop.ifError=FLOW")
770 .outdir(classesNamed2)
771 .files(findJavaFiles(srcNamed2))
774 .getOutputLines(OutputKind.STDOUT);
776 expected = Arrays.asList("null",
780 if (!expected.equals(out)) {
781 throw new AssertionError("Unexpected output: " + out);
785 @SupportedAnnotationTypes("*")
786 public static final class UnnamedPackageProcessor extends AbstractProcessor {
791 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
795 Elements elements = processingEnv.getElementUtils();
796 PackageElement pe = elements.getPackageElement("");
799 System.out.println("null");
801 ModuleElement mod = (ModuleElement) pe.getEnclosingElement();
803 System.out.println("noModule");
804 } else if (mod.isUnnamed()) {
805 System.out.println("unnamedModule");
807 System.out.println(mod);
811 ModuleElement m1x = elements.getModuleElement("m1x");
812 ModuleElement m2x = elements.getModuleElement("m2x");
814 if (m1x != null && m2x != null) {
815 System.out.println("m1x: " + (elements.getPackageElement(m1x, "") != null));
816 System.out.println("m2x: " + (elements.getPackageElement(m2x, "") != null));
825 public void testEmptyInExportedPackage(Path base) throws Exception {
826 Path src = base.resolve("src");
827 Path m = src.resolve("m");
829 "module m { exports api; }");
830 Path apiFile = m.resolve("api").resolve("Api.java");
831 Files.createDirectories(apiFile.getParent());
832 try (BufferedWriter w = Files.newBufferedWriter(apiFile)) {
833 w.write("//no package decl");
835 Path classes = base.resolve("classes");
836 tb.createDirectories(classes);
839 List<String> expected =
840 Arrays.asList("module-info.java:1:20: compiler.err.package.empty.or.not.found: api",
843 System.err.println("file explicitly specified:");
845 log = new JavacTask(tb)
846 .options("-XDrawDiagnostics",
847 "--module-source-path", src.toString())
849 .files(findJavaFiles(src))
850 .run(Task.Expect.FAIL)
852 .getOutputLines(Task.OutputKind.DIRECT);
854 if (!expected.equals(log))
855 throw new Exception("expected output not found: " + log);
857 System.err.println("file not specified:");
859 tb.cleanDirectory(classes);
861 log = new JavacTask(tb)
862 .options("-XDrawDiagnostics",
863 "--module-source-path", src.toString())
865 .files(findJavaFiles(m.resolve("module-info.java")))
866 .run(Task.Expect.FAIL)
868 .getOutputLines(Task.OutputKind.DIRECT);
870 if (!expected.equals(log))
871 throw new Exception("expected output not found: " + log);
875 public void testJustPackageInExportedPackage(Path base) throws Exception {
876 Path src = base.resolve("src");
877 Path m = src.resolve("m");
879 "module m { exports api; }");
880 Path apiFile = m.resolve("api").resolve("Api.java");
881 Files.createDirectories(apiFile.getParent());
882 try (BufferedWriter w = Files.newBufferedWriter(apiFile)) {
883 w.write("package api;");
885 Path classes = base.resolve("classes");
886 tb.createDirectories(classes);
888 System.err.println("file explicitly specified:");
891 .options("-XDrawDiagnostics",
892 "--module-source-path", src.toString())
894 .files(findJavaFiles(src))
898 System.err.println("file not specified:");
900 tb.cleanDirectory(classes);
903 .options("-XDrawDiagnostics",
904 "--module-source-path", src.toString())
906 .files(findJavaFiles(m.resolve("module-info.java")))
912 public void testWrongPackageInExportedPackage(Path base) throws Exception {
913 Path src = base.resolve("src");
914 Path m = src.resolve("m");
916 "module m { exports api; }");
917 Path apiFile = m.resolve("api").resolve("Api.java");
918 Files.createDirectories(apiFile.getParent());
919 try (BufferedWriter w = Files.newBufferedWriter(apiFile)) {
920 w.write("package impl; public class Api { }");
922 Path classes = base.resolve("classes");
923 tb.createDirectories(classes);
927 List<String> expected =
928 Arrays.asList("module-info.java:1:20: compiler.err.package.empty.or.not.found: api",
931 System.err.println("file explicitly specified:");
933 log = new JavacTask(tb)
934 .options("-XDrawDiagnostics",
935 "--module-source-path", src.toString())
937 .files(findJavaFiles(src))
938 .run(Task.Expect.FAIL)
940 .getOutputLines(Task.OutputKind.DIRECT);
942 if (!expected.equals(log))
943 throw new Exception("expected output not found: " + log);
945 System.err.println("file not specified:");
947 tb.cleanDirectory(classes);
949 log = new JavacTask(tb)
950 .options("-XDrawDiagnostics",
951 "--module-source-path", src.toString())
953 .files(findJavaFiles(m.resolve("module-info.java")))
954 .run(Task.Expect.FAIL)
956 .getOutputLines(Task.OutputKind.DIRECT);
958 if (!expected.equals(log))
959 throw new Exception("expected output not found: " + log);
963 public void testDependOnUnnamedAccessibility(Path base) throws Exception {
964 Path unnamedSrc = base.resolve("unnamed-src");
965 tb.writeJavaFiles(unnamedSrc,
966 "package p1; public class First { public static p2.Second get() { return null; } }",
967 "package p2; public class Second { public void test() { } }");
968 Path unnamedClasses = base.resolve("unnamed-classes");
969 tb.createDirectories(unnamedClasses);
971 System.err.println("compiling unnamed sources:");
974 .outdir(unnamedClasses)
975 .files(findJavaFiles(unnamedSrc))
980 Path src = base.resolve("src");
981 Path m = src.resolve("m");
984 "package p; public class Test { { p1.First.get().test(); } }");
985 Path classes = base.resolve("classes");
986 tb.createDirectories(classes);
988 System.err.println("compiling test module:");
991 .options("-classpath", unnamedClasses.toString(),
992 "--add-reads", "m=ALL-UNNAMED")
994 .files(findJavaFiles(src))