ModuleSourcePathTest.java revision 3618:64182008b2d0
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 * @summary tests for --module-source-path
27 * @library /tools/lib
28 * @modules
29 *      jdk.compiler/com.sun.tools.javac.api
30 *      jdk.compiler/com.sun.tools.javac.main
31 * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
32 * @run main ModuleSourcePathTest
33 */
34
35import java.io.File;
36import java.io.IOException;
37import java.nio.file.Files;
38import java.nio.file.Path;
39import java.nio.file.Paths;
40import java.util.Arrays;
41import java.util.List;
42import java.util.stream.Collectors;
43import java.util.stream.Stream;
44
45import toolbox.JavacTask;
46import toolbox.Task;
47import toolbox.ToolBox;
48
49public class ModuleSourcePathTest extends ModuleTestBase {
50
51    public static final char PATH_SEP = File.pathSeparatorChar;
52
53    public static void main(String... args) throws Exception {
54        ModuleSourcePathTest t = new ModuleSourcePathTest();
55        t.runTests();
56    }
57
58    @Test
59    public void testSourcePathConflict(Path base) throws Exception {
60        Path sp = base.resolve("src");
61        Path msp = base.resolve("srcmodules");
62
63        String log = new JavacTask(tb, Task.Mode.CMDLINE)
64                .options("-XDrawDiagnostics",
65                        "--source-path", sp.toString().replace('/', File.separatorChar),
66                        "--module-source-path", msp.toString().replace('/', File.separatorChar),
67                        "dummyClass")
68                .run(Task.Expect.FAIL)
69                .writeAll()
70                .getOutput(Task.OutputKind.DIRECT);
71
72        if (!log.contains("cannot specify both --source-path and --module-source-path"))
73            throw new Exception("expected diagnostic not found");
74    }
75
76    @Test
77    public void testUnnormalizedPath1(Path base) throws Exception {
78        Path src = base.resolve("src");
79        Path src_m1 = src.resolve("m1");
80        tb.writeJavaFiles(src_m1, "module m1 { }");
81        Path modules = base.resolve("modules");
82        Files.createDirectories(modules);
83
84        new JavacTask(tb, Task.Mode.CMDLINE)
85                .options("-XDrawDiagnostics",
86                        "--module-source-path", src.toString())
87                .outdir(modules)
88                .files(prefixAll(findJavaFiles(src), Paths.get("./")))
89                .run()
90                .writeAll();
91    }
92
93    @Test
94    public void testUnnormalizedPath2(Path base) throws Exception {
95        Path src = base.resolve("src");
96        Path src_m1 = src.resolve("m1");
97        tb.writeJavaFiles(src_m1, "module m1 { }");
98        Path modules = base.resolve("modules");
99        Files.createDirectories(modules);
100
101        new JavacTask(tb, Task.Mode.CMDLINE)
102                .options("-XDrawDiagnostics",
103                        "--module-source-path", "./" + src)
104                .outdir(modules)
105                .files(findJavaFiles(src))
106                .run()
107                .writeAll();
108    }
109
110    private Path[] prefixAll(Path[] paths, Path prefix) {
111        return Stream.of(paths)
112                .map(prefix::resolve)
113                .collect(Collectors.toList())
114                .toArray(new Path[paths.length]);
115    }
116
117    @Test
118    public void regularBraces(Path base) throws Exception {
119        generateModules(base, "src1", "src2/inner_dir");
120
121        final Path modules = base.resolve("modules");
122        tb.createDirectories(modules);
123
124        new JavacTask(tb, Task.Mode.CMDLINE)
125                .options("-XDrawDiagnostics",
126                        "--module-source-path", base + "/{src1,src2/inner_dir}")
127                .files(base.resolve("src1/m0/pkg0/A.java"), base.resolve("src2/inner_dir/m1/pkg1/A.java"))
128                .outdir(modules)
129                .run()
130                .writeAll();
131
132        checkFiles(modules.resolve("m0/pkg0/A.class"),
133                modules.resolve("m1/pkg1/A.class"),
134                modules.resolve("m0/module-info.class"),
135                modules.resolve("m1/module-info.class"));
136    }
137
138    @Test
139    public void mismatchedBraces(Path base) throws Exception {
140        final List<String> sourcePaths = Arrays.asList(
141                "{",
142                "}",
143                "}{",
144                "./}",
145                ".././{./",
146                "src{}}",
147                "{{}{}}{}}",
148                "src/{a,b}/{",
149                "src/{a,{,{}}",
150                "{.,..{}/src",
151                "*}{",
152                "{}*}"
153        );
154        for (String sourcepath : sourcePaths) {
155            String log = new JavacTask(tb, Task.Mode.CMDLINE)
156                    .options("-XDrawDiagnostics",
157                            "--module-source-path", sourcepath.replace('/', File.separatorChar))
158                    .run(Task.Expect.FAIL)
159                    .writeAll()
160                    .getOutput(Task.OutputKind.DIRECT);
161
162            if (!log.contains("- compiler.err.illegal.argument.for.option: --module-source-path, mismatched braces"))
163                throw new Exception("expected output for path [" + sourcepath + "] not found");
164        }
165    }
166
167    @Test
168    public void deepBraces(Path base) throws Exception {
169        String[] modulePaths = {"src/src1",
170                "src/src2",
171                "src/src3",
172                "src/srcB/src1",
173                "src/srcB/src2/srcXX",
174                "src/srcB/src2/srcXY",
175                "src/srcC/src1",
176                "src/srcC/src2/srcXX",
177                "src/srcC/src2/srcXY"};
178        generateModules(base, modulePaths);
179
180        final Path modules = base.resolve("modules");
181        tb.createDirectories(modules);
182
183        new JavacTask(tb, Task.Mode.CMDLINE)
184                .options("-XDrawDiagnostics",
185                        "--module-source-path",
186                        base + "/{src/{{src1,src2,src3},{srcB,srcC}/{src1,src2/srcX{X,Y}/}},.}"
187                                .replace('/', File.separatorChar))
188                .files(findJavaFiles(base.resolve(modulePaths[modulePaths.length - 1])))
189                .outdir(modules)
190                .run()
191                .writeAll();
192
193        for (int i = 0; i < modulePaths.length; i++) {
194            checkFiles(modules.resolve("m" + i + "/module-info.class"));
195        }
196        checkFiles(modules.resolve("m8/pkg8/A.class"));
197    }
198
199    @Test
200    public void fileInPath(Path base) throws Exception {
201        Path src = base.resolve("src");
202        tb.writeJavaFiles(src.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
203        tb.writeFile(base.resolve("dummy.txt"), "");
204
205        final Path modules = base.resolve("modules");
206        tb.createDirectories(modules);
207
208        new JavacTask(tb, Task.Mode.CMDLINE)
209                .options("-XDrawDiagnostics",
210                        "--module-source-path", base + "/{dummy.txt,src}")
211                .files(src.resolve("kettle$/electric/Heater.java"))
212                .outdir(modules)
213                .run()
214                .writeAll();
215
216        checkFiles(modules.resolve("kettle$/electric/Heater.class"));
217        checkFiles(modules.resolve("kettle$/module-info.class"));
218    }
219
220    @Test
221    public void noAlternative(Path base) throws Exception {
222        Path src = base.resolve("src");
223        tb.writeJavaFiles(src.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
224
225        final Path modules = base.resolve("modules");
226        tb.createDirectories(modules);
227
228        new JavacTask(tb, Task.Mode.CMDLINE)
229                .options("-XDrawDiagnostics",
230                        "--module-source-path", base + "/{src}")
231                .files(src.resolve("kettle$/electric/Heater.java"))
232                .outdir(modules)
233                .run()
234                .writeAll();
235
236        checkFiles(modules.resolve("kettle$/electric/Heater.class"));
237        checkFiles(modules.resolve("kettle$/module-info.class"));
238    }
239
240    @Test
241    public void noChoice(Path base) throws Exception {
242        tb.writeJavaFiles(base.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
243
244        final Path modules = base.resolve("modules");
245        tb.createDirectories(modules);
246
247        new JavacTask(tb, Task.Mode.CMDLINE)
248                .options("-XDrawDiagnostics",
249                        "--module-source-path", base + "/{}")
250                .files(base.resolve("kettle$/electric/Heater.java"))
251                .outdir(modules)
252                .run()
253                .writeAll();
254
255        checkFiles(modules.resolve("kettle$/electric/Heater.class"));
256        checkFiles(modules.resolve("kettle$/module-info.class"));
257    }
258
259    @Test
260    public void nestedModules(Path src) throws Exception {
261        Path carModule = src.resolve("car");
262        tb.writeJavaFiles(carModule, "module car { }", "package light; class Headlight { }");
263        tb.writeJavaFiles(carModule.resolve("engine"), "module engine { }", "package flat; class Piston { }");
264
265        final Path modules = src.resolve("modules");
266        tb.createDirectories(modules);
267
268        new JavacTask(tb, Task.Mode.CMDLINE)
269                .options("-XDrawDiagnostics",
270                        "--module-source-path", "{" + src + "," + src + "/car}")
271                .files(findJavaFiles(src))
272                .outdir(modules)
273                .run()
274                .writeAll();
275        checkFiles(modules.resolve("car/light/Headlight.class"));
276        checkFiles(modules.resolve("engine/flat/Piston.class"));
277    }
278
279    @Test
280    public void relativePaths(Path base) throws Exception {
281        Path src = base.resolve("src");
282        tb.writeJavaFiles(src.resolve("kettle"), "module kettle { }", "package electric; class Heater { }");
283
284        final Path modules = base.resolve("modules");
285        tb.createDirectories(modules);
286
287        new JavacTask(tb, Task.Mode.CMDLINE)
288                .options("-XDrawDiagnostics",
289                        "--module-source-path", base + "/src/./../src")
290                .files(src.resolve("kettle/electric/Heater.java"))
291                .outdir(modules)
292                .run()
293                .writeAll();
294        checkFiles(modules.resolve("kettle/electric/Heater.class"));
295        checkFiles(modules.resolve("kettle/module-info.class"));
296    }
297
298    @Test
299    public void duplicatePaths(Path base) throws Exception {
300        Path src = base.resolve("src");
301        tb.writeJavaFiles(src.resolve("m1"), "module m1 { }", "package a; class A { }");
302
303        final Path modules = base.resolve("modules");
304        tb.createDirectories(modules);
305
306        new JavacTask(tb, Task.Mode.CMDLINE)
307                .options("-XDrawDiagnostics",
308                        "--module-source-path", base + "/{src,src,src}")
309                .files(src.resolve("m1/a/A.java"))
310                .outdir(modules)
311                .run()
312                .writeAll();
313
314        checkFiles(modules.resolve("m1/module-info.class"));
315    }
316
317    @Test
318    public void notExistentPaths(Path base) throws Exception {
319        tb.writeJavaFiles(base.resolve("m1"), "module m1 { requires m0; }", "package a; class A { }");
320
321        final Path modules = base.resolve("modules");
322        tb.createDirectories(modules);
323
324        String log = new JavacTask(tb, Task.Mode.CMDLINE)
325                .options("-XDrawDiagnostics",
326                        "--module-source-path", base + "/not_exist" + PATH_SEP + base + "/{not_exist,}")
327                .files(base.resolve("m1/a/A.java"))
328                .outdir(modules)
329                .run(Task.Expect.FAIL)
330                .writeAll()
331                .getOutput(Task.OutputKind.DIRECT);
332        if (!log.contains("compiler.err.module.not.found: m0"))
333            throw new Exception("expected output for not existent module source path not found");
334    }
335
336    @Test
337    public void notExistentPathShouldBeSkipped(Path base) throws Exception {
338        tb.writeJavaFiles(base.resolve("m1"), "module m1 { }", "package a; class A { }");
339
340        final Path modules = base.resolve("modules");
341        tb.createDirectories(modules);
342
343        new JavacTask(tb, Task.Mode.CMDLINE)
344                .options("-XDrawDiagnostics",
345                        "--module-source-path", base + "{/not_exist,/}")
346                .files(base.resolve("m1/a/A.java"))
347                .outdir(modules)
348                .run()
349                .writeAll();
350
351        checkFiles(modules.resolve("m1/module-info.class"));
352    }
353
354    @Test
355    public void commas(Path base) throws Exception {
356        Path src = base.resolve("src");
357        tb.writeJavaFiles(src.resolve("m1"), "module m1 { }", "package a; class A { }");
358
359        final Path modules = base.resolve("modules");
360        tb.createDirectories(modules);
361
362        new JavacTask(tb, Task.Mode.CMDLINE)
363                .options("-XDrawDiagnostics",
364                        "--module-source-path", base + "/{,{,,,,src,,,}}")
365                .files(src.resolve("m1/a/A.java"))
366                .outdir(modules)
367                .run()
368                .writeAll();
369
370        checkFiles(modules.resolve("m1/module-info.class"));
371    }
372
373    @Test
374    public void asterisk(Path base) throws Exception {
375        tb.writeJavaFiles(base.resolve("kettle").resolve("classes"), "module kettle { }",
376                "package electric; class Heater { }");
377
378        final Path modules = base.resolve("modules");
379        tb.createDirectories(modules);
380
381        new JavacTask(tb, Task.Mode.CMDLINE)
382                .options("-XDrawDiagnostics",
383                        "--module-source-path", base + "/*/classes/")
384                .files(base.resolve("kettle/classes/electric/Heater.java"))
385                .outdir(modules)
386                .run()
387                .writeAll();
388
389        checkFiles(modules.resolve("kettle/electric/Heater.class"));
390        checkFiles(modules.resolve("kettle/module-info.class"));
391    }
392
393    @Test
394    public void asteriskInDifferentSets(Path base) throws Exception {
395        Path src = base.resolve("src");
396        final Path module = src.resolve("kettle");
397        tb.writeJavaFiles(module.resolve("classes"), "module kettle { }", "package electric; class Heater { }");
398        tb.writeJavaFiles(module.resolve("gensrc"), "package model; class Java { }");
399        tb.writeJavaFiles(module.resolve("special/classes"), "package gas; class Heater { }");
400
401        final Path modules = base.resolve("modules");
402        tb.createDirectories(modules);
403
404        new JavacTask(tb, Task.Mode.CMDLINE)
405                .options("-XDrawDiagnostics",
406                        "--module-source-path", src + "{/*/gensrc/,/*/classes/}" + PATH_SEP
407                                + src + "/*/special/classes")
408                .files(findJavaFiles(src))
409                .outdir(modules)
410                .run()
411                .writeAll();
412
413        checkFiles(modules.resolve("kettle/electric/Heater.class"));
414        checkFiles(modules.resolve("kettle/gas/Heater.class"));
415        checkFiles(modules.resolve("kettle/model/Java.class"));
416        checkFiles(modules.resolve("kettle/module-info.class"));
417    }
418
419    @Test
420    public void asteriskIllegalUse(Path base) throws Exception {
421        final List<String> sourcePaths = Arrays.asList(
422                "*",
423                "**",
424                "***",
425                "*.*",
426                ".*",
427                "*.",
428                "src/*/*/",
429                "{*,*}",
430                "src/module*/"
431        );
432        for (String sourcepath : sourcePaths) {
433            String log = new JavacTask(tb, Task.Mode.CMDLINE)
434                    .options("-XDrawDiagnostics",
435                            "--module-source-path", sourcepath.replace('/', File.separatorChar))
436                    .run(Task.Expect.FAIL)
437                    .writeAll()
438                    .getOutput(Task.OutputKind.DIRECT);
439
440            if (!log.contains("- compiler.err.illegal.argument.for.option: --module-source-path, illegal use of *"))
441                throw new Exception("expected output for path [" + sourcepath + "] not found");
442        }
443    }
444
445    private void generateModules(Path base, String... paths) throws IOException {
446        for (int i = 0; i < paths.length; i++) {
447            String moduleName = "m" + i;
448            String dependency = i > 0 ? "requires m" + (i - 1) + ";" : "";
449            tb.writeJavaFiles(base.resolve(paths[i]).resolve(moduleName),
450                    "module " + moduleName + " { " + dependency + " }",
451                    "package pkg" + i + "; class A { }");
452        }
453    }
454
455    private void checkFiles(Path... files) throws Exception {
456        for (Path file : files) {
457            if (!Files.exists(file)) {
458                throw new Exception("File not exists: " + file);
459            }
460        }
461    }
462}
463