Modules.java revision 3792:d516975e8110
1290000Sglebius/* 2132451Sroberto * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3290000Sglebius * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4290000Sglebius * 5290000Sglebius * 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 8159305 8166127 27 * @summary Tests primarily the module graph computations. 28 * @modules 29 * jdk.javadoc/jdk.javadoc.internal.api 30 * jdk.javadoc/jdk.javadoc.internal.tool 31 * jdk.compiler/com.sun.tools.javac.api 32 * jdk.compiler/com.sun.tools.javac.main 33 * @library /tools/lib 34 * @build toolbox.ToolBox toolbox.TestRunner 35 * @run main Modules 36 */ 37 38import java.io.IOException; 39import java.nio.file.Files; 40import java.nio.file.Path; 41 42import toolbox.*; 43import toolbox.Task.Expect; 44import toolbox.Task.OutputKind; 45 46public class Modules extends ModuleTestBase { 47 48 public static void main(String... args) throws Exception { 49 new Modules().runTests(); 50 } 51 52 @Test 53 public void testBasicMoption(Path base) throws Exception { 54 Files.createDirectory(base); 55 Path src = base.resolve("src"); 56 ModuleBuilder mb = new ModuleBuilder(tb, "m1"); 57 mb.comment("The first module.") 58 .exports("pub") 59 .classes("package pub; /** Class A */ public class A {}") 60 .classes("package pro; /** Class B */ public class B {}") 61 .write(src); 62 execTask("--module-source-path", src.toString(), 63 "--module", "m1"); 64 checkModulesSpecified("m1"); 65 checkPackagesIncluded("pub"); 66 checkTypesIncluded("pub.A"); 67 } 68 69 @Test 70 public void testMultipleModulesOption1(Path base) throws Exception { 71 Path src = base.resolve("src"); 72 73 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 74 mb1.comment("The first module.") 75 .exports("m1pub") 76 .requires("m2") 77 .classes("package m1pub; /** Class A */ public class A {}") 78 .classes("package m1pro; /** Class B */ public class B {}") 79 .write(src); 80 81 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 82 mb2.comment("The second module.") 83 .exports("m2pub") 84 .classes("package m2pub; /** Class A */ public class A {}") 85 .classes("package m2pro; /** Class B */ public class B {}") 86 .write(src); 87 execTask("--module-source-path", src.toString(), 88 "--module", "m1,m2"); 89 checkModulesSpecified("m1", "m2"); 90 checkPackagesIncluded("m1pub", "m2pub"); 91 checkTypesIncluded("m1pub.A", "m2pub.A"); 92 93 } 94 95 @Test 96 public void testMultipleModulesAggregatedModuleOption(Path base) throws Exception { 97 Path src = base.resolve("src"); 98 99 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 100 mb1.comment("The first module.") 101 .exports("m1pub") 102 .requires("m2") 103 .classes("package m1pub; /** Class A */ public class A {}") 104 .classes("package m1pro; /** Class B */ public class B {}") 105 .write(src); 106 107 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 108 mb2.comment("The second module.") 109 .exports("m2pub") 110 .classes("package m2pub; /** Class A */ public class A {}") 111 .classes("package m2pro; /** Class B */ public class B {}") 112 .write(src); 113 execTask("--module-source-path", src.toString(), 114 "--module", "m1", 115 "--module", "m2"); 116 checkModulesSpecified("m1", "m2"); 117 checkPackagesIncluded("m1pub", "m2pub"); 118 checkTypesIncluded("m1pub.A", "m2pub.A"); 119 120 } 121 122 @Test 123 public void testModulePathOption(Path base) throws Exception { 124 Path src = base.resolve("src"); 125 Path modulePath = base.resolve("modules"); 126 127 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 128 mb1.comment("Module on module path.") 129 .exports("pkg1") 130 .classes("package pkg1; /** Class A */ public class A { }") 131 .build(modulePath); 132 133 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 134 mb2.comment("The second module.") 135 .exports("pkg2") 136 .requires("m1") 137 .classes("package pkg2; /** Class B */ public class B { /** Field f */ public pkg1.A f; }") 138 .write(src); 139 execTask("--module-source-path", src.toString(), 140 "--module-path", modulePath.toString(), 141 "--module", "m2"); 142 checkModulesSpecified("m2"); 143 checkPackagesIncluded("pkg2"); 144 checkMembersSelected("pkg2.B.f"); 145 146 // module path option "-p" 147 execTask("--module-source-path", src.toString(), 148 "-p", modulePath.toString(), 149 "--module", "m2"); 150 // no module path 151 execNegativeTask("--module-source-path", src.toString(), 152 "--module", "m2"); 153 assertErrorPresent("error: module not found: m1"); 154 } 155 156 @Test 157 public void testUpgradeModulePathOption(Path base) throws Exception { 158 Path src = base.resolve("src"); 159 Path modulePath = base.resolve("modules"); 160 Path upgradePath = base.resolve("upgrades"); 161 162 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 163 mb1.comment("Module on module path.") 164 .exports("pkg1") 165 .classes("package pkg1; /** Class A */ public class A { }") 166 .build(modulePath); 167 168 ModuleBuilder mbUpgrade = new ModuleBuilder(tb, "m1"); 169 mbUpgrade.comment("Module on upgrade module path.") 170 .exports("pkg1") 171 .classes("package pkg1; /** Class C */ public class C { }") 172 .build(upgradePath); 173 174 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 175 mb2.comment("The second module.") 176 .exports("pkg2") 177 .requires("m1") 178 .classes("package pkg2; /** Class B */ public class B { /** Field f */ public pkg1.C f; }") 179 .write(src); 180 execTask("--module-source-path", src.toString(), 181 "--module-path", modulePath.toString(), 182 "--upgrade-module-path", upgradePath.toString(), 183 "--module", "m2"); 184 checkModulesSpecified("m2"); 185 checkPackagesIncluded("pkg2"); 186 checkMembersSelected("pkg2.B.f"); 187 188 // no upgrade module path 189 execNegativeTask("--module-source-path", src.toString(), 190 "--module-path", modulePath.toString(), 191 "--module", "m2"); 192 assertErrorPresent("error: cannot find symbol"); 193 194 // dependency from module path 195 ModuleBuilder mb3 = new ModuleBuilder(tb, "m3"); 196 mb3.comment("The third module.") 197 .exports("pkg3") 198 .requires("m1") 199 .classes("package pkg3; /** Class Z */ public class Z { /** Field f */ public pkg1.A f; }") 200 .write(src); 201 execNegativeTask("--module-source-path", src.toString(), 202 "--module-path", modulePath.toString(), 203 "--upgrade-module-path", upgradePath.toString(), 204 "--module", "m3"); 205 assertErrorPresent("Z.java:1: error: cannot find symbol"); 206 } 207 208 @Test 209 public void testAddModulesOption(Path base) throws Exception { 210 Path src = base.resolve("src"); 211 Path modulePath = base.resolve("modules"); 212 213 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 214 mb1.comment("Module on module path.") 215 .exports("pkg1") 216 .classes("package pkg1; /** Class A */ public class A { }") 217 .build(modulePath); 218 219 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 220 mb2.comment("The second module.") 221 .exports("pkg2") 222 .classes("package pkg2; /** @see pkg1.A */ public class B { }") 223 .write(src); 224 225 Path out = base.resolve("out-1"); 226 Files.createDirectories(out); 227 String log = new JavadocTask(tb) 228 .outdir(out) 229 .options("--module-source-path", src.toString(), 230 "--module-path", modulePath.toString(), 231 "--module", "m2") 232 .run(Expect.FAIL) 233 .writeAll() 234 .getOutput(OutputKind.DIRECT); 235 if (!log.contains("B.java:1: error: reference not found")) { 236 throw new Exception("Error not found"); 237 } 238 239 out = base.resolve("out-2"); 240 Files.createDirectories(out); 241 new JavadocTask(tb) 242 .outdir(out) 243 .options("--module-source-path", src.toString(), 244 "--module-path", modulePath.toString(), 245 "--add-modules", "m1", 246 "--module", "m2") 247 .run() 248 .writeAll(); 249 } 250 251 @Test 252 public void testLimitModulesOption(Path base) throws Exception { 253 Path src = base.resolve("src"); 254 Path modulePath = base.resolve("modules"); 255 256 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 257 mb1.comment("Module on module path.") 258 .build(modulePath); 259 260 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 261 mb2.comment("The second module.") 262 .exports("pkg2") 263 .requires("m1") 264 .classes("package pkg2; /** Class B */ public class B { }") 265 .write(src); 266 267 execNegativeTask("--module-source-path", src.toString(), 268 "--module-path", modulePath.toString(), 269 "--limit-modules", "java.base", 270 "--module", "m2"); 271 assertErrorPresent("error: module not found: m1"); 272 } 273 274 @Test 275 public void testAddExportsOption(Path base) throws Exception { 276 Path src = base.resolve("src"); 277 Path modulePath = base.resolve("modules"); 278 279 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 280 mb1.comment("Module on module path.") 281 .classes("package pkg1; /** Class A */ public class A { }") 282 .build(modulePath); 283 284 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 285 mb2.comment("The second module.") 286 .exports("pkg2") 287 .requires("m1") 288 .classes("package pkg2; /** Class B */ public class B { /** Field f */ public pkg1.A f; }") 289 .write(src); 290 execTask("--module-source-path", src.toString(), 291 "--module-path", modulePath.toString(), 292 "--add-exports", "m1/pkg1=m2", 293 "--module", "m2"); 294 checkModulesSpecified("m2"); 295 checkPackagesIncluded("pkg2"); 296 checkMembersSelected("pkg2.B.f"); 297 } 298 299 @Test 300 public void testPatchModuleOption(Path base) throws Exception { 301 Path src = base.resolve("src"); 302 Path modulePath = base.resolve("modules"); 303 Path patchPath = base.resolve("patch"); 304 305 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 306 mb1.comment("Module on module path.") 307 .exports("pkg1") 308 .classes("package pkg1; /** Class A */ public class A { }") 309 .build(modulePath); 310 311 tb.writeJavaFiles(patchPath, "package pkg1; /** Class A */ public class A { public static int k; }"); 312 new JavacTask(tb) 313 .files(patchPath.resolve("pkg1/A.java")) 314 .run(); 315 316 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 317 mb2.comment("The second module.") 318 .exports("pkg2") 319 .requires("m1") 320 .classes("package pkg2; /** Class B */ public class B { /** Field f */ public int f = pkg1.A.k; }") 321 .write(src); 322 execTask("--module-source-path", src.toString(), 323 "--patch-module", "m1=" + patchPath.toString(), 324 "--module-path", modulePath.toString(), 325 "--module", "m2"); 326 checkModulesSpecified("m2"); 327 checkPackagesIncluded("pkg2"); 328 checkMembersSelected("pkg2.B.f"); 329 } 330 331 @Test 332 public void testAddReadsOption(Path base) throws Exception { 333 Path src = base.resolve("src"); 334 Path modulePath = base.resolve("modules"); 335 336 ModuleBuilder mb1 = new ModuleBuilder(tb, "m1"); 337 mb1.comment("Module on module path.") 338 .exports("pkg1") 339 .classes("package pkg1; /** Class A */ public class A {}") 340 .build(modulePath); 341 342 ModuleBuilder mb2 = new ModuleBuilder(tb, "m2"); 343 mb2.comment("The second module.") 344 .exports("pkg2") 345 .classes("package pkg2; /** Class B */ public class B { /** Field f */ public pkg1.A f;}") 346 .write(src); 347 execTask("--module-source-path", src.toString(), 348 "--module-path", modulePath.toString(), 349 "--add-modules", "m1", 350 "--add-reads", "m2=m1", 351 "--module", "m2"); 352 checkModulesSpecified("m2"); 353 checkPackagesIncluded("pkg2"); 354 checkMembersSelected("pkg2.B.f"); 355 } 356 357 @Test 358 public void testModuleOptionsWithLegacy(Path base) throws Exception { 359 Files.createDirectory(base); 360 Path src = base.resolve("src"); 361 Path classpath = base.resolve("classpath"); 362 Path modulePath = base.resolve("modules"); 363 364 tb.writeJavaFiles(classpath, "package pkg1; /** Class C */ public class C { }"); 365 new JavacTask(tb) 366 .files(classpath.resolve("pkg1/C.java")) 367 .run(); 368 369 ModuleBuilder mb = new ModuleBuilder(tb, "m1"); 370 mb.comment("The first module.") 371 .exports("pub") 372 .classes("package pub; /** Class M */ public class M { }") 373 .build(modulePath); 374 375 tb.writeJavaFiles(src, "package pkg; /** Class L */ public class L { public pkg1.C f1; public pub.M f2; }"); 376 377 execTask("--source-path", src.toString(), 378 "--class-path", classpath.toString(), 379 "--module-path", modulePath.toString(), 380 "--add-modules", "m1", 381 "pkg"); 382 checkPackagesIncluded("pkg"); 383 checkTypesIncluded("pkg.L"); 384 checkMembersSelected("pkg.L.f1"); 385 checkMembersSelected("pkg.L.f2"); 386 assertAbsent("error", OutputKind.DIRECT); 387 } 388 389 /** 390 * Tests diamond graph, inspired by javac diamond tests. 391 * 392 * 393 * Module M : test module, with variable requires 394 * 395 * Module N : 396 * requires transitive O ---> Module O: 397 * requires J ----> Module J: 398 * exports openO exports openJ 399 * 400 * 401 * Module L : 402 * requires transitive P ---> Module P: 403 * exports openP 404 * 405 * 406 */ 407 408 @Test 409 public void testExpandRequiresNone(Path base) throws Exception { 410 Path src = base.resolve("src"); 411 412 createAuxiliaryModules(src); 413 414 new ModuleBuilder(tb, "M") 415 .comment("The M module.") 416 .requires("N", src) 417 .requires("L", src) 418 .requires("O", src) 419 .exports("p") 420 .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") 421 .write(src); 422 423 execTask("--module-source-path", src.toString(), 424 "--module", "M"); 425 426 checkModulesSpecified("M"); 427 checkModulesIncluded("M"); 428 checkPackagesIncluded("p"); 429 checkTypesIncluded("p.Main"); 430 checkPackagesNotIncluded(".*open.*"); 431 } 432 433 @Test 434 public void testExpandRequiresTransitive(Path base) throws Exception { 435 Path src = base.resolve("src"); 436 437 createAuxiliaryModules(src); 438 439 new ModuleBuilder(tb, "M") 440 .comment("The M module.") 441 .requiresTransitive("N", src) 442 .requires("L", src) 443 .exports("p") 444 .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") 445 .write(src); 446 447 execTask("--module-source-path", src.toString(), 448 "--module", "M", 449 "--expand-requires", "transitive"); 450 451 checkModulesSpecified("M", "N", "O"); 452 checkModulesIncluded("M", "N", "O"); 453 checkPackagesIncluded("p", "openN", "openO"); 454 checkTypesIncluded("p.Main", "openN.N", "openO.O"); 455 } 456 457 @Test 458 public void testExpandRequiresAll(Path base) throws Exception { 459 Path src = base.resolve("src"); 460 461 createAuxiliaryModules(src); 462 463 new ModuleBuilder(tb, "M") 464 .comment("The M module.") 465 .requiresTransitive("N", src) 466 .requires("L", src) 467 .requires("O", src) 468 .exports("p") 469 .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") 470 .write(src); 471 472 execTask("--module-source-path", src.toString(), 473 "--module", "M", 474 "--expand-requires", "all"); 475 476 checkModulesSpecified("M", "java.base", "N", "L", "O"); 477 checkModulesIncluded("M", "java.base", "N", "L", "O"); 478 checkModulesNotIncluded("P", "J", "Q"); 479 checkPackagesIncluded("p", "openN", "openL", "openO"); 480 checkPackagesNotIncluded(".*openP.*", ".*openJ.*"); 481 checkTypesIncluded("p.Main", "openN.N", "openL.L", "openO.O"); 482 checkTypesNotIncluded(".*openP.*", ".*openJ.*"); 483 } 484 485 @Test 486 public void testMissingModule(Path base) throws Exception { 487 Path src = base.resolve("src"); 488 489 createAuxiliaryModules(src); 490 491 new ModuleBuilder(tb, "M") 492 .comment("The M module.") 493 .requiresTransitive("N", src) 494 .requires("L", src) 495 .requires("O", src) 496 .exports("p") 497 .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") 498 .write(src); 499 500 execNegativeTask("--module-source-path", src.toString(), 501 "--module", "MIA", 502 "--expand-requires", "all"); 503 504 assertErrorPresent("javadoc: error - module MIA not found."); 505 } 506 507 @Test 508 public void testMissingModuleMultiModuleCmdline(Path base) throws Exception { 509 Path src = base.resolve("src"); 510 511 createAuxiliaryModules(src); 512 513 new ModuleBuilder(tb, "M") 514 .comment("The M module.") 515 .requiresTransitive("N", src) 516 .requires("L", src) 517 .requires("O", src) 518 .exports("p") 519 .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") 520 .write(src); 521 522 execNegativeTask("--module-source-path", src.toString(), 523 "--module", "M,N,L,MIA,O,P", 524 "--expand-requires", "all"); 525 526 assertErrorPresent("javadoc: error - module MIA not found"); 527 } 528 529 void createAuxiliaryModules(Path src) throws IOException { 530 531 new ModuleBuilder(tb, "J") 532 .comment("The J module.") 533 .exports("openJ") 534 .classes("package openJ; /** Class J open. */ public class J { }") 535 .classes("package closedJ; /** Class J closed. */ public class J { }") 536 .write(src); 537 538 new ModuleBuilder(tb, "L") 539 .comment("The L module.") 540 .exports("openL") 541 . requiresTransitive("P") 542 .classes("package openL; /** Class L open */ public class L { }") 543 .classes("package closedL; /** Class L closed */ public class L { }") 544 .write(src); 545 546 new ModuleBuilder(tb, "N") 547 .comment("The N module.") 548 .exports("openN") 549 .requiresTransitive("O") 550 .classes("package openN; /** Class N open */ public class N { }") 551 .classes("package closedN; /** Class N closed */ public class N { }") 552 .write(src); 553 554 new ModuleBuilder(tb, "O") 555 .comment("The O module.") 556 .exports("openO") 557 .requires("J") 558 .classes("package openO; /** Class O open. */ public class O { openJ.J j; }") 559 .classes("package closedO; /** Class O closed. */ public class O { }") 560 .write(src); 561 562 new ModuleBuilder(tb, "P") 563 .comment("The O module.") 564 .exports("openP") 565 .requires("J") 566 .classes("package openP; /** Class O open. */ public class O { openJ.J j; }") 567 .classes("package closedP; /** Class O closed. */ public class O { }") 568 .write(src); 569 570 new ModuleBuilder(tb, "Q") 571 .comment("The Q module.") 572 .exports("openQ") 573 .requires("J") 574 .classes("package openQ; /** Class Q open. */ public class Q { openJ.J j; }") 575 .classes("package closedQ; /** Class Q closed. */ public class Q { }") 576 .write(src); 577 578 } 579} 580