EdgeCases.java revision 3923:923a093b4bd8
1/* 2 * Copyright (c) 2015, 2017, 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 * @bug 8154283 8167320 8171098 8172809 8173068 8173117 27 * @summary tests for multi-module mode compilation 28 * @library /tools/lib 29 * @modules 30 * jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.code 32 * jdk.compiler/com.sun.tools.javac.main 33 * jdk.compiler/com.sun.tools.javac.processing 34 * jdk.compiler/com.sun.tools.javac.util 35 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase 36 * @run main EdgeCases 37 */ 38 39import java.io.Writer; 40import java.nio.file.Files; 41import java.nio.file.Path; 42import java.nio.file.Paths; 43import java.util.Arrays; 44import java.util.HashSet; 45import java.util.List; 46import java.util.Objects; 47import java.util.Set; 48 49import javax.annotation.processing.AbstractProcessor; 50import javax.annotation.processing.RoundEnvironment; 51import javax.annotation.processing.SupportedAnnotationTypes; 52import javax.annotation.processing.SupportedOptions; 53import javax.lang.model.SourceVersion; 54import javax.lang.model.element.Element; 55import javax.lang.model.element.ModuleElement; 56import javax.lang.model.element.ModuleElement.RequiresDirective; 57import javax.lang.model.element.PackageElement; 58import javax.lang.model.element.TypeElement; 59import javax.lang.model.util.ElementFilter; 60import javax.lang.model.util.Elements; 61import javax.tools.JavaCompiler; 62import javax.tools.JavaFileObject; 63import javax.tools.StandardJavaFileManager; 64import javax.tools.ToolProvider; 65 66import com.sun.source.tree.CompilationUnitTree; 67//import com.sun.source.util.JavacTask; // conflicts with toolbox.JavacTask 68import com.sun.tools.javac.api.JavacTaskImpl; 69import com.sun.tools.javac.code.Symbol.ModuleSymbol; 70import com.sun.tools.javac.code.Symbol.PackageSymbol; 71import com.sun.tools.javac.code.Symtab; 72import com.sun.tools.javac.processing.JavacProcessingEnvironment; 73import com.sun.tools.javac.util.Context; 74 75import toolbox.JarTask; 76import toolbox.JavacTask; 77import toolbox.Task; 78import toolbox.Task.Expect; 79import toolbox.Task.OutputKind; 80 81public class EdgeCases extends ModuleTestBase { 82 83 public static void main(String... args) throws Exception { 84 new EdgeCases().runTests(); 85 } 86 87 @Test 88 public void testAddExportUndefinedModule(Path base) throws Exception { 89 Path src = base.resolve("src"); 90 tb.writeJavaFiles(src, "package test; import undefPackage.Any; public class Test {}"); 91 Path classes = base.resolve("classes"); 92 tb.createDirectories(classes); 93 94 List<String> log = new JavacTask(tb) 95 .options("--add-exports", "undefModule/undefPackage=ALL-UNNAMED", 96 "-XDrawDiagnostics") 97 .outdir(classes) 98 .files(findJavaFiles(src)) 99 .run(Task.Expect.FAIL) 100 .writeAll() 101 .getOutputLines(Task.OutputKind.DIRECT); 102 103 List<String> expected = Arrays.asList("- compiler.warn.module.for.option.not.found: --add-exports, undefModule", 104 "Test.java:1:34: compiler.err.doesnt.exist: undefPackage", 105 "1 error", "1 warning"); 106 107 if (!expected.equals(log)) 108 throw new Exception("expected output not found: " + log); 109 } 110 111 @Test 112 public void testModuleSymbolOutterMostClass(Path base) throws Exception { 113 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 114 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 115 Path moduleSrc = base.resolve("module-src"); 116 Path m1 = moduleSrc.resolve("m1x"); 117 118 tb.writeJavaFiles(m1, "module m1x { }"); 119 120 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(moduleSrc)); 121 com.sun.source.util.JavacTask task = 122 (com.sun.source.util.JavacTask) compiler.getTask(null, fm, null, null, null, files); 123 124 task.analyze(); 125 126 ModuleSymbol msym = (ModuleSymbol) task.getElements().getModuleElement("m1x"); 127 128 msym.outermostClass(); 129 } 130 } 131 132 @Test 133 public void testParseEnterAnalyze(Path base) throws Exception { 134 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 135 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 136 Path moduleSrc = base.resolve("module-src"); 137 Path m1 = moduleSrc.resolve("m1x"); 138 139 tb.writeJavaFiles(m1, "module m1x { }", 140 "package p;", 141 "package p; class T { }"); 142 143 Path classes = base.resolve("classes"); 144 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(moduleSrc)); 145 List<String> options = Arrays.asList("-d", classes.toString(), "-Xpkginfo:always"); 146 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fm, null, options, null, files); 147 148 Iterable<? extends CompilationUnitTree> parsed = task.parse(); 149 Iterable<? extends Element> entered = task.enter(parsed); 150 Iterable<? extends Element> analyzed = task.analyze(entered); 151 Iterable<? extends JavaFileObject> generatedFiles = task.generate(analyzed); 152 153 Set<String> generated = new HashSet<>(); 154 155 for (JavaFileObject jfo : generatedFiles) { 156 generated.add(jfo.getName()); 157 } 158 159 Set<String> expected = new HashSet<>( 160 Arrays.asList(Paths.get("testParseEnterAnalyze", "classes", "p", "package-info.class").toString(), 161 Paths.get("testParseEnterAnalyze", "classes", "module-info.class").toString(), 162 Paths.get("testParseEnterAnalyze", "classes", "p", "T.class").toString()) 163 ); 164 165 if (!Objects.equals(expected, generated)) 166 throw new AssertionError("Incorrect generated files: " + generated); 167 } 168 } 169 170 @Test 171 public void testModuleImplicitModuleBoundaries(Path base) throws Exception { 172 Path src = base.resolve("src"); 173 Path src_m1 = src.resolve("m1x"); 174 tb.writeJavaFiles(src_m1, 175 "module m1x { exports api1; }", 176 "package api1; public class Api1 { public void call() { } }"); 177 Path src_m2 = src.resolve("m2x"); 178 tb.writeJavaFiles(src_m2, 179 "module m2x { requires m1x; exports api2; }", 180 "package api2; public class Api2 { public static api1.Api1 get() { return null; } }"); 181 Path src_m3 = src.resolve("m3x"); 182 tb.writeJavaFiles(src_m3, 183 "module m3x { requires m2x; }", 184 "package test; public class Test { { api2.Api2.get().call(); api2.Api2.get().toString(); } }"); 185 Path classes = base.resolve("classes"); 186 tb.createDirectories(classes); 187 188 String log = new JavacTask(tb) 189 .options("-XDrawDiagnostics", 190 "--module-source-path", src.toString()) 191 .outdir(classes) 192 .files(findJavaFiles(src)) 193 .run(Task.Expect.FAIL) 194 .writeAll() 195 .getOutput(Task.OutputKind.DIRECT); 196 197 if (!log.contains("Test.java:1:52: compiler.err.not.def.access.class.intf.cant.access.reason: call(), api1.Api1, api1, (compiler.misc.not.def.access.does.not.read: m3x, api1, m1x)") || 198 !log.contains("Test.java:1:76: compiler.err.not.def.access.class.intf.cant.access: toString(), java.lang.Object")) 199 throw new Exception("expected output not found"); 200 } 201 202 @Test 203 public void testAssignClassToAutomaticModule(Path base) throws Exception { 204 //check that if a ClassSymbol belongs to an automatic module, it is properly assigned and not 205 //duplicated when being accessed through a classfile. 206 Path automaticSrc = base.resolve("automaticSrc"); 207 tb.writeJavaFiles(automaticSrc, "package api1; public class Api1 {}"); 208 Path automaticClasses = base.resolve("automaticClasses"); 209 tb.createDirectories(automaticClasses); 210 211 String automaticLog = new JavacTask(tb) 212 .outdir(automaticClasses) 213 .files(findJavaFiles(automaticSrc)) 214 .run() 215 .writeAll() 216 .getOutput(Task.OutputKind.DIRECT); 217 218 if (!automaticLog.isEmpty()) 219 throw new Exception("expected output not found: " + automaticLog); 220 221 Path modulePath = base.resolve("module-path"); 222 223 Files.createDirectories(modulePath); 224 225 Path automaticJar = modulePath.resolve("a-1.0.jar"); 226 227 new JarTask(tb, automaticJar) 228 .baseDir(automaticClasses) 229 .files("api1/Api1.class") 230 .run(); 231 232 Path src = base.resolve("src"); 233 Path src_m2 = src.resolve("m2x"); 234 tb.writeJavaFiles(src_m2, 235 "module m2x { requires a; exports api2; }", 236 "package api2; public class Api2 { public static api1.Api1 get() { return null; } }"); 237 Path src_m3 = src.resolve("m3x"); 238 tb.writeJavaFiles(src_m3, 239 "module m3x { requires a; requires m2x; }", 240 "package test; public class Test { { api2.Api2.get(); api1.Api1 a1; } }"); 241 Path classes = base.resolve("classes"); 242 tb.createDirectories(classes); 243 244 new JavacTask(tb) 245 .options("--module-path", modulePath.toString(), 246 "--module-source-path", src.toString()) 247 .outdir(classes) 248 .files(findJavaFiles(src_m2)) 249 .run() 250 .writeAll(); 251 252 new JavacTask(tb) 253 .options("--module-path", modulePath.toString(), 254 "--module-source-path", src.toString()) 255 .outdir(classes) 256 .files(findJavaFiles(src_m3)) 257 .run() 258 .writeAll(); 259 } 260 261 @Test 262 public void testEmptyImplicitModuleInfo(Path base) throws Exception { 263 Path src = base.resolve("src"); 264 Path src_m1 = src.resolve("m1x"); 265 Files.createDirectories(src_m1); 266 try (Writer w = Files.newBufferedWriter(src_m1.resolve("module-info.java"))) {} 267 tb.writeJavaFiles(src_m1, 268 "package test; public class Test {}"); 269 Path classes = base.resolve("classes"); 270 tb.createDirectories(classes); 271 272 new JavacTask(tb) 273 .options("--source-path", src_m1.toString(), 274 "-XDrawDiagnostics") 275 .outdir(classes) 276 .files(findJavaFiles(src_m1.resolve("test"))) 277 .run(Task.Expect.FAIL) 278 .writeAll(); 279 280 tb.writeJavaFiles(src_m1, 281 "module m1x {}"); 282 283 new JavacTask(tb) 284 .options("--source-path", src_m1.toString()) 285 .outdir(classes) 286 .files(findJavaFiles(src_m1.resolve("test"))) 287 .run() 288 .writeAll(); 289 290 } 291 292 @Test 293 public void testClassPackageClash(Path base) throws Exception { 294 Path src = base.resolve("src"); 295 Path src_m1 = src.resolve("m1x"); 296 tb.writeJavaFiles(src_m1, 297 "module m1x { exports test.m1x; }", 298 "package test.m1x;\n" + 299 "public class Test {}\n"); 300 Path src_m2 = src.resolve("m2x"); 301 tb.writeJavaFiles(src_m2, 302 "module m2x { requires m1x; }", 303 "package test;\n" + 304 "public class m1x {}\n"); 305 Path classes = base.resolve("classes"); 306 tb.createDirectories(classes); 307 308 List<String> log = new JavacTask(tb) 309 .options("--module-source-path", src.toString(), 310 "-XDrawDiagnostics") 311 .outdir(classes) 312 .files(findJavaFiles(src)) 313 .run(Task.Expect.FAIL) 314 .writeAll() 315 .getOutputLines(Task.OutputKind.DIRECT); 316 317 List<String> expected = Arrays.asList( 318 "m1x.java:2:8: compiler.err.clash.with.pkg.of.same.name: kindname.class, test.m1x", 319 "1 error" 320 ); 321 322 if (!expected.equals(log)) { 323 throw new IllegalStateException(log.toString()); 324 } 325 } 326 327 @Test 328 public void testImplicitJavaBase(Path base) throws Exception { 329 Path src = base.resolve("src"); 330 Path src_java_base = src.resolve("java.base"); 331 Files.createDirectories(src_java_base); 332 tb.writeJavaFiles(src_java_base, "module java.base { exports java.lang; }"); 333 tb.writeJavaFiles(src_java_base, 334 "package java.lang; public class Object {}"); 335 Path classes = base.resolve("classes"); 336 tb.createDirectories(classes); 337 338 //module-info from source: 339 new JavacTask(tb) 340 .options("-sourcepath", src_java_base.toString()) 341 .outdir(classes) 342 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java"))) 343 .run() 344 .writeAll(); 345 346 //module-info from class: 347 if (!Files.exists(classes.resolve("module-info.class"))) { 348 throw new AssertionError("module-info.class not created!"); 349 } 350 351 new JavacTask(tb) 352 .outdir(classes) 353 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java"))) 354 .run() 355 .writeAll(); 356 357 //broken module-info.class: 358 Files.newOutputStream(classes.resolve("module-info.class")).close(); 359 360 List<String> log = new JavacTask(tb) 361 .options("-XDrawDiagnostics") 362 .outdir(classes) 363 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java"))) 364 .run(Expect.FAIL) 365 .writeAll() 366 .getOutputLines(OutputKind.DIRECT); 367 368 List<String> expected = Arrays.asList( 369 "- compiler.err.cant.access: <error>.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.illegal.start.of.class.file))", 370 "1 error"); 371 372 if (!expected.equals(log)) { 373 throw new AssertionError("Unexpected output: " + log); 374 } 375 376 //broken module-info.java: 377 Files.delete(classes.resolve("module-info.class")); 378 379 try (Writer out = Files.newBufferedWriter(src_java_base.resolve("module-info.java"))) { 380 out.write("class Broken {}"); 381 } 382 383 log = new JavacTask(tb) 384 .options("-sourcepath", src_java_base.toString(), 385 "-XDrawDiagnostics") 386 .outdir(classes) 387 .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java"))) 388 .run(Expect.FAIL) 389 .writeAll() 390 .getOutputLines(OutputKind.DIRECT); 391 392 expected = Arrays.asList("X"); 393 394 if (expected.equals(log)) { 395 throw new AssertionError("Unexpected output: " + log); 396 } 397 } 398 399 @Test 400 public void testModuleInfoNameMismatchSource(Path base) throws Exception { 401 Path src = base.resolve("src"); 402 Path m1 = src.resolve("m1x"); 403 Files.createDirectories(m1); 404 tb.writeJavaFiles(m1, "module other { }", 405 "package test; public class Test {}"); 406 Path classes = base.resolve("classes"); 407 tb.createDirectories(classes); 408 409 List<String> log = new JavacTask(tb) 410 .options("--module-source-path", src.toString(), 411 "-XDrawDiagnostics") 412 .outdir(classes) 413 .files(findJavaFiles(m1.resolve("test").resolve("Test.java"))) 414 .run(Expect.FAIL) 415 .writeAll() 416 .getOutputLines(OutputKind.DIRECT); 417 418 List<String> expected = Arrays.asList( 419 "module-info.java:1:1: compiler.err.module.name.mismatch: other, m1x", 420 "- compiler.err.cant.access: m1x.module-info, (compiler.misc.cant.resolve.modules)", 421 "2 errors"); 422 423 if (!expected.equals(log)) { 424 throw new AssertionError("Unexpected output: " + log); 425 } 426 } 427 428 @Test 429 public void testModuleInfoNameMismatchClass(Path base) throws Exception { 430 Path src = base.resolve("src"); 431 Files.createDirectories(src); 432 tb.writeJavaFiles(src, "module other { }", 433 "package test; public class Test {}"); 434 Path classes = base.resolve("classes"); 435 Path m1Classes = classes.resolve("m1x"); 436 tb.createDirectories(m1Classes); 437 438 new JavacTask(tb) 439 .outdir(m1Classes) 440 .files(findJavaFiles(src)) 441 .run() 442 .writeAll() 443 .getOutputLines(OutputKind.DIRECT); 444 445 Path src2 = base.resolve("src2"); 446 Files.createDirectories(src2); 447 tb.writeJavaFiles(src2, "module use { requires m1x; }"); 448 449 Path classes2 = base.resolve("classes2"); 450 tb.createDirectories(classes2); 451 452 List<String> log = new JavacTask(tb) 453 .options("--module-path", classes.toString(), 454 "-XDrawDiagnostics") 455 .outdir(classes2) 456 .files(findJavaFiles(src2)) 457 .run(Expect.FAIL) 458 .writeAll() 459 .getOutputLines(OutputKind.DIRECT); 460 461 List<String> expected = Arrays.asList( 462 "- compiler.err.cant.access: m1x.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.module.name.mismatch: other, m1x))", 463 "1 error"); 464 465 if (!expected.equals(log)) { 466 throw new AssertionError("Unexpected output: " + log); 467 } 468 } 469 470 @Test 471 public void testGetDirectivesComplete(Path base) throws Exception { 472 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 473 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, null, null, null); 474 Symtab syms = Symtab.instance(task.getContext()); 475 476 syms.java_base.getDirectives(); 477 } 478 479 @Test 480 public void testPackageInModuleInfo(Path base) throws Exception { 481 Path src = base.resolve("src"); 482 Files.createDirectories(src); 483 tb.writeJavaFiles(src, "package p; module foo { }"); 484 Path classes = base.resolve("classes"); 485 tb.createDirectories(classes); 486 487 List<String> log = new JavacTask(tb) 488 .options("-XDrawDiagnostics", "-XDshould-stop.ifError=FLOW") 489 .outdir(classes) 490 .files(findJavaFiles(src)) 491 .run(Expect.FAIL) 492 .writeAll() 493 .getOutputLines(OutputKind.DIRECT); 494 495 List<String> expected = Arrays.asList( 496 "module-info.java:1:1: compiler.err.no.pkg.in.module-info.java", 497 "1 error"); 498 499 if (!expected.equals(log)) { 500 throw new AssertionError("Unexpected output: " + log); 501 } 502 } 503 504 @Test 505 public void testInvisibleClassVisiblePackageClash(Path base) throws Exception { 506 Path src = base.resolve("src"); 507 Path src_m1 = src.resolve("m1x"); 508 tb.writeJavaFiles(src_m1, 509 "module m1x { }", 510 "package m1x;\n" + 511 "import m1x.a.*; public class Test { A a; }\n", 512 "package m1x.a;\n" + 513 "public class A { }\n"); 514 Path src_m2 = src.resolve("m2x"); 515 tb.writeJavaFiles(src_m2, 516 "module m2x { }", 517 "package m1x;\n" + 518 "public class a { public static class A { } }\n"); 519 Path classes = base.resolve("classes"); 520 tb.createDirectories(classes); 521 522 new JavacTask(tb) 523 .options("--module-source-path", src.toString(), 524 "-XDrawDiagnostics") 525 .outdir(classes) 526 .files(findJavaFiles(src)) 527 .run() 528 .writeAll(); 529 } 530 531 @Test 532 public void testStripUnknownRequired(Path base) throws Exception { 533 Path src = base.resolve("src"); 534 Path src_m1 = src.resolve("m1x"); 535 tb.writeJavaFiles(src_m1, 536 "module m1x { }"); 537 Path src_m2 = src.resolve("m2x"); 538 tb.writeJavaFiles(src_m2, 539 "module m2x { }"); 540 Path src_m3 = src.resolve("m3x"); 541 tb.writeJavaFiles(src_m3, 542 "module m3x { }"); 543 Path src_m4 = src.resolve("m4x"); 544 tb.writeJavaFiles(src_m4, 545 "module m4x { }"); 546 Path src_test = src.resolve("test"); 547 tb.writeJavaFiles(src_test, 548 "module test { requires m1x; requires m2x; requires java.base; requires m3x; requires m4x; }"); 549 Path src_compile = src.resolve("compile"); 550 tb.writeJavaFiles(src_compile, 551 "module compile { exports p to test; }", 552 "package p; public class Test { }"); 553 Path classes = base.resolve("classes"); 554 tb.createDirectories(classes); 555 556 List<String> log = new JavacTask(tb) 557 .options("-processor", ListRequires.class.getName(), 558 "--module-source-path", src.toString(), 559 "--limit-modules", "compile", 560 "-XDaccessInternalAPI=true") 561 .outdir(classes) 562 .files(findJavaFiles(src_compile)) 563 .run(Expect.FAIL) 564 .writeAll() 565 .getOutputLines(Task.OutputKind.STDOUT); 566 567 List<String> expected = Arrays.asList( 568 "from directives:", 569 "java.base", 570 "from requires:", 571 "java.base" 572 ); 573 if (!Objects.equals(log, expected)) 574 throw new AssertionError("Unexpected output: " + log); 575 } 576 577 @SupportedAnnotationTypes("*") 578 @SupportedOptions("expectedEnclosedElements") 579 public static final class ListRequires extends AbstractProcessor { 580 581 private int round; 582 583 @Override 584 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 585 if (round++ == 0) { 586 ModuleElement compileE = processingEnv.getElementUtils().getModuleElement("compile"); 587 ModuleElement testE = ElementFilter.exportsIn(compileE.getDirectives()).get(0).getTargetModules().get(0); 588 589 System.out.println("from directives:"); 590 for (RequiresDirective rd : ElementFilter.requiresIn(testE.getDirectives())) { 591 System.out.println(rd.getDependency().getSimpleName()); 592 } 593 594 System.out.println("from requires:"); 595 for (RequiresDirective rd : ((ModuleSymbol) testE).requires) { 596 System.out.println(rd.getDependency().getSimpleName()); 597 } 598 } 599 600 return false; 601 } 602 603 @Override 604 public SourceVersion getSupportedSourceVersion() { 605 return SourceVersion.latest(); 606 } 607 608 } 609 610 @Test 611 public void testOnDemandCompletionModuleInfoJava(Path base) throws Exception { 612 Path src = base.resolve("src"); 613 Path src_m1 = src.resolve("m1x"); 614 tb.writeJavaFiles(src_m1, 615 "@Deprecated module m1x { }"); 616 Path src_m2 = src.resolve("m2x"); 617 tb.writeJavaFiles(src_m2, 618 "module m2x { requires m1x; }"); 619 Path src_m3 = src.resolve("m3x"); 620 tb.writeJavaFiles(src_m3, 621 "module m3x { requires m2x; requires m1x; }"); 622 Path classes = base.resolve("classes"); 623 tb.createDirectories(classes); 624 625 List<String> log; 626 List<String> expected; 627 628 log = new JavacTask(tb) 629 .options("--module-source-path", src.toString()) 630 .outdir(classes) 631 .files(findJavaFiles(src_m1)) 632 .run() 633 .writeAll() 634 .getOutputLines(Task.OutputKind.DIRECT); 635 636 expected = Arrays.asList(""); 637 638 if (!expected.equals(log)) { 639 throw new IllegalStateException(log.toString()); 640 } 641 642 log = new JavacTask(tb) 643 .options("--module-source-path", src.toString(), 644 "-XDrawDiagnostics", 645 "-Xlint:deprecation") 646 .outdir(classes) 647 .files(findJavaFiles(src_m3)) 648 .run() 649 .writeAll() 650 .getOutputLines(Task.OutputKind.DIRECT); 651 652 expected = Arrays.asList( 653 "module-info.java:1:23: compiler.warn.has.been.deprecated.module: m1x", 654 "module-info.java:1:37: compiler.warn.has.been.deprecated.module: m1x", 655 "2 warnings" 656 ); 657 658 if (!expected.equals(log)) { 659 throw new IllegalStateException(log.toString()); 660 } 661 } 662 663 @Test 664 public void testUnnamedPackage(Path base) throws Exception { 665 List<String> out; 666 List<String> expected; 667 668 //-source 8: 669 Path src8 = base.resolve("src8"); 670 Files.createDirectories(src8); 671 tb.writeJavaFiles(src8, 672 "package test; public class Test {}"); 673 Path classes = base.resolve("classes"); 674 tb.createDirectories(classes); 675 676 out = new JavacTask(tb) 677 .options("--source-path", src8.toString(), 678 "-processor", UnnamedPackageProcessor.class.getName(), 679 "-source", "8") 680 .outdir(classes) 681 .files(findJavaFiles(src8)) 682 .run() 683 .writeAll() 684 .getOutputLines(OutputKind.STDOUT); 685 686 expected = Arrays.asList("noModule"); 687 688 if (!expected.equals(out)) { 689 throw new AssertionError("Unexpected output: " + out); 690 } 691 692 //-source 9, unnamed: 693 Path srcUnnamed = base.resolve("srcUnnamed"); 694 Files.createDirectories(srcUnnamed); 695 tb.writeJavaFiles(srcUnnamed, 696 "public class Test {}"); 697 Path classesUnnamed = base.resolve("classesUnnamed"); 698 tb.createDirectories(classesUnnamed); 699 700 out = new JavacTask(tb) 701 .options("--source-path", srcUnnamed.toString(), 702 "-processor", UnnamedPackageProcessor.class.getName()) 703 .outdir(classesUnnamed) 704 .files(findJavaFiles(srcUnnamed)) 705 .run() 706 .writeAll() 707 .getOutputLines(OutputKind.STDOUT); 708 709 expected = Arrays.asList("unnamedModule"); 710 711 if (!expected.equals(out)) { 712 throw new AssertionError("Unexpected output: " + out); 713 } 714 715 //-source 9, named: 716 Path srcNamed = base.resolve("srcNamed"); 717 Files.createDirectories(srcNamed); 718 tb.writeJavaFiles(srcNamed, 719 "module m {}", 720 "public class Test {}"); 721 Path classesNamed = base.resolve("classesNamed"); 722 tb.createDirectories(classesNamed); 723 724 out = new JavacTask(tb) 725 .options("--source-path", srcNamed.toString(), 726 "-classpath", "", 727 "-processorpath", System.getProperty("test.class.path"), 728 "-processor", UnnamedPackageProcessor.class.getName()) 729 .outdir(classesNamed) 730 .files(findJavaFiles(srcNamed)) 731 .run() 732 .writeAll() 733 .getOutputLines(OutputKind.STDOUT); 734 735 expected = Arrays.asList("m"); 736 737 if (!expected.equals(out)) { 738 throw new AssertionError("Unexpected output: " + out); 739 } 740 741 //-source 9, conflict: 742 Path srcNamed2 = base.resolve("srcNamed2"); 743 Path srcNamed2m1 = srcNamed2.resolve("m1x"); 744 Files.createDirectories(srcNamed2m1); 745 tb.writeJavaFiles(srcNamed2m1, 746 "module m1x {}", 747 "public class Test {}"); 748 Path srcNamed2m2 = srcNamed2.resolve("m2x"); 749 Files.createDirectories(srcNamed2m2); 750 tb.writeJavaFiles(srcNamed2m2, 751 "module m2x {}", 752 "public class Test {}"); 753 Path classesNamed2 = base.resolve("classesNamed2"); 754 tb.createDirectories(classesNamed2); 755 756 out = new JavacTask(tb) 757 .options("--module-source-path", srcNamed2.toString(), 758 "-classpath", "", 759 "-processorpath", System.getProperty("test.class.path"), 760 "-processor", UnnamedPackageProcessor.class.getName(), 761 "-XDshould-stop.ifError=FLOW") 762 .outdir(classesNamed2) 763 .files(findJavaFiles(srcNamed2)) 764 .run(Expect.FAIL) 765 .writeAll() 766 .getOutputLines(OutputKind.STDOUT); 767 768 expected = Arrays.asList("null", 769 "m1x: true", 770 "m2x: true"); 771 772 if (!expected.equals(out)) { 773 throw new AssertionError("Unexpected output: " + out); 774 } 775 } 776 777 @SupportedAnnotationTypes("*") 778 public static final class UnnamedPackageProcessor extends AbstractProcessor { 779 780 int round = 0; 781 782 @Override 783 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 784 if (round++ != 0) 785 return false; 786 787 Elements elements = processingEnv.getElementUtils(); 788 PackageElement pe = elements.getPackageElement(""); 789 790 if (pe == null) { 791 System.out.println("null"); 792 } else { 793 ModuleElement mod = (ModuleElement) pe.getEnclosingElement(); 794 if (mod == null) { 795 System.out.println("noModule"); 796 } else if (mod.isUnnamed()) { 797 System.out.println("unnamedModule"); 798 } else { 799 System.out.println(mod); 800 } 801 } 802 803 ModuleElement m1x = elements.getModuleElement("m1x"); 804 ModuleElement m2x = elements.getModuleElement("m2x"); 805 806 if (m1x != null && m2x != null) { 807 System.out.println("m1x: " + (elements.getPackageElement(m1x, "") != null)); 808 System.out.println("m2x: " + (elements.getPackageElement(m2x, "") != null)); 809 } 810 811 return false; 812 } 813 814 } 815} 816