AutomaticModules.java revision 4158:abaedfca9e3e
1/*
2 * Copyright (c) 2015, 2016, 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 8155026 8178011
27 * @summary Test automatic modules
28 * @library /tools/lib
29 * @modules
30 *      java.desktop
31 *      jdk.compiler/com.sun.tools.javac.api
32 *      jdk.compiler/com.sun.tools.javac.main
33 * @build toolbox.ToolBox toolbox.JavacTask toolbox.JarTask ModuleTestBase
34 * @run main AutomaticModules
35 */
36
37import java.io.File;
38import java.nio.file.Files;
39import java.nio.file.Path;
40import java.util.Arrays;
41import java.util.List;
42import java.util.zip.ZipEntry;
43import java.util.zip.ZipOutputStream;
44
45import toolbox.JarTask;
46import toolbox.JavacTask;
47import toolbox.Task;
48import toolbox.Task.Mode;
49
50public class AutomaticModules extends ModuleTestBase {
51
52    public static void main(String... args) throws Exception {
53        AutomaticModules t = new AutomaticModules();
54        t.runTests();
55    }
56
57    @Test
58    public void testSimple(Path base) throws Exception {
59        Path legacySrc = base.resolve("legacy-src");
60        tb.writeJavaFiles(legacySrc,
61                          "package api; import java.awt.event.ActionListener; public abstract class Api implements ActionListener {}");
62        Path legacyClasses = base.resolve("legacy-classes");
63        Files.createDirectories(legacyClasses);
64
65        String log = new JavacTask(tb)
66                .options()
67                .outdir(legacyClasses)
68                .files(findJavaFiles(legacySrc))
69                .run()
70                .writeAll()
71                .getOutput(Task.OutputKind.DIRECT);
72
73        if (!log.isEmpty()) {
74            throw new Exception("unexpected output: " + log);
75        }
76
77        Path modulePath = base.resolve("module-path");
78
79        Files.createDirectories(modulePath);
80
81        Path jar = modulePath.resolve("test-api-1.0.jar");
82
83        new JarTask(tb, jar)
84          .baseDir(legacyClasses)
85          .files("api/Api.class")
86          .run();
87
88        Path moduleSrc = base.resolve("module-src");
89        Path m1 = moduleSrc.resolve("m1x");
90
91        Path classes = base.resolve("classes");
92
93        Files.createDirectories(classes);
94
95        tb.writeJavaFiles(m1,
96                          "module m1x { requires test.api; requires java.desktop; }",
97                          "package impl; public class Impl { public void e(api.Api api) { api.actionPerformed(null); } }");
98
99        new JavacTask(tb)
100                .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString())
101                .outdir(classes)
102                .files(findJavaFiles(moduleSrc))
103                .run()
104                .writeAll();
105    }
106
107    @Test
108    public void testUnnamedModule(Path base) throws Exception {
109        Path legacySrc = base.resolve("legacy-src");
110        tb.writeJavaFiles(legacySrc,
111                          "package api; public abstract class Api { public void run(CharSequence str) { } private void run(base.Base base) { } }",
112                          "package base; public interface Base { public void run(); }");
113        Path legacyClasses = base.resolve("legacy-classes");
114        Files.createDirectories(legacyClasses);
115
116        String log = new JavacTask(tb)
117                .options()
118                .outdir(legacyClasses)
119                .files(findJavaFiles(legacySrc))
120                .run()
121                .writeAll()
122                .getOutput(Task.OutputKind.DIRECT);
123
124        if (!log.isEmpty()) {
125            throw new Exception("unexpected output: " + log);
126        }
127
128        Path modulePath = base.resolve("module-path");
129
130        Files.createDirectories(modulePath);
131
132        Path apiJar = modulePath.resolve("test-api-1.0.jar");
133
134        new JarTask(tb, apiJar)
135          .baseDir(legacyClasses)
136          .files("api/Api.class")
137          .run();
138
139        Path baseJar = base.resolve("base.jar");
140
141        new JarTask(tb, baseJar)
142          .baseDir(legacyClasses)
143          .files("base/Base.class")
144          .run();
145
146        Path moduleSrc = base.resolve("module-src");
147        Path m1 = moduleSrc.resolve("m1x");
148
149        Path classes = base.resolve("classes");
150
151        Files.createDirectories(classes);
152
153        tb.writeJavaFiles(m1,
154                          "module m1x { requires test.api; }",
155                          "package impl; public class Impl { public void e(api.Api api) { api.run(\"\"); } }");
156
157        new JavacTask(tb)
158                .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString(), "--class-path", baseJar.toString())
159                .outdir(classes)
160                .files(findJavaFiles(moduleSrc))
161                .run()
162                .writeAll();
163    }
164
165    @Test
166    public void testModuleInfoFromClassFileDependsOnAutomatic(Path base) throws Exception {
167        Path automaticSrc = base.resolve("automaticSrc");
168        tb.writeJavaFiles(automaticSrc, "package api; public class Api {}");
169        Path automaticClasses = base.resolve("automaticClasses");
170        tb.createDirectories(automaticClasses);
171
172        String automaticLog = new JavacTask(tb)
173                                .outdir(automaticClasses)
174                                .files(findJavaFiles(automaticSrc))
175                                .run()
176                                .writeAll()
177                                .getOutput(Task.OutputKind.DIRECT);
178
179        if (!automaticLog.isEmpty())
180            throw new Exception("expected output not found: " + automaticLog);
181
182        Path modulePath = base.resolve("module-path");
183
184        Files.createDirectories(modulePath);
185
186        Path automaticJar = modulePath.resolve("automatic-1.0.jar");
187
188        new JarTask(tb, automaticJar)
189          .baseDir(automaticClasses)
190          .files("api/Api.class")
191          .run();
192
193        Path depSrc = base.resolve("depSrc");
194        Path depClasses = base.resolve("depClasses");
195
196        Files.createDirectories(depSrc);
197        Files.createDirectories(depClasses);
198
199        tb.writeJavaFiles(depSrc,
200                          "module m1x { requires transitive automatic; }",
201                          "package dep; public class Dep { api.Api api; }");
202
203        new JavacTask(tb)
204                .options("--module-path", modulePath.toString())
205                .outdir(depClasses)
206                .files(findJavaFiles(depSrc))
207                .run()
208                .writeAll();
209
210        Path moduleJar = modulePath.resolve("m1x.jar");
211
212        new JarTask(tb, moduleJar)
213          .baseDir(depClasses)
214          .files("module-info.class", "dep/Dep.class")
215          .run();
216
217        Path testSrc = base.resolve("testSrc");
218        Path testClasses = base.resolve("testClasses");
219
220        Files.createDirectories(testSrc);
221        Files.createDirectories(testClasses);
222
223        tb.writeJavaFiles(testSrc,
224                          "module m2x { requires automatic; }",
225                          "package test; public class Test { }");
226
227        new JavacTask(tb)
228                .options("--module-path", modulePath.toString())
229                .outdir(testClasses)
230                .files(findJavaFiles(testSrc))
231                .run()
232                .writeAll();
233    }
234
235    @Test
236    public void testAutomaticAndNamedModules(Path base) throws Exception {
237        Path modulePath = base.resolve("module-path");
238
239        Files.createDirectories(modulePath);
240
241        for (char c : new char[] {'A', 'B'}) {
242            Path automaticSrc = base.resolve("automaticSrc" + c);
243            tb.writeJavaFiles(automaticSrc, "package api" + c + "; public class Api {}");
244            Path automaticClasses = base.resolve("automaticClasses" + c);
245            tb.createDirectories(automaticClasses);
246
247            String automaticLog = new JavacTask(tb)
248                                    .outdir(automaticClasses)
249                                    .files(findJavaFiles(automaticSrc))
250                                    .run()
251                                    .writeAll()
252                                    .getOutput(Task.OutputKind.DIRECT);
253
254            if (!automaticLog.isEmpty())
255                throw new Exception("expected output not found: " + automaticLog);
256
257            Path automaticJar = modulePath.resolve("automatic" + c + "-1.0.jar");
258
259            new JarTask(tb, automaticJar)
260              .baseDir(automaticClasses)
261              .files("api" + c + "/Api.class")
262              .run();
263        }
264
265        Path moduleSrc = base.resolve("module-src");
266
267        tb.writeJavaFiles(moduleSrc.resolve("m1x"),
268                          "module m1x { requires static automaticA; }",
269                          "package impl; public class Impl { apiA.Api a; apiB.Api b; m2x.M2 m;}");
270
271        tb.writeJavaFiles(moduleSrc.resolve("m2x"),
272                          "module m2x { exports m2x; }",
273                          "package m2x; public class M2 { }");
274
275        Path classes = base.resolve("classes");
276
277        Files.createDirectories(classes);
278
279        List<String> log = new JavacTask(tb)
280                .options("--module-source-path", moduleSrc.toString(),
281                         "--module-path", modulePath.toString(),
282                         "--add-modules", "automaticB",
283                         "-XDrawDiagnostics")
284                .outdir(classes)
285                .files(findJavaFiles(moduleSrc))
286                .run(Task.Expect.FAIL)
287                .writeAll()
288                .getOutputLines(Task.OutputKind.DIRECT);
289
290        List<String> expected = Arrays.asList("Impl.java:1:59: compiler.err.package.not.visible: m2x, (compiler.misc.not.def.access.does.not.read: m1x, m2x, m2x)",
291                                              "1 error");
292
293        if (!expected.equals(log)) {
294            throw new Exception("expected output not found: " + log);
295        }
296
297        log = new JavacTask(tb)
298                .options("--module-source-path", moduleSrc.toString(),
299                         "--module-path", modulePath.toString(),
300                         "-XDrawDiagnostics")
301                .outdir(classes)
302                .files(findJavaFiles(moduleSrc))
303                .run(Task.Expect.FAIL)
304                .writeAll()
305                .getOutputLines(Task.OutputKind.DIRECT);
306
307        expected = Arrays.asList("Impl.java:1:59: compiler.err.package.not.visible: m2x, (compiler.misc.not.def.access.does.not.read: m1x, m2x, m2x)",
308                                 "1 error");
309
310        if (!expected.equals(log)) {
311            throw new Exception("expected output not found: " + log);
312        }
313    }
314
315    @Test
316    public void testWithTrailingVersion(Path base) throws Exception {
317        Path legacySrc = base.resolve("legacy-src");
318        tb.writeJavaFiles(legacySrc,
319                          "package api; public class Api {}");
320        Path legacyClasses = base.resolve("legacy-classes");
321        Files.createDirectories(legacyClasses);
322
323        String log = new JavacTask(tb)
324                .options()
325                .outdir(legacyClasses)
326                .files(findJavaFiles(legacySrc))
327                .run()
328                .writeAll()
329                .getOutput(Task.OutputKind.DIRECT);
330
331        if (!log.isEmpty()) {
332            throw new Exception("unexpected output: " + log);
333        }
334
335        Path modulePath = base.resolve("module-path");
336
337        Files.createDirectories(modulePath);
338
339        Path jar = modulePath.resolve("test1.jar");
340
341        new JarTask(tb, jar)
342          .baseDir(legacyClasses)
343          .files("api/Api.class")
344          .run();
345
346        Path moduleSrc = base.resolve("module-src");
347        Path m = moduleSrc.resolve("m");
348
349        Path classes = base.resolve("classes");
350
351        Files.createDirectories(classes);
352
353        tb.writeJavaFiles(m,
354                          "module m { requires test1; }",
355                          "package impl; public class Impl { public void e(api.Api api) { } }");
356
357        new JavacTask(tb)
358                .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString())
359                .outdir(classes)
360                .files(findJavaFiles(moduleSrc))
361                .run()
362                .writeAll();
363    }
364
365    @Test
366    public void testMultipleAutomatic(Path base) throws Exception {
367        Path modulePath = base.resolve("module-path");
368
369        Files.createDirectories(modulePath);
370
371        for (char c : new char[] {'A', 'B'}) {
372            Path automaticSrc = base.resolve("automaticSrc" + c);
373            tb.writeJavaFiles(automaticSrc, "package api" + c + "; public class Api {}");
374            Path automaticClasses = base.resolve("automaticClasses" + c);
375            tb.createDirectories(automaticClasses);
376
377            String automaticLog = new JavacTask(tb)
378                                    .outdir(automaticClasses)
379                                    .files(findJavaFiles(automaticSrc))
380                                    .run()
381                                    .writeAll()
382                                    .getOutput(Task.OutputKind.DIRECT);
383
384            if (!automaticLog.isEmpty())
385                throw new Exception("expected output not found: " + automaticLog);
386
387            Path automaticJar = modulePath.resolve("automatic" + c + "-1.0.jar");
388
389            new JarTask(tb, automaticJar)
390              .baseDir(automaticClasses)
391              .files("api" + c + "/Api.class")
392              .run();
393        }
394
395        Path src = base.resolve("src");
396
397        tb.writeJavaFiles(src.resolve("m1x"),
398                          "package impl; public class Impl { apiA.Api a; apiB.Api b; }");
399
400        Path classes = base.resolve("classes");
401
402        Files.createDirectories(classes);
403
404        List<String> log = new JavacTask(tb)
405                .options("--module-path", modulePath.toString(),
406                         "-XDrawDiagnostics")
407                .outdir(classes)
408                .files(findJavaFiles(src))
409                .run(Task.Expect.FAIL)
410                .writeAll()
411                .getOutputLines(Task.OutputKind.DIRECT);
412
413        List<String> expected = Arrays.asList("Impl.java:1:35: compiler.err.package.not.visible: apiA, (compiler.misc.not.def.access.does.not.read.from.unnamed: apiA, automaticA)",
414                                              "Impl.java:1:47: compiler.err.package.not.visible: apiB, (compiler.misc.not.def.access.does.not.read.from.unnamed: apiB, automaticB)",
415                                              "2 errors");
416
417        if (!expected.equals(log)) {
418            throw new Exception("expected output not found: " + log);
419        }
420
421        new JavacTask(tb)
422                .options("--module-path", modulePath.toString(),
423                         "--add-modules", "automaticA",
424                         "-XDrawDiagnostics")
425                .outdir(classes)
426                .files(findJavaFiles(src))
427                .run()
428                .writeAll();
429    }
430
431    @Test
432    public void testLintRequireAutomatic(Path base) throws Exception {
433        Path modulePath = base.resolve("module-path");
434
435        Files.createDirectories(modulePath);
436
437        for (char c : new char[] {'A', 'B'}) {
438            Path automaticSrc = base.resolve("automaticSrc" + c);
439            tb.writeJavaFiles(automaticSrc, "package api" + c + "; public class Api {}");
440            Path automaticClasses = base.resolve("automaticClasses" + c);
441            tb.createDirectories(automaticClasses);
442
443            String automaticLog = new JavacTask(tb)
444                                    .outdir(automaticClasses)
445                                    .files(findJavaFiles(automaticSrc))
446                                    .run()
447                                    .writeAll()
448                                    .getOutput(Task.OutputKind.DIRECT);
449
450            if (!automaticLog.isEmpty())
451                throw new Exception("expected output not found: " + automaticLog);
452
453            Path automaticJar = modulePath.resolve("automatic" + c + "-1.0.jar");
454
455            new JarTask(tb, automaticJar)
456              .baseDir(automaticClasses)
457              .files("api" + c + "/Api.class")
458              .run();
459        }
460
461        Path src = base.resolve("src");
462
463        tb.writeJavaFiles(src,
464                          "module m1x {\n" +
465                          "    requires transitive automaticA;\n" +
466                          "    requires automaticB;\n" +
467                          "}");
468
469        Path classes = base.resolve("classes");
470
471        Files.createDirectories(classes);
472
473        List<String> expected;
474        List<String> log;
475
476        log = new JavacTask(tb)
477            .options("--source-path", src.toString(),
478                     "--module-path", modulePath.toString(),
479                     "-XDrawDiagnostics",
480                     "-Werror")
481            .outdir(classes)
482            .files(findJavaFiles(src))
483            .run(Task.Expect.FAIL)
484            .writeAll()
485            .getOutputLines(Task.OutputKind.DIRECT);
486
487        expected = Arrays.asList("module-info.java:2:25: compiler.warn.requires.transitive.automatic",
488                                 "- compiler.err.warnings.and.werror",
489                                 "1 error",
490                                 "1 warning");
491
492        if (!expected.equals(log)) {
493            throw new Exception("expected output not found: " + log);
494        }
495
496        log = new JavacTask(tb)
497            .options("--source-path", src.toString(),
498                     "--module-path", modulePath.toString(),
499                     "-Xlint:requires-automatic",
500                     "-XDrawDiagnostics",
501                     "-Werror")
502            .outdir(classes)
503            .files(findJavaFiles(src))
504            .run(Task.Expect.FAIL)
505            .writeAll()
506            .getOutputLines(Task.OutputKind.DIRECT);
507
508        expected = Arrays.asList("module-info.java:2:25: compiler.warn.requires.transitive.automatic",
509                                 "module-info.java:3:14: compiler.warn.requires.automatic",
510                                 "- compiler.err.warnings.and.werror",
511                                 "1 error",
512                                 "2 warnings");
513
514        if (!expected.equals(log)) {
515            throw new Exception("expected output not found: " + log);
516        }
517
518        log = new JavacTask(tb)
519            .options("--source-path", src.toString(),
520                     "--module-path", modulePath.toString(),
521                     "-Xlint:-requires-transitive-automatic,requires-automatic",
522                     "-XDrawDiagnostics",
523                     "-Werror")
524            .outdir(classes)
525            .files(findJavaFiles(src))
526            .run(Task.Expect.FAIL)
527            .writeAll()
528            .getOutputLines(Task.OutputKind.DIRECT);
529
530        expected = Arrays.asList("module-info.java:2:25: compiler.warn.requires.automatic",
531                                 "module-info.java:3:14: compiler.warn.requires.automatic",
532                                 "- compiler.err.warnings.and.werror",
533                                 "1 error",
534                                 "2 warnings");
535
536        if (!expected.equals(log)) {
537            throw new Exception("expected output not found: " + log);
538        }
539
540        new JavacTask(tb)
541            .options("--source-path", src.toString(),
542                     "--module-path", modulePath.toString(),
543                     "-Xlint:-requires-transitive-automatic",
544                     "-XDrawDiagnostics",
545                     "-Werror")
546            .outdir(classes)
547            .files(findJavaFiles(src))
548            .run(Task.Expect.SUCCESS)
549            .writeAll()
550            .getOutputLines(Task.OutputKind.DIRECT);
551
552        tb.writeJavaFiles(src,
553                          "@SuppressWarnings(\"requires-transitive-automatic\")\n" +
554                          "module m1x {\n" +
555                          "    requires transitive automaticA;\n" +
556                          "    requires automaticB;\n" +
557                          "}");
558
559        new JavacTask(tb)
560            .options("--source-path", src.toString(),
561                     "--module-path", modulePath.toString(),
562                     "-XDrawDiagnostics",
563                     "-Werror")
564            .outdir(classes)
565            .files(findJavaFiles(src))
566            .run(Task.Expect.SUCCESS)
567            .writeAll()
568            .getOutputLines(Task.OutputKind.DIRECT);
569
570        log = new JavacTask(tb)
571            .options("--source-path", src.toString(),
572                     "--module-path", modulePath.toString(),
573                     "-Xlint:requires-automatic",
574                     "-XDrawDiagnostics",
575                     "-Werror")
576            .outdir(classes)
577            .files(findJavaFiles(src))
578            .run(Task.Expect.FAIL)
579            .writeAll()
580            .getOutputLines(Task.OutputKind.DIRECT);
581
582        expected = Arrays.asList("module-info.java:3:25: compiler.warn.requires.automatic",
583                                 "module-info.java:4:14: compiler.warn.requires.automatic",
584                                 "- compiler.err.warnings.and.werror",
585                                 "1 error",
586                                 "2 warnings");
587
588        if (!expected.equals(log)) {
589            throw new Exception("expected output not found: " + log);
590        }
591
592        tb.writeJavaFiles(src,
593                          "@SuppressWarnings(\"requires-automatic\")\n" +
594                          "module m1x {\n" +
595                          "    requires transitive automaticA;\n" +
596                          "    requires automaticB;\n" +
597                          "}");
598
599        log = new JavacTask(tb)
600            .options("--source-path", src.toString(),
601                     "--module-path", modulePath.toString(),
602                     "-Xlint:requires-automatic",
603                     "-XDrawDiagnostics",
604                     "-Werror")
605            .outdir(classes)
606            .files(findJavaFiles(src))
607            .run(Task.Expect.FAIL)
608            .writeAll()
609            .getOutputLines(Task.OutputKind.DIRECT);
610
611        expected = Arrays.asList("module-info.java:3:25: compiler.warn.requires.transitive.automatic",
612                                 "- compiler.err.warnings.and.werror",
613                                 "1 error",
614                                 "1 warning");
615
616        if (!expected.equals(log)) {
617            throw new Exception("expected output not found: " + log);
618        }
619    }
620
621    @Test
622    public void testAutomaticModuleNameCorrect(Path base) throws Exception {
623        Path modulePath = base.resolve("module-path");
624
625        Files.createDirectories(modulePath);
626
627        Path automaticSrc = base.resolve("automaticSrc");
628        tb.writeJavaFiles(automaticSrc, "package api; public class Api {}");
629        Path automaticClasses = base.resolve("automaticClasses");
630        tb.createDirectories(automaticClasses);
631
632        String automaticLog = new JavacTask(tb)
633                                .outdir(automaticClasses)
634                                .files(findJavaFiles(automaticSrc))
635                                .run()
636                                .writeAll()
637                                .getOutput(Task.OutputKind.DIRECT);
638
639        if (!automaticLog.isEmpty())
640            throw new Exception("expected output not found: " + automaticLog);
641
642        Path automaticJar = modulePath.resolve("automatic-1.0.jar");
643
644        new JarTask(tb, automaticJar)
645          .baseDir(automaticClasses)
646          .files("api/Api.class")
647          .manifest("Automatic-Module-Name: custom.module.name\n\n")
648          .run();
649
650        Path src = base.resolve("src");
651
652        tb.writeJavaFiles(src,
653                          "module m { requires custom.module.name; }",
654                          "package impl; public class Impl { api.Api a; }");
655
656        Path classes = base.resolve("classes");
657
658        Files.createDirectories(classes);
659
660        new JavacTask(tb)
661                .options("--module-path", modulePath.toString(),
662                         "-XDrawDiagnostics")
663                .outdir(classes)
664                .files(findJavaFiles(src))
665                .run(Task.Expect.SUCCESS)
666                .writeAll()
667                .getOutputLines(Task.OutputKind.DIRECT);
668
669        tb.writeJavaFiles(src,
670                          "module m { requires automatic; }");
671
672        List<String> log = new JavacTask(tb)
673                .options("--module-path", modulePath.toString(),
674                         "-XDrawDiagnostics")
675                .outdir(classes)
676                .files(findJavaFiles(src))
677                .run(Task.Expect.FAIL)
678                .writeAll()
679                .getOutputLines(Task.OutputKind.DIRECT);
680
681        List<String> expected =
682                Arrays.asList("module-info.java:1:21: compiler.err.module.not.found: automatic",
683                              "1 error");
684
685        if (!expected.equals(log)) {
686            throw new Exception("expected output not found: " + log);
687        }
688    }
689
690    @Test
691    public void testAutomaticModuleNameIncorrect(Path base) throws Exception {
692        for (String name : new String[] {"", "999", "foo.class", "foo._"}) {
693            if (Files.isDirectory(base)) {
694                tb.cleanDirectory(base);
695            }
696            Path modulePath = base.resolve("module-path");
697
698            Files.createDirectories(modulePath);
699
700            Path automaticSrc = base.resolve("automaticSrc");
701            tb.writeJavaFiles(automaticSrc, "package api; public class Api {}");
702            Path automaticClasses = base.resolve("automaticClasses");
703            tb.createDirectories(automaticClasses);
704
705            String automaticLog = new JavacTask(tb)
706                                    .outdir(automaticClasses)
707                                    .files(findJavaFiles(automaticSrc))
708                                    .run()
709                                    .writeAll()
710                                    .getOutput(Task.OutputKind.DIRECT);
711
712            if (!automaticLog.isEmpty())
713                throw new Exception("expected output not found: " + automaticLog);
714
715            Path automaticJar = modulePath.resolve("automatic-1.0.jar");
716
717            new JarTask(tb, automaticJar)
718              .baseDir(automaticClasses)
719              .files("api/Api.class")
720              .manifest("Automatic-Module-Name: " + name + "\n\n")
721              .run();
722
723            Path src = base.resolve("src");
724
725            tb.writeJavaFiles(src,
726                              "package impl; public class Impl { api.Api a; }");
727
728            Path classes = base.resolve("classes");
729
730            Files.createDirectories(classes);
731
732            List<String> log = new JavacTask(tb, Mode.CMDLINE)
733                    .options("--module-path", modulePath.toString(),
734                             "--add-modules", "ALL-MODULE-PATH",
735                             "-XDrawDiagnostics")
736                    .outdir(classes)
737                    .files(findJavaFiles(src))
738                    .run(Task.Expect.FAIL)
739                    .writeAll()
740                    .getOutputLines(Task.OutputKind.DIRECT);
741
742            List<String> expected =
743                    Arrays.asList("- compiler.err.locn.cant.get.module.name.for.jar: " +
744                                      "testAutomaticModuleNameIncorrect/module-path/automatic-1.0.jar".replace("/", File.separator),
745                                  "1 error");
746
747            if (!expected.equals(log)) {
748                throw new Exception("expected output not found: " + log);
749            }
750        }
751    }
752
753    @Test
754    public void testAutomaticModuleNameBroken(Path base) throws Exception {
755        Path modulePath = base.resolve("module-path");
756
757        Files.createDirectories(modulePath);
758
759        Path automaticSrc = base.resolve("automaticSrc");
760        tb.writeJavaFiles(automaticSrc, "package api; public class Api {}");
761        Path automaticClasses = base.resolve("automaticClasses");
762        tb.createDirectories(automaticClasses);
763
764        String automaticLog = new JavacTask(tb)
765                                .outdir(automaticClasses)
766                                .files(findJavaFiles(automaticSrc))
767                                .run()
768                                .writeAll()
769                                .getOutput(Task.OutputKind.DIRECT);
770
771        if (!automaticLog.isEmpty())
772            throw new Exception("expected output not found: " + automaticLog);
773
774        Path automaticJar = modulePath.resolve("automatic-1.0.jar");
775
776        try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(automaticJar))) {
777            out.putNextEntry(new ZipEntry("api/Api.class"));
778            Files.copy(automaticClasses.resolve("api").resolve("Api.class"), out);
779        }
780
781        Path src = base.resolve("src");
782
783        tb.writeJavaFiles(src,
784                          "module m { requires automatic; }",
785                          "package impl; public class Impl { api.Api a; }");
786
787        Path classes = base.resolve("classes");
788
789        Files.createDirectories(classes);
790
791        new JavacTask(tb)
792                .options("--module-path", modulePath.toString(),
793                         "-XDrawDiagnostics")
794                .outdir(classes)
795                .files(findJavaFiles(src))
796                .run(Task.Expect.SUCCESS)
797                .writeAll()
798                .getOutputLines(Task.OutputKind.DIRECT);
799
800        tb.writeJavaFiles(src,
801                          "module m { requires custom.module.name; }");
802
803        List<String> log = new JavacTask(tb)
804                .options("--module-path", modulePath.toString(),
805                         "-XDrawDiagnostics")
806                .outdir(classes)
807                .files(findJavaFiles(src))
808                .run(Task.Expect.FAIL)
809                .writeAll()
810                .getOutputLines(Task.OutputKind.DIRECT);
811
812        List<String> expected =
813                Arrays.asList("module-info.java:1:34: compiler.err.module.not.found: custom.module.name",
814                              "1 error");
815
816        if (!expected.equals(log)) {
817            throw new Exception("expected output not found: " + log);
818        }
819    }
820
821}
822