AutomaticModules.java revision 3507:7637541752e7
11541Srgrimes/*
21541Srgrimes * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
31549Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41549Srgrimes *
51541Srgrimes * This code is free software; you can redistribute it and/or modify it
61541Srgrimes * under the terms of the GNU General Public License version 2 only, as
71541Srgrimes * published by the Free Software Foundation.
81541Srgrimes *
91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131541Srgrimes * accompanied this code).
141541Srgrimes *
151541Srgrimes * You should have received a copy of the GNU General Public License version
161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181541Srgrimes *
191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
201541Srgrimes * or visit www.oracle.com if you need additional information or have any
211541Srgrimes * questions.
221541Srgrimes */
231541Srgrimes
241541Srgrimes/**
251541Srgrimes * @test
261541Srgrimes * @bug 8155026
271541Srgrimes * @summary Test automatic modules
281541Srgrimes * @library /tools/lib
291541Srgrimes * @modules
301541Srgrimes *      java.desktop
311541Srgrimes *      jdk.compiler/com.sun.tools.javac.api
321541Srgrimes *      jdk.compiler/com.sun.tools.javac.main
331541Srgrimes * @build toolbox.ToolBox toolbox.JavacTask toolbox.JarTask ModuleTestBase
341541Srgrimes * @run main AutomaticModules
351541Srgrimes */
361541Srgrimes
371541Srgrimesimport java.nio.file.Files;
381549Srgrimesimport java.nio.file.Path;
3950477Speterimport java.util.Arrays;
401541Srgrimesimport java.util.List;
411541Srgrimes
421549Srgrimesimport toolbox.JarTask;
431549Srgrimesimport toolbox.JavacTask;
441549Srgrimesimport toolbox.Task;
451549Srgrimes
461549Srgrimespublic class AutomaticModules extends ModuleTestBase {
47108599Sphk
48108599Sphk    public static void main(String... args) throws Exception {
491541Srgrimes        AutomaticModules t = new AutomaticModules();
501541Srgrimes        t.runTests();
51108602Sphk    }
52108602Sphk
53108602Sphk    @Test
54108602Sphk    public void testSimple(Path base) throws Exception {
55108602Sphk        Path legacySrc = base.resolve("legacy-src");
56108602Sphk        tb.writeJavaFiles(legacySrc,
57108602Sphk                          "package api; import java.awt.event.ActionListener; public abstract class Api implements ActionListener {}");
58108602Sphk        Path legacyClasses = base.resolve("legacy-classes");
59108602Sphk        Files.createDirectories(legacyClasses);
60108602Sphk
61108602Sphk        String log = new JavacTask(tb)
62108602Sphk                .options()
63108602Sphk                .outdir(legacyClasses)
64108602Sphk                .files(findJavaFiles(legacySrc))
65108602Sphk                .run()
66108602Sphk                .writeAll()
67108602Sphk                .getOutput(Task.OutputKind.DIRECT);
68108602Sphk
6967082Sdillon        if (!log.isEmpty()) {
7067082Sdillon            throw new Exception("unexpected output: " + log);
7167082Sdillon        }
721541Srgrimes
7333758Sdyson        Path modulePath = base.resolve("module-path");
741549Srgrimes
7533758Sdyson        Files.createDirectories(modulePath);
7633758Sdyson
7742957Sdillon        Path jar = modulePath.resolve("test-api-1.0.jar");
7842957Sdillon
7942957Sdillon        new JarTask(tb, jar)
8042957Sdillon          .baseDir(legacyClasses)
8142957Sdillon          .files("api/Api.class")
8242957Sdillon          .run();
8342957Sdillon
8442957Sdillon        Path moduleSrc = base.resolve("module-src");
8542957Sdillon        Path m1 = moduleSrc.resolve("m1");
8642957Sdillon
8742957Sdillon        Path classes = base.resolve("classes");
8842957Sdillon
8942957Sdillon        Files.createDirectories(classes);
9042957Sdillon
915455Sdg        tb.writeJavaFiles(m1,
9242957Sdillon                          "module m1 { requires test.api; requires java.desktop; }",
9342957Sdillon                          "package impl; public class Impl { public void e(api.Api api) { api.actionPerformed(null); } }");
9451339Sdillon
9542957Sdillon        new JavacTask(tb)
9642957Sdillon                .options("-modulesourcepath", moduleSrc.toString(), "-modulepath", modulePath.toString())
971541Srgrimes                .outdir(classes)
981541Srgrimes                .files(findJavaFiles(moduleSrc))
9910080Sbde                .run()
10011317Sdg                .writeAll();
10142957Sdillon    }
102102966Sbde
103107913Sdillon    @Test
104108600Sphk    public void testUnnamedModule(Path base) throws Exception {
105108600Sphk        Path legacySrc = base.resolve("legacy-src");
106108600Sphk        tb.writeJavaFiles(legacySrc,
107108600Sphk                          "package api; public abstract class Api { public void run(CharSequence str) { } private void run(base.Base base) { } }",
108108600Sphk                          "package base; public interface Base { public void run(); }");
109108600Sphk        Path legacyClasses = base.resolve("legacy-classes");
110108600Sphk        Files.createDirectories(legacyClasses);
111108600Sphk
112108600Sphk        String log = new JavacTask(tb)
11310080Sbde                .options()
11492727Salfred                .outdir(legacyClasses)
11592727Salfred                .files(findJavaFiles(legacySrc))
116107913Sdillon                .run()
11742957Sdillon                .writeAll()
11892727Salfred                .getOutput(Task.OutputKind.DIRECT);
11992727Salfred
12092727Salfred        if (!log.isEmpty()) {
12192727Salfred            throw new Exception("unexpected output: " + log);
12292727Salfred        }
12392727Salfred
12442957Sdillon        Path modulePath = base.resolve("module-path");
12542957Sdillon
12642957Sdillon        Files.createDirectories(modulePath);
12742957Sdillon
12842957Sdillon        Path apiJar = modulePath.resolve("test-api-1.0.jar");
12992727Salfred
13042957Sdillon        new JarTask(tb, apiJar)
13153338Speter          .baseDir(legacyClasses)
13253338Speter          .files("api/Api.class")
13392727Salfred          .run();
13453338Speter
13592029Seivind        Path baseJar = base.resolve("base.jar");
136108599Sphk
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("-modulesourcepath", moduleSrc.toString(), "-modulepath", modulePath.toString(), "-classpath", 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("-modulepath", 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("-modulepath", 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("-modulesourcepath", moduleSrc.toString(),
277                         "-modulepath", modulePath.toString(),
278                         "-addmods", "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("-modulesourcepath", moduleSrc.toString(),
295                         "-modulepath", 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