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