AutomaticModules.java revision 3573:c4a18ee691c4
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
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.nio.file.Files;
38import java.nio.file.Path;
39import java.util.Arrays;
40import java.util.List;
41
42import toolbox.JarTask;
43import toolbox.JavacTask;
44import toolbox.Task;
45
46public class AutomaticModules extends ModuleTestBase {
47
48    public static void main(String... args) throws Exception {
49        AutomaticModules t = new AutomaticModules();
50        t.runTests();
51    }
52
53    @Test
54    public void testSimple(Path base) throws Exception {
55        Path legacySrc = base.resolve("legacy-src");
56        tb.writeJavaFiles(legacySrc,
57                          "package api; import java.awt.event.ActionListener; public abstract class Api implements ActionListener {}");
58        Path legacyClasses = base.resolve("legacy-classes");
59        Files.createDirectories(legacyClasses);
60
61        String log = new JavacTask(tb)
62                .options()
63                .outdir(legacyClasses)
64                .files(findJavaFiles(legacySrc))
65                .run()
66                .writeAll()
67                .getOutput(Task.OutputKind.DIRECT);
68
69        if (!log.isEmpty()) {
70            throw new Exception("unexpected output: " + log);
71        }
72
73        Path modulePath = base.resolve("module-path");
74
75        Files.createDirectories(modulePath);
76
77        Path jar = modulePath.resolve("test-api-1.0.jar");
78
79        new JarTask(tb, jar)
80          .baseDir(legacyClasses)
81          .files("api/Api.class")
82          .run();
83
84        Path moduleSrc = base.resolve("module-src");
85        Path m1 = moduleSrc.resolve("m1");
86
87        Path classes = base.resolve("classes");
88
89        Files.createDirectories(classes);
90
91        tb.writeJavaFiles(m1,
92                          "module m1 { requires test.api; requires java.desktop; }",
93                          "package impl; public class Impl { public void e(api.Api api) { api.actionPerformed(null); } }");
94
95        new JavacTask(tb)
96                .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString())
97                .outdir(classes)
98                .files(findJavaFiles(moduleSrc))
99                .run()
100                .writeAll();
101    }
102
103    @Test
104    public void testUnnamedModule(Path base) throws Exception {
105        Path legacySrc = base.resolve("legacy-src");
106        tb.writeJavaFiles(legacySrc,
107                          "package api; public abstract class Api { public void run(CharSequence str) { } private void run(base.Base base) { } }",
108                          "package base; public interface Base { public void run(); }");
109        Path legacyClasses = base.resolve("legacy-classes");
110        Files.createDirectories(legacyClasses);
111
112        String log = new JavacTask(tb)
113                .options()
114                .outdir(legacyClasses)
115                .files(findJavaFiles(legacySrc))
116                .run()
117                .writeAll()
118                .getOutput(Task.OutputKind.DIRECT);
119
120        if (!log.isEmpty()) {
121            throw new Exception("unexpected output: " + log);
122        }
123
124        Path modulePath = base.resolve("module-path");
125
126        Files.createDirectories(modulePath);
127
128        Path apiJar = modulePath.resolve("test-api-1.0.jar");
129
130        new JarTask(tb, apiJar)
131          .baseDir(legacyClasses)
132          .files("api/Api.class")
133          .run();
134
135        Path baseJar = base.resolve("base.jar");
136
137        new JarTask(tb, baseJar)
138          .baseDir(legacyClasses)
139          .files("base/Base.class")
140          .run();
141
142        Path moduleSrc = base.resolve("module-src");
143        Path m1 = moduleSrc.resolve("m1");
144
145        Path classes = base.resolve("classes");
146
147        Files.createDirectories(classes);
148
149        tb.writeJavaFiles(m1,
150                          "module m1 { requires test.api; }",
151                          "package impl; public class Impl { public void e(api.Api api) { api.run(\"\"); } }");
152
153        new JavacTask(tb)
154                .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString(), "--class-path", baseJar.toString())
155                .outdir(classes)
156                .files(findJavaFiles(moduleSrc))
157                .run()
158                .writeAll();
159    }
160
161    @Test
162    public void testModuleInfoFromClassFileDependsOnAutomatic(Path base) throws Exception {
163        Path automaticSrc = base.resolve("automaticSrc");
164        tb.writeJavaFiles(automaticSrc, "package api; public class Api {}");
165        Path automaticClasses = base.resolve("automaticClasses");
166        tb.createDirectories(automaticClasses);
167
168        String automaticLog = new JavacTask(tb)
169                                .outdir(automaticClasses)
170                                .files(findJavaFiles(automaticSrc))
171                                .run()
172                                .writeAll()
173                                .getOutput(Task.OutputKind.DIRECT);
174
175        if (!automaticLog.isEmpty())
176            throw new Exception("expected output not found: " + automaticLog);
177
178        Path modulePath = base.resolve("module-path");
179
180        Files.createDirectories(modulePath);
181
182        Path automaticJar = modulePath.resolve("automatic-1.0.jar");
183
184        new JarTask(tb, automaticJar)
185          .baseDir(automaticClasses)
186          .files("api/Api.class")
187          .run();
188
189        Path depSrc = base.resolve("depSrc");
190        Path depClasses = base.resolve("depClasses");
191
192        Files.createDirectories(depSrc);
193        Files.createDirectories(depClasses);
194
195        tb.writeJavaFiles(depSrc,
196                          "module m1 { requires public automatic; }",
197                          "package dep; public class Dep { api.Api api; }");
198
199        new JavacTask(tb)
200                .options("--module-path", modulePath.toString())
201                .outdir(depClasses)
202                .files(findJavaFiles(depSrc))
203                .run()
204                .writeAll();
205
206        Path moduleJar = modulePath.resolve("m1.jar");
207
208        new JarTask(tb, moduleJar)
209          .baseDir(depClasses)
210          .files("module-info.class", "dep/Dep.class")
211          .run();
212
213        Path testSrc = base.resolve("testSrc");
214        Path testClasses = base.resolve("testClasses");
215
216        Files.createDirectories(testSrc);
217        Files.createDirectories(testClasses);
218
219        tb.writeJavaFiles(testSrc,
220                          "module m2 { requires automatic; }",
221                          "package test; public class Test { }");
222
223        new JavacTask(tb)
224                .options("--module-path", modulePath.toString())
225                .outdir(testClasses)
226                .files(findJavaFiles(testSrc))
227                .run()
228                .writeAll();
229    }
230
231    @Test
232    public void testAutomaticAndNamedModules(Path base) throws Exception {
233        Path modulePath = base.resolve("module-path");
234
235        Files.createDirectories(modulePath);
236
237        for (char c : new char[] {'A', 'B'}) {
238            Path automaticSrc = base.resolve("automaticSrc" + c);
239            tb.writeJavaFiles(automaticSrc, "package api" + c + "; public class Api {}");
240            Path automaticClasses = base.resolve("automaticClasses" + c);
241            tb.createDirectories(automaticClasses);
242
243            String automaticLog = new JavacTask(tb)
244                                    .outdir(automaticClasses)
245                                    .files(findJavaFiles(automaticSrc))
246                                    .run()
247                                    .writeAll()
248                                    .getOutput(Task.OutputKind.DIRECT);
249
250            if (!automaticLog.isEmpty())
251                throw new Exception("expected output not found: " + automaticLog);
252
253            Path automaticJar = modulePath.resolve("automatic" + c + "-1.0.jar");
254
255            new JarTask(tb, automaticJar)
256              .baseDir(automaticClasses)
257              .files("api" + c + "/Api.class")
258              .run();
259        }
260
261        Path moduleSrc = base.resolve("module-src");
262
263        tb.writeJavaFiles(moduleSrc.resolve("m1"),
264                          "module m1 { requires automaticA; }",
265                          "package impl; public class Impl { apiA.Api a; apiB.Api b; m2.M2 m;}");
266
267        tb.writeJavaFiles(moduleSrc.resolve("m2"),
268                          "module m2 { exports m2; }",
269                          "package m2; public class M2 { }");
270
271        Path classes = base.resolve("classes");
272
273        Files.createDirectories(classes);
274
275        List<String> log = new JavacTask(tb)
276                .options("--module-source-path", moduleSrc.toString(),
277                         "--module-path", modulePath.toString(),
278                         "--add-modules", "automaticB",
279                         "-XDrawDiagnostics")
280                .outdir(classes)
281                .files(findJavaFiles(moduleSrc))
282                .run(Task.Expect.FAIL)
283                .writeAll()
284                .getOutputLines(Task.OutputKind.DIRECT);
285
286        List<String> expected = Arrays.asList("Impl.java:1:61: compiler.err.not.def.access.package.cant.access: m2.M2, m2",
287                                              "1 error");
288
289        if (!expected.equals(log)) {
290            throw new Exception("expected output not found: " + log);
291        }
292
293        log = new JavacTask(tb)
294                .options("--module-source-path", moduleSrc.toString(),
295                         "--module-path", modulePath.toString(),
296                         "-XDrawDiagnostics")
297                .outdir(classes)
298                .files(findJavaFiles(moduleSrc))
299                .run(Task.Expect.FAIL)
300                .writeAll()
301                .getOutputLines(Task.OutputKind.DIRECT);
302
303        expected = Arrays.asList("Impl.java:1:51: compiler.err.doesnt.exist: apiB",
304                                 "Impl.java:1:61: compiler.err.not.def.access.package.cant.access: m2.M2, m2",
305                                 "2 errors");
306
307        if (!expected.equals(log)) {
308            throw new Exception("expected output not found: " + log);
309        }
310    }
311}
312