ModulesAndClassPathTest.java revision 3573:c4a18ee691c4
1/*
2 * Copyright (c) 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 Ensure named modules cannot refer to classpath types.
27 * @library /tools/lib
28 * @modules jdk.compiler/com.sun.tools.javac.api
29 *          jdk.compiler/com.sun.tools.javac.main
30 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
31 * @run main ModulesAndClassPathTest
32 */
33
34import java.io.File;
35import java.nio.file.Files;
36import java.nio.file.Path;
37import java.util.Arrays;
38import java.util.List;
39import java.util.Set;
40
41import javax.annotation.processing.AbstractProcessor;
42import javax.annotation.processing.RoundEnvironment;
43import javax.annotation.processing.SupportedAnnotationTypes;
44import javax.lang.model.element.TypeElement;
45
46import toolbox.JarTask;
47import toolbox.JavacTask;
48import toolbox.Task;
49
50public class ModulesAndClassPathTest extends ModuleTestBase {
51
52    public static void main(String... args) throws Exception {
53        new ModulesAndClassPathTest().runTests();
54    }
55
56    @Test
57    public void testModulesAndClassPath(Path base) throws Exception {
58        Path jar = prepareTestJar(base);
59
60        Path moduleSrc = base.resolve("module-src");
61        Path m1 = moduleSrc.resolve("m1");
62
63        Path classes = base.resolve("classes");
64
65        Files.createDirectories(classes);
66
67        tb.writeJavaFiles(m1,
68                          "module m1 { }",
69                          "package impl; public class Impl { api.Api api; }");
70
71        List<String> modLog = new JavacTask(tb)
72                                .options("--class-path", jar.toString(),
73                                         "-XDrawDiagnostics")
74                                .outdir(classes)
75                                .files(findJavaFiles(moduleSrc))
76                                .run(Task.Expect.FAIL)
77                                .writeAll()
78                                .getOutputLines(Task.OutputKind.DIRECT);
79
80        List<String> expected = Arrays.asList("Impl.java:1:38: compiler.err.doesnt.exist: api",
81                                              "1 error");
82
83        if (!expected.equals(modLog)) {
84            throw new Exception("unexpected output: " + modLog);
85        }
86
87        new JavacTask(tb)
88          .options("--class-path", jar.toString(),
89                   "--add-reads", "m1=ALL-UNNAMED")
90          .outdir(classes)
91          .files(findJavaFiles(moduleSrc))
92          .run()
93          .writeAll()
94          .getOutputLines(Task.OutputKind.DIRECT);
95
96        new JavacTask(tb)
97          .options("--class-path", jar.toString() + File.pathSeparator + System.getProperty("test.classes"),
98                   "--add-reads", "m1=ALL-UNNAMED",
99                   "-processor", ProcessorImpl.class.getName())
100          .outdir(classes)
101          .files(findJavaFiles(moduleSrc))
102          .run()
103          .writeAll()
104          .getOutputLines(Task.OutputKind.DIRECT);
105    }
106
107    @Test
108    public void testImplicitSourcePathModuleInfo(Path base) throws Exception {
109        Path jar = prepareTestJar(base);
110
111        Path moduleSrc = base.resolve("module-src");
112        Path m1 = moduleSrc.resolve("m1");
113
114        Path classes = base.resolve("classes");
115
116        Files.createDirectories(classes);
117
118        tb.writeJavaFiles(m1,
119                          "module m1 { }",
120                          "package impl; public class Impl { api.Api api; }");
121
122        List<String> modLog = new JavacTask(tb)
123                                .options("--class-path", jar.toString(),
124                                         "-sourcepath", m1.toString(),
125                                         "-XDrawDiagnostics")
126                                .outdir(classes)
127                                .files(m1.resolve("impl").resolve("Impl.java"))
128                                .run(Task.Expect.FAIL)
129                                .writeAll()
130                                .getOutputLines(Task.OutputKind.DIRECT);
131
132        List<String> expected = Arrays.asList("Impl.java:1:38: compiler.err.doesnt.exist: api",
133                                              "1 error");
134
135        if (!expected.equals(modLog)) {
136            throw new Exception("unexpected output: " + modLog);
137        }
138    }
139
140    @Test
141    public void testModuleInfoFromOutput(Path base) throws Exception {
142        Path jar = prepareTestJar(base);
143
144        Path moduleSrc = base.resolve("module-src");
145        Path m1 = moduleSrc.resolve("m1");
146
147        Path classes = base.resolve("classes");
148
149        Files.createDirectories(classes);
150
151        tb.writeJavaFiles(m1,
152                          "module m1 { }",
153                          "package impl; public class Impl { api.Api api; }");
154
155        new JavacTask(tb)
156          .options("--class-path", jar.toString(),
157                   "-XDrawDiagnostics")
158          .outdir(classes)
159          .files(m1.resolve("module-info.java"))
160          .run()
161          .writeAll()
162          .getOutputLines(Task.OutputKind.DIRECT);
163
164        List<String> modLog = new JavacTask(tb)
165                                .options("--class-path", jar.toString(),
166                                         "-XDrawDiagnostics")
167                                .outdir(classes)
168                                .files(m1.resolve("impl").resolve("Impl.java"))
169                                .run(Task.Expect.FAIL)
170                                .writeAll()
171                                .getOutputLines(Task.OutputKind.DIRECT);
172
173        List<String> expected = Arrays.asList("Impl.java:1:38: compiler.err.doesnt.exist: api",
174                                              "1 error");
175
176        if (!expected.equals(modLog)) {
177            throw new Exception("unexpected output: " + modLog);
178        }
179    }
180
181    private Path prepareTestJar(Path base) throws Exception {
182        Path legacySrc = base.resolve("legacy-src");
183        tb.writeJavaFiles(legacySrc,
184                          "package api; public abstract class Api {}");
185        Path legacyClasses = base.resolve("legacy-classes");
186        Files.createDirectories(legacyClasses);
187
188        String log = new JavacTask(tb)
189                .options()
190                .outdir(legacyClasses)
191                .files(findJavaFiles(legacySrc))
192                .run()
193                .writeAll()
194                .getOutput(Task.OutputKind.DIRECT);
195
196        if (!log.isEmpty()) {
197            throw new Exception("unexpected output: " + log);
198        }
199
200        Path lib = base.resolve("lib");
201
202        Files.createDirectories(lib);
203
204        Path jar = lib.resolve("test-api-1.0.jar");
205
206        new JarTask(tb, jar)
207          .baseDir(legacyClasses)
208          .files("api/Api.class")
209          .run();
210
211        return jar;
212    }
213
214    @SupportedAnnotationTypes("*")
215    public static class ProcessorImpl extends AbstractProcessor {
216        @Override
217        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
218            return false;
219        }
220    }
221
222    @Test
223    public void testClassOutputVisibleForIncrementalCompilation(Path base) throws Exception {
224        Path moduleSrc = base.resolve("module-src");
225        Path m1 = moduleSrc.resolve("m1");
226
227        Path classes = base.resolve("classes");
228
229        Files.createDirectories(classes);
230
231        tb.writeJavaFiles(m1,
232                          "module m1 { exports impl; }",
233                          "package impl; public class Impl { }",
234                          "package src; public class Src { }",
235                          "package test; public class TestCP extends impl.Impl { }",
236                          "package test; public class TestSP extends src.Src { }");
237
238        new JavacTask(tb)
239          .outdir(classes)
240          .files(m1.resolve("impl").resolve("Impl.java"))
241          .run()
242          .writeAll()
243          .getOutputLines(Task.OutputKind.DIRECT);
244
245        new JavacTask(tb)
246          .outdir(classes)
247          .files(m1.resolve("module-info.java"))
248          .run()
249          .writeAll()
250          .getOutputLines(Task.OutputKind.DIRECT);
251
252        new JavacTask(tb)
253          .outdir(classes)
254          .files(m1.resolve("test").resolve("TestCP.java"))
255          .run()
256          .writeAll()
257          .getOutputLines(Task.OutputKind.DIRECT);
258
259        new JavacTask(tb)
260          .options("-sourcepath", m1.toString())
261          .outdir(classes)
262          .files(m1.resolve("test").resolve("TestSP.java"))
263          .run()
264          .writeAll()
265          .getOutputLines(Task.OutputKind.DIRECT);
266    }
267}
268