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 multi-module mode compilation |
|
27 * @library /tools/lib |
|
28 * @modules |
|
29 * jdk.compiler/com.sun.tools.javac.api |
|
30 * jdk.compiler/com.sun.tools.javac.code |
|
31 * jdk.compiler/com.sun.tools.javac.main |
|
32 * jdk.compiler/com.sun.tools.javac.processing |
|
33 * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase |
|
34 * @run main XModuleTest |
|
35 */ |
|
36 |
|
37 import java.nio.file.Path; |
|
38 import java.util.Arrays; |
|
39 import java.util.List; |
|
40 import java.util.Set; |
|
41 |
|
42 import javax.annotation.processing.AbstractProcessor; |
|
43 import javax.annotation.processing.RoundEnvironment; |
|
44 import javax.annotation.processing.SupportedAnnotationTypes; |
|
45 import javax.lang.model.SourceVersion; |
|
46 import javax.lang.model.element.ModuleElement; |
|
47 import javax.lang.model.element.TypeElement; |
|
48 import javax.lang.model.util.Elements; |
|
49 |
|
50 import com.sun.tools.javac.code.Symtab; |
|
51 import com.sun.tools.javac.processing.JavacProcessingEnvironment; |
|
52 import toolbox.JavacTask; |
|
53 import toolbox.ModuleBuilder; |
|
54 import toolbox.Task; |
|
55 import toolbox.Task.Expect; |
|
56 |
|
57 public class XModuleTest extends ModuleTestBase { |
|
58 |
|
59 public static void main(String... args) throws Exception { |
|
60 new XModuleTest().runTests(); |
|
61 } |
|
62 |
|
63 @Test |
|
64 public void testCorrectXModule(Path base) throws Exception { |
|
65 //note: avoiding use of java.base, as that gets special handling on some places: |
|
66 Path src = base.resolve("src"); |
|
67 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }"); |
|
68 Path classes = base.resolve("classes"); |
|
69 tb.createDirectories(classes); |
|
70 |
|
71 String log = new JavacTask(tb) |
|
72 .options("-Xmodule:java.compiler") |
|
73 .outdir(classes) |
|
74 .files(findJavaFiles(src)) |
|
75 .run() |
|
76 .writeAll() |
|
77 .getOutput(Task.OutputKind.DIRECT); |
|
78 |
|
79 if (!log.isEmpty()) |
|
80 throw new Exception("expected output not found: " + log); |
|
81 } |
|
82 |
|
83 @Test |
|
84 public void testSourcePath(Path base) throws Exception { |
|
85 //note: avoiding use of java.base, as that gets special handling on some places: |
|
86 Path src = base.resolve("src"); |
|
87 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }", "package javax.lang.model.element; interface Other { }"); |
|
88 Path classes = base.resolve("classes"); |
|
89 tb.createDirectories(classes); |
|
90 |
|
91 String log = new JavacTask(tb) |
|
92 .options("-Xmodule:java.compiler", "-sourcepath", src.toString()) |
|
93 .outdir(classes) |
|
94 .files(src.resolve("javax/lang/model/element/Extra.java")) |
|
95 .run() |
|
96 .writeAll() |
|
97 .getOutput(Task.OutputKind.DIRECT); |
|
98 |
|
99 if (!log.isEmpty()) |
|
100 throw new Exception("expected output not found: " + log); |
|
101 } |
|
102 |
|
103 @Test |
|
104 public void testClassPath(Path base) throws Exception { |
|
105 Path cpSrc = base.resolve("cpSrc"); |
|
106 tb.writeJavaFiles(cpSrc, "package p; public interface Other { }"); |
|
107 Path cpClasses = base.resolve("cpClasses"); |
|
108 tb.createDirectories(cpClasses); |
|
109 |
|
110 String cpLog = new JavacTask(tb) |
|
111 .outdir(cpClasses) |
|
112 .files(findJavaFiles(cpSrc)) |
|
113 .run() |
|
114 .writeAll() |
|
115 .getOutput(Task.OutputKind.DIRECT); |
|
116 |
|
117 if (!cpLog.isEmpty()) |
|
118 throw new Exception("expected output not found: " + cpLog); |
|
119 |
|
120 Path src = base.resolve("src"); |
|
121 //note: avoiding use of java.base, as that gets special handling on some places: |
|
122 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, p.Other { }"); |
|
123 Path classes = base.resolve("classes"); |
|
124 tb.createDirectories(classes); |
|
125 |
|
126 List<String> log = new JavacTask(tb) |
|
127 .options("-Xmodule:java.compiler", |
|
128 "--class-path", cpClasses.toString(), |
|
129 "-XDrawDiagnostics") |
|
130 .outdir(classes) |
|
131 .files(src.resolve("javax/lang/model/element/Extra.java")) |
|
132 .run(Expect.FAIL) |
|
133 .writeAll() |
|
134 .getOutputLines(Task.OutputKind.DIRECT); |
|
135 |
|
136 List<String> expectedOut = Arrays.asList( |
|
137 "Extra.java:1:76: compiler.err.doesnt.exist: p", |
|
138 "1 error" |
|
139 ); |
|
140 |
|
141 if (!expectedOut.equals(log)) |
|
142 throw new Exception("expected output not found: " + log); |
|
143 } |
|
144 |
|
145 @Test |
|
146 public void testNoModuleInfoOnSourcePath(Path base) throws Exception { |
|
147 //note: avoiding use of java.base, as that gets special handling on some places: |
|
148 Path src = base.resolve("src"); |
|
149 tb.writeJavaFiles(src, |
|
150 "module java.compiler {}", |
|
151 "package javax.lang.model.element; public interface Extra { }"); |
|
152 Path classes = base.resolve("classes"); |
|
153 tb.createDirectories(classes); |
|
154 |
|
155 List<String> log = new JavacTask(tb) |
|
156 .options("-XDrawDiagnostics", "-Xmodule:java.compiler") |
|
157 .outdir(classes) |
|
158 .files(findJavaFiles(src)) |
|
159 .run(Task.Expect.FAIL) |
|
160 .writeAll() |
|
161 .getOutputLines(Task.OutputKind.DIRECT); |
|
162 |
|
163 List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.sourcepath", |
|
164 "1 error"); |
|
165 |
|
166 if (!expected.equals(log)) |
|
167 throw new Exception("expected output not found: " + log); |
|
168 } |
|
169 |
|
170 @Test |
|
171 public void testNoModuleInfoInClassOutput(Path base) throws Exception { |
|
172 //note: avoiding use of java.base, as that gets special handling on some places: |
|
173 Path srcMod = base.resolve("src-mod"); |
|
174 tb.writeJavaFiles(srcMod, |
|
175 "module mod {}"); |
|
176 Path classes = base.resolve("classes"); |
|
177 tb.createDirectories(classes); |
|
178 |
|
179 String logMod = new JavacTask(tb) |
|
180 .options() |
|
181 .outdir(classes) |
|
182 .files(findJavaFiles(srcMod)) |
|
183 .run() |
|
184 .writeAll() |
|
185 .getOutput(Task.OutputKind.DIRECT); |
|
186 |
|
187 if (!logMod.isEmpty()) |
|
188 throw new Exception("unexpected output found: " + logMod); |
|
189 |
|
190 Path src = base.resolve("src"); |
|
191 tb.writeJavaFiles(src, |
|
192 "package javax.lang.model.element; public interface Extra { }"); |
|
193 tb.createDirectories(classes); |
|
194 |
|
195 List<String> log = new JavacTask(tb) |
|
196 .options("-XDrawDiagnostics", "-Xmodule:java.compiler") |
|
197 .outdir(classes) |
|
198 .files(findJavaFiles(src)) |
|
199 .run(Task.Expect.FAIL) |
|
200 .writeAll() |
|
201 .getOutputLines(Task.OutputKind.DIRECT); |
|
202 |
|
203 List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.classpath", |
|
204 "1 error"); |
|
205 |
|
206 if (!expected.equals(log)) |
|
207 throw new Exception("expected output not found: " + log); |
|
208 } |
|
209 |
|
210 @Test |
|
211 public void testModuleSourcePathXModule(Path base) throws Exception { |
|
212 //note: avoiding use of java.base, as that gets special handling on some places: |
|
213 Path src = base.resolve("src"); |
|
214 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }"); |
|
215 Path classes = base.resolve("classes"); |
|
216 tb.createDirectories(classes); |
|
217 |
|
218 List<String> log = new JavacTask(tb) |
|
219 .options("-XDrawDiagnostics", "-Xmodule:java.compiler", "--module-source-path", src.toString()) |
|
220 .outdir(classes) |
|
221 .files(findJavaFiles(src)) |
|
222 .run(Task.Expect.FAIL) |
|
223 .writeAll() |
|
224 .getOutputLines(Task.OutputKind.DIRECT); |
|
225 |
|
226 List<String> expected = Arrays.asList("- compiler.err.xmodule.no.module.sourcepath"); |
|
227 |
|
228 if (!expected.equals(log)) |
|
229 throw new Exception("expected output not found: " + log); |
|
230 } |
|
231 |
|
232 @Test |
|
233 public void testXModuleTooMany(Path base) throws Exception { |
|
234 //note: avoiding use of java.base, as that gets special handling on some places: |
|
235 Path src = base.resolve("src"); |
|
236 tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }"); |
|
237 Path classes = base.resolve("classes"); |
|
238 tb.createDirectories(classes); |
|
239 |
|
240 List<String> log = new JavacTask(tb, Task.Mode.CMDLINE) |
|
241 .options("-XDrawDiagnostics", "-Xmodule:java.compiler", "-Xmodule:java.compiler") |
|
242 .outdir(classes) |
|
243 .files(findJavaFiles(src)) |
|
244 .run(Task.Expect.FAIL) |
|
245 .writeAll() |
|
246 .getOutputLines(Task.OutputKind.DIRECT); |
|
247 |
|
248 List<String> expected = Arrays.asList("javac: option -Xmodule: can only be specified once", |
|
249 "Usage: javac <options> <source files>", |
|
250 "use --help for a list of possible options"); |
|
251 |
|
252 if (!expected.equals(log)) |
|
253 throw new Exception("expected output not found: " + log); |
|
254 } |
|
255 |
|
256 @Test |
|
257 public void testWithModulePath(Path base) throws Exception { |
|
258 Path modSrc = base.resolve("modSrc"); |
|
259 Path modules = base.resolve("modules"); |
|
260 new ModuleBuilder(tb, "m1") |
|
261 .classes("package pkg1; public interface E { }") |
|
262 .build(modSrc, modules); |
|
263 |
|
264 Path src = base.resolve("src"); |
|
265 tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }"); |
|
266 |
|
267 new JavacTask(tb, Task.Mode.CMDLINE) |
|
268 .options("--module-path", modules.toString(), |
|
269 "-Xmodule:m1") |
|
270 .files(findJavaFiles(src)) |
|
271 .run() |
|
272 .writeAll(); |
|
273 |
|
274 //checks module bounds still exist |
|
275 new ModuleBuilder(tb, "m2") |
|
276 .classes("package pkg2; public interface D { }") |
|
277 .build(modSrc, modules); |
|
278 |
|
279 Path src2 = base.resolve("src2"); |
|
280 tb.writeJavaFiles(src2, "package p; interface A extends pkg2.D { }"); |
|
281 |
|
282 List<String> log = new JavacTask(tb, Task.Mode.CMDLINE) |
|
283 .options("-XDrawDiagnostics", |
|
284 "--module-path", modules.toString(), |
|
285 "-Xmodule:m1") |
|
286 .files(findJavaFiles(src2)) |
|
287 .run(Task.Expect.FAIL) |
|
288 .writeAll() |
|
289 .getOutputLines(Task.OutputKind.DIRECT); |
|
290 |
|
291 List<String> expected = Arrays.asList("A.java:1:32: compiler.err.package.not.visible: pkg2, (compiler.misc.not.def.access.does.not.read: m1, pkg2, m2)", |
|
292 "1 error"); |
|
293 |
|
294 if (!expected.equals(log)) |
|
295 throw new Exception("expected output not found: " + log); |
|
296 } |
|
297 |
|
298 @Test |
|
299 public void testWithUpgradeModulePath(Path base) throws Exception { |
|
300 Path modSrc = base.resolve("modSrc"); |
|
301 Path modules = base.resolve("modules"); |
|
302 new ModuleBuilder(tb, "m1") |
|
303 .classes("package pkg1; public interface E { }") |
|
304 .build(modSrc, modules); |
|
305 |
|
306 Path upgrSrc = base.resolve("upgradeSrc"); |
|
307 Path upgrade = base.resolve("upgrade"); |
|
308 new ModuleBuilder(tb, "m1") |
|
309 .classes("package pkg1; public interface D { }") |
|
310 .build(upgrSrc, upgrade); |
|
311 |
|
312 Path src = base.resolve("src"); |
|
313 tb.writeJavaFiles(src, "package p; interface A extends pkg1.D { }"); |
|
314 |
|
315 new JavacTask(tb, Task.Mode.CMDLINE) |
|
316 .options("--module-path", modules.toString(), |
|
317 "--upgrade-module-path", upgrade.toString(), |
|
318 "-Xmodule:m1") |
|
319 .files(findJavaFiles(src)) |
|
320 .run() |
|
321 .writeAll(); |
|
322 } |
|
323 |
|
324 @Test |
|
325 public void testUnnamedIsolation(Path base) throws Exception { |
|
326 //note: avoiding use of java.base, as that gets special handling on some places: |
|
327 Path sourcePath = base.resolve("source-path"); |
|
328 tb.writeJavaFiles(sourcePath, "package src; public class Src {}"); |
|
329 |
|
330 Path classPathSrc = base.resolve("class-path-src"); |
|
331 tb.writeJavaFiles(classPathSrc, "package cp; public class CP { }"); |
|
332 Path classPath = base.resolve("classPath"); |
|
333 tb.createDirectories(classPath); |
|
334 |
|
335 String cpLog = new JavacTask(tb) |
|
336 .outdir(classPath) |
|
337 .files(findJavaFiles(classPathSrc)) |
|
338 .run() |
|
339 .writeAll() |
|
340 .getOutput(Task.OutputKind.DIRECT); |
|
341 |
|
342 if (!cpLog.isEmpty()) |
|
343 throw new Exception("expected output not found: " + cpLog); |
|
344 |
|
345 Path modulePathSrc = base.resolve("module-path-src"); |
|
346 tb.writeJavaFiles(modulePathSrc, |
|
347 "module m {}", |
|
348 "package m; public class M {}"); |
|
349 Path modulePath = base.resolve("modulePath"); |
|
350 tb.createDirectories(modulePath.resolve("m")); |
|
351 |
|
352 String modLog = new JavacTask(tb) |
|
353 .outdir(modulePath.resolve("m")) |
|
354 .files(findJavaFiles(modulePathSrc)) |
|
355 .run() |
|
356 .writeAll() |
|
357 .getOutput(Task.OutputKind.DIRECT); |
|
358 |
|
359 if (!modLog.isEmpty()) |
|
360 throw new Exception("expected output not found: " + modLog); |
|
361 |
|
362 Path src = base.resolve("src"); |
|
363 tb.writeJavaFiles(src, "package m; public class Extra { }"); |
|
364 Path classes = base.resolve("classes"); |
|
365 tb.createDirectories(classes); |
|
366 |
|
367 String log = new JavacTask(tb) |
|
368 .options("-Xmodule:m", |
|
369 "--class-path", classPath.toString(), |
|
370 "--source-path", sourcePath.toString(), |
|
371 "--module-path", modulePath.toString(), |
|
372 "--processor-path", System.getProperty("test.classes"), |
|
373 "-XDaccessInternalAPI=true", |
|
374 "-processor", CheckModuleContentProcessing.class.getName()) |
|
375 .outdir(classes) |
|
376 .files(findJavaFiles(sourcePath)) |
|
377 .run() |
|
378 .writeAll() |
|
379 .getOutput(Task.OutputKind.DIRECT); |
|
380 |
|
381 if (!log.isEmpty()) |
|
382 throw new Exception("expected output not found: " + log); |
|
383 } |
|
384 |
|
385 @SupportedAnnotationTypes("*") |
|
386 public static final class CheckModuleContentProcessing extends AbstractProcessor { |
|
387 |
|
388 @Override |
|
389 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
|
390 Symtab syms = Symtab.instance(((JavacProcessingEnvironment) processingEnv).getContext()); |
|
391 Elements elements = processingEnv.getElementUtils(); |
|
392 ModuleElement unnamedModule = syms.unnamedModule; |
|
393 ModuleElement mModule = elements.getModuleElement("m"); |
|
394 |
|
395 assertNonNull("mModule found", mModule); |
|
396 assertNonNull("src.Src from m", elements.getTypeElement(mModule, "src.Src")); |
|
397 assertNull("cp.CP not from m", elements.getTypeElement(mModule, "cp.CP")); |
|
398 assertNull("src.Src not from unnamed", elements.getTypeElement(unnamedModule, "src.Src")); |
|
399 assertNonNull("cp.CP from unnamed", elements.getTypeElement(unnamedModule, "cp.CP")); |
|
400 |
|
401 return false; |
|
402 } |
|
403 |
|
404 @Override |
|
405 public SourceVersion getSupportedSourceVersion() { |
|
406 return SourceVersion.latest(); |
|
407 } |
|
408 |
|
409 private static void assertNonNull(String msg, Object val) { |
|
410 if (val == null) { |
|
411 throw new AssertionError(msg); |
|
412 } |
|
413 } |
|
414 |
|
415 private static void assertNull(String msg, Object val) { |
|
416 if (val != null) { |
|
417 throw new AssertionError(msg); |
|
418 } |
|
419 } |
|
420 } |
|
421 |
|
422 } |
|