43 import javax.lang.model.SourceVersion; 44 import javax.lang.model.element.ModuleElement; 45 import javax.lang.model.element.ModuleElement.RequiresDirective; 46 import javax.lang.model.element.TypeElement; 47 import javax.lang.model.util.ElementFilter; 48 49 import toolbox.JarTask; 50 import toolbox.JavacTask; 51 import toolbox.JavapTask; 52 import toolbox.Task; 53 54 public class AddReadsTest extends ModuleTestBase { 55 56 public static void main(String... args) throws Exception { 57 new AddReadsTest().runTests(); 58 } 59 60 @Test 61 public void testAddReads(Path base) throws Exception { 62 Path src = base.resolve("src"); 63 Path src_m1 = src.resolve("m1"); 64 tb.writeJavaFiles(src_m1, 65 "module m1 { exports api; }", 66 "package api; public class Api { }"); 67 Path src_m2 = src.resolve("m2"); 68 tb.writeJavaFiles(src_m2, 69 "module m2 { }", 70 "package test; public class Test extends api.Api { }"); 71 Path classes = base.resolve("classes"); 72 tb.createDirectories(classes); 73 74 String log = new JavacTask(tb) 75 .options("-XDrawDiagnostics", 76 "--module-source-path", src.toString()) 77 .outdir(classes) 78 .files(findJavaFiles(src)) 79 .run(Task.Expect.FAIL) 80 .writeAll() 81 .getOutput(Task.OutputKind.DIRECT); 82 83 checkOutputContains(log, 84 "Test.java:1:44: compiler.err.not.def.access.package.cant.access: api.Api, api"); 85 86 //test add dependencies: 87 new JavacTask(tb) 88 .options("--add-reads", "m2=m1", 89 "--module-source-path", src.toString(), 90 "-processor", VerifyRequires.class.getName()) 91 .outdir(classes) 92 .files(findJavaFiles(src)) 93 .run() 94 .writeAll(); 95 96 String decompiled = new JavapTask(tb) 97 .options("-verbose", classes.resolve("m2").resolve("module-info.class").toString()) 98 .run() 99 .getOutput(Task.OutputKind.DIRECT); 100 101 if (decompiled.contains("m1")) { 102 throw new Exception("Incorrectly refers to m1 module."); 103 } 104 105 //cyclic dependencies OK when created through addReads: 106 new JavacTask(tb) 107 .options("--add-reads", "m2=m1", 108 "--add-reads", "m1=m2", 109 "--module-source-path", src.toString()) 110 .outdir(classes) 111 .files(findJavaFiles(src)) 112 .run() 113 .writeAll(); 114 115 tb.writeJavaFiles(src_m2, 116 "module m2 { requires m1; }"); 117 118 new JavacTask(tb) 119 .options("--add-reads", "m1=m2", 120 "--module-source-path", src.toString()) 121 .outdir(classes) 122 .files(findJavaFiles(src)) 123 .run() 124 .writeAll(); 125 } 126 127 @SupportedAnnotationTypes("*") 128 public static final class VerifyRequires extends AbstractProcessor { 129 130 @Override 131 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 132 ModuleElement m2Module = processingEnv.getElementUtils().getModuleElement("m2"); 133 if (m2Module == null) { 134 throw new AssertionError("Cannot find the m2 module!"); 135 } 136 boolean foundM1 = false; 137 for (RequiresDirective rd : ElementFilter.requiresIn(m2Module.getDirectives())) { 138 foundM1 |= rd.getDependency().getSimpleName().contentEquals("m1"); 139 } 140 if (!foundM1) { 141 throw new AssertionError("Cannot find the dependency on m1 module!"); 142 } 143 return false; 144 } 145 146 @Override 147 public SourceVersion getSupportedSourceVersion() { 148 return SourceVersion.latest(); 149 } 150 151 } 152 153 @Test 154 public void testAddReadsUnnamedModule(Path base) throws Exception { 155 Path jar = prepareTestJar(base); 156 157 Path moduleSrc = base.resolve("module-src"); 158 Path m1 = moduleSrc.resolve("m1"); 159 160 Path classes = base.resolve("classes"); 161 162 Files.createDirectories(classes); 163 164 tb.writeJavaFiles(m1, 165 "module m1 { }", 166 "package impl; public class Impl { api.Api api; }"); 167 168 new JavacTask(tb) 169 .options("--class-path", jar.toString(), 170 "--add-reads", "m1=ALL-UNNAMED", 171 "-XDrawDiagnostics") 172 .outdir(classes) 173 .files(findJavaFiles(moduleSrc)) 174 .run() 175 .writeAll(); 176 } 177 178 @Test 179 public void testAddReadsUnnamedModulePackageConflict(Path base) throws Exception { 180 Path jar = prepareTestJar(base); 181 182 Path moduleSrc = base.resolve("module-src"); 183 Path m1 = moduleSrc.resolve("m1"); 184 185 Path classes = base.resolve("classes"); 186 187 Files.createDirectories(classes); 188 189 tb.writeJavaFiles(m1, 190 "module m1 { }", 191 "package api; public class Api { public static void test() { } }", 192 "package impl; public class Impl { { api.Api.test(); } }"); 193 194 new JavacTask(tb) 195 .options("--class-path", jar.toString(), 196 "--module-source-path", moduleSrc.toString(), 197 "--add-reads", "m1=ALL-UNNAMED", 198 "-XDrawDiagnostics") 199 .outdir(classes) 200 .files(m1.resolve("impl").resolve("Impl.java")) 201 .run() 202 .writeAll(); 203 } 204 205 @Test 206 public void testAddReadsUnnamedToJavaBase(Path base) throws Exception { 207 Path jar = prepareTestJar(base); 208 Path src = base.resolve("src"); 209 Path classes = base.resolve("classes"); 210 211 Files.createDirectories(classes); 212 213 tb.writeJavaFiles(src, 214 "package impl; public class Impl { api.Api a; }"); 215 216 new JavacTask(tb) 217 .options("--class-path", jar.toString(), 262 throw new Exception("unexpected output: " + log); 263 } 264 265 Path lib = base.resolve("lib"); 266 267 Files.createDirectories(lib); 268 269 Path jar = lib.resolve("test-api-1.0.jar"); 270 271 new JarTask(tb, jar) 272 .baseDir(legacyClasses) 273 .files("api/Api.class") 274 .run(); 275 276 return jar; 277 } 278 279 @Test 280 public void testX(Path base) throws Exception { 281 Path src = base.resolve("src"); 282 Path src_m1 = src.resolve("m1"); 283 tb.writeJavaFiles(src_m1, 284 "module m1 { provides java.lang.Runnable with impl.Impl; }", 285 "package impl; public class Impl implements Runnable { public void run() { } }"); 286 Path classes = base.resolve("classes"); 287 tb.createDirectories(classes); 288 289 new JavacTask(tb) 290 .options("--module-source-path", src.toString()) 291 .outdir(classes) 292 .files(findJavaFiles(src)) 293 .run() 294 .writeAll(); 295 296 Path unnamedSrc = base.resolve("unnamed-src"); 297 Path unnamedClasses = base.resolve("unnamed-classes"); 298 299 Files.createDirectories(unnamedClasses); 300 301 tb.writeJavaFiles(unnamedSrc, 302 "package impl; public class Impl { }"); 303 304 new JavacTask(tb) 305 .options("--add-reads", "m1=ALL-UNNAMED", 306 "-Xmodule:m1", 307 "--module-path", classes.toString()) 308 .outdir(unnamedClasses) 309 .files(findJavaFiles(unnamedSrc)) 310 .run() 311 .writeAll(); 312 } 313 314 @Test 315 public void testAddSelf(Path base) throws Exception { 316 Path src = base.resolve("src"); 317 Path src_m1 = src.resolve("m1"); 318 tb.writeJavaFiles(src_m1, 319 "module m1 { exports p1; }", 320 "package p1; public class C1 { }"); 321 Path classes = base.resolve("classes"); 322 tb.createDirectories(classes); 323 324 new JavacTask(tb) 325 .options("--module-source-path", src.toString(), 326 "--add-reads", "m1=m1") 327 .outdir(classes) 328 .files(findJavaFiles(src)) 329 .run() 330 .writeAll(); 331 } 332 333 @Test 334 public void testEmpty(Path base) throws Exception { 335 Path src = base.resolve("src"); 336 tb.writeJavaFiles(src, "class Dummy { }"); 337 Path classes = base.resolve("classes"); 338 tb.createDirectories(classes); 339 340 testEmpty(src, classes, "--add-reads", ""); 341 testEmpty(src, classes, "--add-reads="); 342 } 343 344 private void testEmpty(Path src, Path classes, String... options) throws Exception { 345 String log = new JavacTask(tb, Task.Mode.CMDLINE) 346 .options(options) 347 .outdir(classes) 348 .files(findJavaFiles(src)) 349 .run(Task.Expect.FAIL) 350 .writeAll() 351 .getOutput(Task.OutputKind.DIRECT); 352 353 checkOutputContains(log, 354 "javac: no value for --add-reads option"); 355 } 356 357 @Test 358 public void testEmptyItem(Path base) throws Exception { 359 Path src = base.resolve("src"); 360 Path src_m1 = src.resolve("m1"); 361 tb.writeJavaFiles(src_m1, 362 "module m1 { exports p1; }", 363 "package p1; public class C1 { }"); 364 Path src_m2 = src.resolve("m2"); 365 tb.writeJavaFiles(src_m2, 366 "module m2 { }", 367 "package p2; class C2 { }"); 368 Path src_m3 = src.resolve("m3"); 369 tb.writeJavaFiles(src_m3, 370 "module m3 { }", 371 "package p3; class C3 { p1.C1 c1; }"); 372 Path classes = base.resolve("classes"); 373 tb.createDirectories(classes); 374 375 testEmptyItem(src, classes, "m3=,m1"); 376 testEmptyItem(src, classes, "m3=m1,,m2"); 377 testEmptyItem(src, classes, "m3=m1,"); 378 } 379 380 private void testEmptyItem(Path src, Path classes, String option) throws Exception { 381 new JavacTask(tb) 382 .options("--module-source-path", src.toString(), 383 "--add-reads", option) 384 .outdir(classes) 385 .files(findJavaFiles(src)) 386 .run() 387 .writeAll(); 388 } 389 390 @Test 391 public void testEmptyList(Path base) throws Exception { 392 Path src = base.resolve("src"); 393 Path src_m1 = src.resolve("m1"); 394 tb.writeJavaFiles(src_m1, 395 "module m1 { exports p1; }", 396 "package p1; public class C1 { }"); 397 Path src_m2 = src.resolve("m2"); 398 tb.writeJavaFiles(src_m2, 399 "module m2 { }", 400 "package p2; class C2 { }"); 401 Path src_m3 = src.resolve("m3"); 402 tb.writeJavaFiles(src_m3, 403 "module m3 { }", 404 "package p3; class C3 { p1.C1 c1; }"); 405 Path classes = base.resolve("classes"); 406 tb.createDirectories(classes); 407 408 testEmptyList(src, classes, "m3="); 409 testEmptyList(src, classes, "m3=,"); 410 } 411 412 private void testEmptyList(Path src, Path classes, String option) throws Exception { 413 String log = new JavacTask(tb, Task.Mode.CMDLINE) 414 .options("--module-source-path", src.toString(), 415 "--add-reads", option) 416 .outdir(classes) 417 .files(findJavaFiles(src)) 418 .run(Task.Expect.FAIL) 419 .writeAll() 420 .getOutput(Task.OutputKind.DIRECT); 421 422 checkOutputContains(log, 423 "javac: bad value for --add-reads option: '" + option + "'"); 424 } 425 426 @Test 427 public void testMultipleAddReads_DifferentModules(Path base) throws Exception { 428 Path src = base.resolve("src"); 429 Path src_m1 = src.resolve("m1"); 430 tb.writeJavaFiles(src_m1, 431 "module m1 { exports p1; }", 432 "package p1; public class C1 { }"); 433 Path src_m2 = src.resolve("m2"); 434 tb.writeJavaFiles(src_m2, 435 "module m2 { }", 436 "package p2; class C2 { p1.C1 c1; }"); 437 Path src_m3 = src.resolve("m3"); 438 tb.writeJavaFiles(src_m3, 439 "module m3 { }", 440 "package p3; class C3 { p1.C1 c1; }"); 441 Path classes = base.resolve("classes"); 442 tb.createDirectories(classes); 443 444 new JavacTask(tb) 445 .options("--module-source-path", src.toString(), 446 "--add-reads", "m2=m1", 447 "--add-reads", "m3=m1") 448 .outdir(classes) 449 .files(findJavaFiles(src)) 450 .run() 451 .writeAll(); 452 } 453 454 @Test 455 public void testMultipleAddReads_SameModule(Path base) throws Exception { 456 Path src = base.resolve("src"); 457 Path src_m1 = src.resolve("m1"); 458 tb.writeJavaFiles(src_m1, 459 "module m1 { exports p1; }", 460 "package p1; public class C1 { }"); 461 Path src_m2 = src.resolve("m2"); 462 tb.writeJavaFiles(src_m2, 463 "module m2 { exports p2; }", 464 "package p2; public class C2 { }"); 465 Path src_m3 = src.resolve("m3"); 466 tb.writeJavaFiles(src_m3, 467 "module m3 { }", 468 "package p3; class C3 { p1.C1 c1; p2.C2 c2; }"); 469 Path classes = base.resolve("classes"); 470 tb.createDirectories(classes); 471 472 new JavacTask(tb) 473 .options("--module-source-path", src.toString(), 474 "--add-reads", "m3=m1", 475 "--add-reads", "m3=m2") 476 .outdir(classes) 477 .files(findJavaFiles(src)) 478 .run() 479 .writeAll(); 480 } 481 482 @Test 483 public void testDuplicateAddReads_SameOption(Path base) throws Exception { 484 Path src = base.resolve("src"); 485 Path src_m1 = src.resolve("m1"); 486 tb.writeJavaFiles(src_m1, 487 "module m1 { exports p1; }", 488 "package p1; public class C1 { }"); 489 Path src_m2 = src.resolve("m2"); 490 tb.writeJavaFiles(src_m2, 491 "module m2 { exports p2; }", 492 "package p2; class C2 { p1.C1 c1; }"); 493 Path classes = base.resolve("classes"); 494 tb.createDirectories(classes); 495 496 new JavacTask(tb) 497 .options("--module-source-path", src.toString(), 498 "--add-reads", "m2=m1,m1") 499 .outdir(classes) 500 .files(findJavaFiles(src)) 501 .run() 502 .writeAll(); 503 } 504 505 @Test 506 public void testDuplicateAddReads_MultipleOptions(Path base) throws Exception { 507 Path src = base.resolve("src"); 508 Path src_m1 = src.resolve("m1"); 509 tb.writeJavaFiles(src_m1, 510 "module m1 { exports p1; }", 511 "package p1; public class C1 { }"); 512 Path src_m2 = src.resolve("m2"); 513 tb.writeJavaFiles(src_m2, 514 "module m2 { }", 515 "package p2; class C2 { p1.C1 c1; }"); 516 Path classes = base.resolve("classes"); 517 tb.createDirectories(classes); 518 519 new JavacTask(tb) 520 .options("--module-source-path", src.toString(), 521 "--add-reads", "m2=m1", 522 "--add-reads", "m2=m1") 523 .outdir(classes) 524 .files(findJavaFiles(src)) 525 .run() 526 .writeAll(); 527 } 528 529 @Test 530 public void testRepeatedAddReads(Path base) throws Exception { 531 Path src = base.resolve("src"); 532 Path src_m1 = src.resolve("m1"); 533 tb.writeJavaFiles(src_m1, 534 "module m1 { exports p1; }", 535 "package p1; public class C1 { }"); 536 Path src_m2 = src.resolve("m2"); 537 tb.writeJavaFiles(src_m2, 538 "module m2 { exports p2; }", 539 "package p2; public class C2 { }"); 540 Path src_m3 = src.resolve("m3"); 541 tb.writeJavaFiles(src_m3, 542 "module m3 { }", 543 "package p3; class C3 { p1.C1 c1; p2.C2 c2; }"); 544 Path classes = base.resolve("classes"); 545 tb.createDirectories(classes); 546 547 new JavacTask(tb) 548 .options("--module-source-path", src.toString(), 549 "--add-reads", "m3=m1", 550 "--add-reads", "m3=m2") 551 .outdir(classes) 552 .files(findJavaFiles(src)) 553 .run() 554 .writeAll(); 555 } 556 557 @Test 558 public void testNoEquals(Path base) throws Exception { 559 Path src = base.resolve("src"); 560 tb.writeJavaFiles(src, "class Dummy { }"); 561 Path classes = base.resolve("classes"); 562 tb.createDirectories(classes); 563 564 String log = new JavacTask(tb, Task.Mode.CMDLINE) 565 .options("-XDrawDiagnostics", 566 "--add-reads", "m1:m2") 567 .outdir(classes) 568 .files(findJavaFiles(src)) 569 .run(Task.Expect.FAIL) 570 .writeAll() 571 .getOutput(Task.OutputKind.DIRECT); 572 573 checkOutputContains(log, 574 "javac: bad value for --add-reads option: 'm1:m2'"); 575 } 576 577 @Test 578 public void testBadSourceName(Path base) throws Exception { 579 Path src = base.resolve("src"); 580 tb.writeJavaFiles(src, "class Dummy { }"); 581 Path classes = base.resolve("classes"); 582 tb.createDirectories(classes); 583 584 String log = new JavacTask(tb) 585 .options("-XDrawDiagnostics", 586 "--add-reads", "bad*Source=m2") 587 .outdir(classes) 588 .files(findJavaFiles(src)) 589 .run() 590 .writeAll() 591 .getOutput(Task.OutputKind.DIRECT); 592 593 checkOutputContains(log, 594 "- compiler.warn.bad.name.for.option: --add-reads, bad*Source"); 595 } 596 597 @Test 598 public void testBadTargetName(Path base) throws Exception { 599 Path src = base.resolve("src"); 600 Path src_m1 = src.resolve("m1"); 601 tb.writeJavaFiles(src_m1, 602 "module m1 { }", 603 "package p1; class C1 { }"); 604 Path classes = base.resolve("classes"); 605 tb.createDirectories(classes); 606 607 String log = new JavacTask(tb) 608 .options("-XDrawDiagnostics", 609 "--add-reads", "m1=badTarget!") 610 .outdir(classes) 611 .files(findJavaFiles(src)) 612 .run() 613 .writeAll() 614 .getOutput(Task.OutputKind.DIRECT); 615 616 checkOutputContains(log, 617 "- compiler.warn.bad.name.for.option: --add-reads, badTarget!"); 618 } 619 620 @Test 621 public void testSourceNameNotFound(Path base) throws Exception { 622 Path src = base.resolve("src"); 623 Path src_m1 = src.resolve("m1"); 624 tb.writeJavaFiles(src_m1, 625 "module m1 { exports p1; }", 626 "package p1; public class C1 { }"); 627 Path classes = base.resolve("classes"); 628 tb.createDirectories(classes); 629 630 String log = new JavacTask(tb) 631 .options("-XDrawDiagnostics", 632 "--add-reads", "missingSource=m1") 633 .outdir(classes) 634 .files(findJavaFiles(src)) 635 .run() 636 .writeAll() 637 .getOutput(Task.OutputKind.DIRECT); 638 639 checkOutputContains(log, 640 "- compiler.warn.module.for.option.not.found: --add-reads, missingSource"); 641 } 642 643 @Test 644 public void testTargetNameNotFound(Path base) throws Exception { 645 Path src = base.resolve("src"); 646 Path src_m1 = src.resolve("m1"); 647 tb.writeJavaFiles(src_m1, 648 "module m1 { exports p1; }", 649 "package p1; public class C1 { }"); 650 Path classes = base.resolve("classes"); 651 tb.createDirectories(classes); 652 653 String log = new JavacTask(tb) 654 .options("-XDrawDiagnostics", 655 "--add-reads", "m1=missingTarget") 656 .outdir(classes) 657 .files(findJavaFiles(src)) 658 .run() 659 .writeAll() 660 .getOutput(Task.OutputKind.DIRECT); 661 662 checkOutputContains(log, 663 "- compiler.warn.module.for.option.not.found: --add-reads, missingTarget"); 664 } 665 } | 43 import javax.lang.model.SourceVersion; 44 import javax.lang.model.element.ModuleElement; 45 import javax.lang.model.element.ModuleElement.RequiresDirective; 46 import javax.lang.model.element.TypeElement; 47 import javax.lang.model.util.ElementFilter; 48 49 import toolbox.JarTask; 50 import toolbox.JavacTask; 51 import toolbox.JavapTask; 52 import toolbox.Task; 53 54 public class AddReadsTest extends ModuleTestBase { 55 56 public static void main(String... args) throws Exception { 57 new AddReadsTest().runTests(); 58 } 59 60 @Test 61 public void testAddReads(Path base) throws Exception { 62 Path src = base.resolve("src"); 63 Path src_m1 = src.resolve("m1x"); 64 tb.writeJavaFiles(src_m1, 65 "module m1x { exports api; }", 66 "package api; public class Api { }"); 67 Path src_m2 = src.resolve("m2x"); 68 tb.writeJavaFiles(src_m2, 69 "module m2x { }", 70 "package test; public class Test extends api.Api { }"); 71 Path classes = base.resolve("classes"); 72 tb.createDirectories(classes); 73 74 String log = new JavacTask(tb) 75 .options("-XDrawDiagnostics", 76 "--module-source-path", src.toString()) 77 .outdir(classes) 78 .files(findJavaFiles(src)) 79 .run(Task.Expect.FAIL) 80 .writeAll() 81 .getOutput(Task.OutputKind.DIRECT); 82 83 checkOutputContains(log, 84 "Test.java:1:44: compiler.err.not.def.access.package.cant.access: api.Api, api"); 85 86 //test add dependencies: 87 new JavacTask(tb) 88 .options("--add-reads", "m2x=m1x", 89 "--module-source-path", src.toString(), 90 "-processor", VerifyRequires.class.getName()) 91 .outdir(classes) 92 .files(findJavaFiles(src)) 93 .run() 94 .writeAll(); 95 96 String decompiled = new JavapTask(tb) 97 .options("-verbose", 98 classes.resolve("m2x").resolve("module-info.class").toString()) 99 .run() 100 .getOutput(Task.OutputKind.DIRECT); 101 102 if (decompiled.contains("m1x")) { 103 throw new Exception("Incorrectly refers to m1x module."); 104 } 105 106 //cyclic dependencies OK when created through addReads: 107 new JavacTask(tb) 108 .options("--add-reads", "m2x=m1x", 109 "--add-reads", "m1x=m2x", 110 "--module-source-path", src.toString()) 111 .outdir(classes) 112 .files(findJavaFiles(src)) 113 .run() 114 .writeAll(); 115 116 tb.writeJavaFiles(src_m2, 117 "module m2x { requires m1x; }"); 118 119 new JavacTask(tb) 120 .options("--add-reads", "m1x=m2x", 121 "--module-source-path", src.toString()) 122 .outdir(classes) 123 .files(findJavaFiles(src)) 124 .run() 125 .writeAll(); 126 } 127 128 @SupportedAnnotationTypes("*") 129 public static final class VerifyRequires extends AbstractProcessor { 130 131 @Override 132 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 133 ModuleElement m2Module = processingEnv.getElementUtils().getModuleElement("m2x"); 134 if (m2Module == null) { 135 throw new AssertionError("Cannot find the m2x module!"); 136 } 137 boolean foundM1 = false; 138 for (RequiresDirective rd : ElementFilter.requiresIn(m2Module.getDirectives())) { 139 foundM1 |= rd.getDependency().getSimpleName().contentEquals("m1x"); 140 } 141 if (!foundM1) { 142 throw new AssertionError("Cannot find the dependency on m1x module!"); 143 } 144 return false; 145 } 146 147 @Override 148 public SourceVersion getSupportedSourceVersion() { 149 return SourceVersion.latest(); 150 } 151 152 } 153 154 @Test 155 public void testAddReadsUnnamedModule(Path base) throws Exception { 156 Path jar = prepareTestJar(base); 157 158 Path moduleSrc = base.resolve("module-src"); 159 Path m1 = moduleSrc.resolve("m1x"); 160 161 Path classes = base.resolve("classes"); 162 163 Files.createDirectories(classes); 164 165 tb.writeJavaFiles(m1, 166 "module m1x { }", 167 "package impl; public class Impl { api.Api api; }"); 168 169 new JavacTask(tb) 170 .options("--class-path", jar.toString(), 171 "--add-reads", "m1x=ALL-UNNAMED", 172 "-XDrawDiagnostics") 173 .outdir(classes) 174 .files(findJavaFiles(moduleSrc)) 175 .run() 176 .writeAll(); 177 } 178 179 @Test 180 public void testAddReadsUnnamedModulePackageConflict(Path base) throws Exception { 181 Path jar = prepareTestJar(base); 182 183 Path moduleSrc = base.resolve("module-src"); 184 Path m1 = moduleSrc.resolve("m1x"); 185 186 Path classes = base.resolve("classes"); 187 188 Files.createDirectories(classes); 189 190 tb.writeJavaFiles(m1, 191 "module m1x { }", 192 "package api; public class Api { public static void test() { } }", 193 "package impl; public class Impl { { api.Api.test(); } }"); 194 195 new JavacTask(tb) 196 .options("--class-path", jar.toString(), 197 "--module-source-path", moduleSrc.toString(), 198 "--add-reads", "m1x=ALL-UNNAMED", 199 "-XDrawDiagnostics") 200 .outdir(classes) 201 .files(m1.resolve("impl").resolve("Impl.java")) 202 .run() 203 .writeAll(); 204 } 205 206 @Test 207 public void testAddReadsUnnamedToJavaBase(Path base) throws Exception { 208 Path jar = prepareTestJar(base); 209 Path src = base.resolve("src"); 210 Path classes = base.resolve("classes"); 211 212 Files.createDirectories(classes); 213 214 tb.writeJavaFiles(src, 215 "package impl; public class Impl { api.Api a; }"); 216 217 new JavacTask(tb) 218 .options("--class-path", jar.toString(), 263 throw new Exception("unexpected output: " + log); 264 } 265 266 Path lib = base.resolve("lib"); 267 268 Files.createDirectories(lib); 269 270 Path jar = lib.resolve("test-api-1.0.jar"); 271 272 new JarTask(tb, jar) 273 .baseDir(legacyClasses) 274 .files("api/Api.class") 275 .run(); 276 277 return jar; 278 } 279 280 @Test 281 public void testX(Path base) throws Exception { 282 Path src = base.resolve("src"); 283 Path src_m1 = src.resolve("m1x"); 284 tb.writeJavaFiles(src_m1, 285 "module m1x { provides java.lang.Runnable with impl.Impl; }", 286 "package impl; public class Impl implements Runnable { public void run() { } }"); 287 Path classes = base.resolve("classes"); 288 tb.createDirectories(classes); 289 290 new JavacTask(tb) 291 .options("--module-source-path", src.toString()) 292 .outdir(classes) 293 .files(findJavaFiles(src)) 294 .run() 295 .writeAll(); 296 297 Path unnamedSrc = base.resolve("unnamed-src"); 298 Path unnamedClasses = base.resolve("unnamed-classes"); 299 300 Files.createDirectories(unnamedClasses); 301 302 tb.writeJavaFiles(unnamedSrc, 303 "package impl; public class Impl { }"); 304 305 new JavacTask(tb) 306 .options("--add-reads", "m1x=ALL-UNNAMED", 307 "-Xmodule:m1x", 308 "--module-path", classes.toString()) 309 .outdir(unnamedClasses) 310 .files(findJavaFiles(unnamedSrc)) 311 .run() 312 .writeAll(); 313 } 314 315 @Test 316 public void testAddSelf(Path base) throws Exception { 317 Path src = base.resolve("src"); 318 Path src_m1 = src.resolve("m1x"); 319 tb.writeJavaFiles(src_m1, 320 "module m1x { exports p1; }", 321 "package p1; public class C1 { }"); 322 Path classes = base.resolve("classes"); 323 tb.createDirectories(classes); 324 325 new JavacTask(tb) 326 .options("--module-source-path", src.toString(), 327 "--add-reads", "m1x=m1x") 328 .outdir(classes) 329 .files(findJavaFiles(src)) 330 .run() 331 .writeAll(); 332 } 333 334 @Test 335 public void testEmpty(Path base) throws Exception { 336 Path src = base.resolve("src"); 337 tb.writeJavaFiles(src, "class Dummy { }"); 338 Path classes = base.resolve("classes"); 339 tb.createDirectories(classes); 340 341 testEmpty(src, classes, "--add-reads", ""); 342 testEmpty(src, classes, "--add-reads="); 343 } 344 345 private void testEmpty(Path src, Path classes, String... options) throws Exception { 346 String log = new JavacTask(tb, Task.Mode.CMDLINE) 347 .options(options) 348 .outdir(classes) 349 .files(findJavaFiles(src)) 350 .run(Task.Expect.FAIL) 351 .writeAll() 352 .getOutput(Task.OutputKind.DIRECT); 353 354 checkOutputContains(log, 355 "javac: no value for --add-reads option"); 356 } 357 358 @Test 359 public void testEmptyItem(Path base) throws Exception { 360 Path src = base.resolve("src"); 361 Path src_m1 = src.resolve("m1x"); 362 tb.writeJavaFiles(src_m1, 363 "module m1x { exports p1; }", 364 "package p1; public class C1 { }"); 365 Path src_m2 = src.resolve("m2x"); 366 tb.writeJavaFiles(src_m2, 367 "module m2x { }", 368 "package p2; class C2 { }"); 369 Path src_m3 = src.resolve("m3x"); 370 tb.writeJavaFiles(src_m3, 371 "module m3x { }", 372 "package p3; class C3 { p1.C1 c1; }"); 373 Path classes = base.resolve("classes"); 374 tb.createDirectories(classes); 375 376 testEmptyItem(src, classes, "m3x=,m1x"); 377 testEmptyItem(src, classes, "m3x=m1x,,m2x"); 378 testEmptyItem(src, classes, "m3x=m1x,"); 379 } 380 381 private void testEmptyItem(Path src, Path classes, String option) throws Exception { 382 new JavacTask(tb) 383 .options("--module-source-path", src.toString(), 384 "--add-reads", option) 385 .outdir(classes) 386 .files(findJavaFiles(src)) 387 .run() 388 .writeAll(); 389 } 390 391 @Test 392 public void testEmptyList(Path base) throws Exception { 393 Path src = base.resolve("src"); 394 Path src_m1 = src.resolve("m1x"); 395 tb.writeJavaFiles(src_m1, 396 "module m1x { exports p1; }", 397 "package p1; public class C1 { }"); 398 Path src_m2 = src.resolve("m2x"); 399 tb.writeJavaFiles(src_m2, 400 "module m2x { }", 401 "package p2; class C2 { }"); 402 Path src_m3 = src.resolve("m3x"); 403 tb.writeJavaFiles(src_m3, 404 "module m3x { }", 405 "package p3; class C3 { p1.C1 c1; }"); 406 Path classes = base.resolve("classes"); 407 tb.createDirectories(classes); 408 409 testEmptyList(src, classes, "m3x="); 410 testEmptyList(src, classes, "m3x=,"); 411 } 412 413 private void testEmptyList(Path src, Path classes, String option) throws Exception { 414 String log = new JavacTask(tb, Task.Mode.CMDLINE) 415 .options("--module-source-path", src.toString(), 416 "--add-reads", option) 417 .outdir(classes) 418 .files(findJavaFiles(src)) 419 .run(Task.Expect.FAIL) 420 .writeAll() 421 .getOutput(Task.OutputKind.DIRECT); 422 423 checkOutputContains(log, 424 "javac: bad value for --add-reads option: '" + option + "'"); 425 } 426 427 @Test 428 public void testMultipleAddReads_DifferentModules(Path base) throws Exception { 429 Path src = base.resolve("src"); 430 Path src_m1 = src.resolve("m1x"); 431 tb.writeJavaFiles(src_m1, 432 "module m1x { exports p1; }", 433 "package p1; public class C1 { }"); 434 Path src_m2 = src.resolve("m2x"); 435 tb.writeJavaFiles(src_m2, 436 "module m2x { }", 437 "package p2; class C2 { p1.C1 c1; }"); 438 Path src_m3 = src.resolve("m3x"); 439 tb.writeJavaFiles(src_m3, 440 "module m3x { }", 441 "package p3; class C3 { p1.C1 c1; }"); 442 Path classes = base.resolve("classes"); 443 tb.createDirectories(classes); 444 445 new JavacTask(tb) 446 .options("--module-source-path", src.toString(), 447 "--add-reads", "m2x=m1x", 448 "--add-reads", "m3x=m1x") 449 .outdir(classes) 450 .files(findJavaFiles(src)) 451 .run() 452 .writeAll(); 453 } 454 455 @Test 456 public void testMultipleAddReads_SameModule(Path base) throws Exception { 457 Path src = base.resolve("src"); 458 Path src_m1 = src.resolve("m1x"); 459 tb.writeJavaFiles(src_m1, 460 "module m1x { exports p1; }", 461 "package p1; public class C1 { }"); 462 Path src_m2 = src.resolve("m2x"); 463 tb.writeJavaFiles(src_m2, 464 "module m2x { exports p2; }", 465 "package p2; public class C2 { }"); 466 Path src_m3 = src.resolve("m3x"); 467 tb.writeJavaFiles(src_m3, 468 "module m3x { }", 469 "package p3; class C3 { p1.C1 c1; p2.C2 c2; }"); 470 Path classes = base.resolve("classes"); 471 tb.createDirectories(classes); 472 473 new JavacTask(tb) 474 .options("--module-source-path", src.toString(), 475 "--add-reads", "m3x=m1x", 476 "--add-reads", "m3x=m2x") 477 .outdir(classes) 478 .files(findJavaFiles(src)) 479 .run() 480 .writeAll(); 481 } 482 483 @Test 484 public void testDuplicateAddReads_SameOption(Path base) throws Exception { 485 Path src = base.resolve("src"); 486 Path src_m1 = src.resolve("m1x"); 487 tb.writeJavaFiles(src_m1, 488 "module m1x { exports p1; }", 489 "package p1; public class C1 { }"); 490 Path src_m2 = src.resolve("m2x"); 491 tb.writeJavaFiles(src_m2, 492 "module m2x { exports p2; }", 493 "package p2; class C2 { p1.C1 c1; }"); 494 Path classes = base.resolve("classes"); 495 tb.createDirectories(classes); 496 497 new JavacTask(tb) 498 .options("--module-source-path", src.toString(), 499 "--add-reads", "m2x=m1x,m1x") 500 .outdir(classes) 501 .files(findJavaFiles(src)) 502 .run() 503 .writeAll(); 504 } 505 506 @Test 507 public void testDuplicateAddReads_MultipleOptions(Path base) throws Exception { 508 Path src = base.resolve("src"); 509 Path src_m1 = src.resolve("m1x"); 510 tb.writeJavaFiles(src_m1, 511 "module m1x { exports p1; }", 512 "package p1; public class C1 { }"); 513 Path src_m2 = src.resolve("m2x"); 514 tb.writeJavaFiles(src_m2, 515 "module m2x { }", 516 "package p2; class C2 { p1.C1 c1; }"); 517 Path classes = base.resolve("classes"); 518 tb.createDirectories(classes); 519 520 new JavacTask(tb) 521 .options("--module-source-path", src.toString(), 522 "--add-reads", "m2x=m1x", 523 "--add-reads", "m2x=m1x") 524 .outdir(classes) 525 .files(findJavaFiles(src)) 526 .run() 527 .writeAll(); 528 } 529 530 @Test 531 public void testRepeatedAddReads(Path base) throws Exception { 532 Path src = base.resolve("src"); 533 Path src_m1 = src.resolve("m1x"); 534 tb.writeJavaFiles(src_m1, 535 "module m1x { exports p1; }", 536 "package p1; public class C1 { }"); 537 Path src_m2 = src.resolve("m2x"); 538 tb.writeJavaFiles(src_m2, 539 "module m2x { exports p2; }", 540 "package p2; public class C2 { }"); 541 Path src_m3 = src.resolve("m3x"); 542 tb.writeJavaFiles(src_m3, 543 "module m3x { }", 544 "package p3; class C3 { p1.C1 c1; p2.C2 c2; }"); 545 Path classes = base.resolve("classes"); 546 tb.createDirectories(classes); 547 548 new JavacTask(tb) 549 .options("--module-source-path", src.toString(), 550 "--add-reads", "m3x=m1x", 551 "--add-reads", "m3x=m2x") 552 .outdir(classes) 553 .files(findJavaFiles(src)) 554 .run() 555 .writeAll(); 556 } 557 558 @Test 559 public void testNoEquals(Path base) throws Exception { 560 Path src = base.resolve("src"); 561 tb.writeJavaFiles(src, "class Dummy { }"); 562 Path classes = base.resolve("classes"); 563 tb.createDirectories(classes); 564 565 String log = new JavacTask(tb, Task.Mode.CMDLINE) 566 .options("-XDrawDiagnostics", 567 "--add-reads", "m1x:m2x") 568 .outdir(classes) 569 .files(findJavaFiles(src)) 570 .run(Task.Expect.FAIL) 571 .writeAll() 572 .getOutput(Task.OutputKind.DIRECT); 573 574 checkOutputContains(log, 575 "javac: bad value for --add-reads option: 'm1x:m2x'"); 576 } 577 578 @Test 579 public void testBadSourceName(Path base) throws Exception { 580 Path src = base.resolve("src"); 581 tb.writeJavaFiles(src, "class Dummy { }"); 582 Path classes = base.resolve("classes"); 583 tb.createDirectories(classes); 584 585 String log = new JavacTask(tb) 586 .options("-XDrawDiagnostics", 587 "--add-reads", "bad*Source=m2x") 588 .outdir(classes) 589 .files(findJavaFiles(src)) 590 .run() 591 .writeAll() 592 .getOutput(Task.OutputKind.DIRECT); 593 594 checkOutputContains(log, 595 "- compiler.warn.bad.name.for.option: --add-reads, bad*Source"); 596 } 597 598 @Test 599 public void testBadTargetName(Path base) throws Exception { 600 Path src = base.resolve("src"); 601 Path src_m1 = src.resolve("m1x"); 602 tb.writeJavaFiles(src_m1, 603 "module m1x { }", 604 "package p1; class C1 { }"); 605 Path classes = base.resolve("classes"); 606 tb.createDirectories(classes); 607 608 String log = new JavacTask(tb) 609 .options("-XDrawDiagnostics", 610 "--add-reads", "m1x=badTarget!") 611 .outdir(classes) 612 .files(findJavaFiles(src)) 613 .run() 614 .writeAll() 615 .getOutput(Task.OutputKind.DIRECT); 616 617 checkOutputContains(log, 618 "- compiler.warn.bad.name.for.option: --add-reads, badTarget!"); 619 } 620 621 @Test 622 public void testSourceNameNotFound(Path base) throws Exception { 623 Path src = base.resolve("src"); 624 Path src_m1 = src.resolve("m1x"); 625 tb.writeJavaFiles(src_m1, 626 "module m1x { exports p1; }", 627 "package p1; public class C1 { }"); 628 Path classes = base.resolve("classes"); 629 tb.createDirectories(classes); 630 631 String log = new JavacTask(tb) 632 .options("-XDrawDiagnostics", 633 "--add-reads", "missingSource=m") 634 .outdir(classes) 635 .files(findJavaFiles(src)) 636 .run() 637 .writeAll() 638 .getOutput(Task.OutputKind.DIRECT); 639 640 checkOutputContains(log, 641 "- compiler.warn.module.for.option.not.found: --add-reads, missingSource"); 642 } 643 644 @Test 645 public void testTargetNameNotFound(Path base) throws Exception { 646 Path src = base.resolve("src"); 647 Path src_m1 = src.resolve("m1x"); 648 tb.writeJavaFiles(src_m1, 649 "module m1x { exports p1; }", 650 "package p1; public class C1 { }"); 651 Path classes = base.resolve("classes"); 652 tb.createDirectories(classes); 653 654 String log = new JavacTask(tb) 655 .options("-XDrawDiagnostics", 656 "--add-reads", "m1x=missingTarget") 657 .outdir(classes) 658 .files(findJavaFiles(src)) 659 .run() 660 .writeAll() 661 .getOutput(Task.OutputKind.DIRECT); 662 663 checkOutputContains(log, 664 "- compiler.warn.module.for.option.not.found: --add-reads, missingTarget"); 665 } 666 } |