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 -modulepath
  27  * @library /tools/lib
  28  * @modules
  29  *      jdk.compiler/com.sun.tools.javac.api
  30  *      jdk.compiler/com.sun.tools.javac.main
  31  *      jdk.jdeps/com.sun.tools.javap
  32  *      jdk.jlink/jdk.tools.jmod
  33  * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.ModuleBuilder
  34  *      ModuleTestBase
  35  * @run main ModulePathTest
  36  */
  37 
  38 import java.io.File;
  39 import java.io.IOException;
  40 import java.nio.file.Files;
  41 import java.nio.file.Path;
  42 
  43 import toolbox.JarTask;
  44 import toolbox.JavacTask;
  45 import toolbox.ModuleBuilder;
  46 import toolbox.Task;
  47 import toolbox.ToolBox;
  48 
  49 public class ModulePathTest extends ModuleTestBase {
  50 
  51     public static final String PATH_SEP = File.pathSeparator;
  52 
  53     public static void main(String... args) throws Exception {
  54         ModulePathTest t = new ModulePathTest();
  55         t.runTests();
  56     }
  57 
  58     @Test
  59     public void testNotExistsOnPath(Path base) throws Exception {
  60         Path src = base.resolve("src");
  61         tb.writeJavaFiles(src, "class C { }");
  62 
  63         String log = new JavacTask(tb, Task.Mode.CMDLINE)
  64                 .options("-XDrawDiagnostics",
  65                         "-modulepath", "doesNotExist")
  66                 .files(findJavaFiles(src))
  67                 .run(Task.Expect.FAIL)
  68                 .writeAll()
  69                 .getOutput(Task.OutputKind.DIRECT);
  70 
  71         if (!log.contains("- compiler.err.illegal.argument.for.option: -modulepath, doesNotExist"))
  72             throw new Exception("expected output not found");
  73     }
  74 
  75     @Test
  76     public void testNotADirOnPath_1(Path base) throws Exception {
  77         Path src = base.resolve("src");
  78         tb.writeJavaFiles(src, "class C { }");
  79         tb.writeFile("dummy.txt", "");
  80 
  81         String log = new JavacTask(tb, Task.Mode.CMDLINE)
  82                 .options("-XDrawDiagnostics",
  83                         "-modulepath", "dummy.txt")
  84                 .files(findJavaFiles(src))
  85                 .run(Task.Expect.FAIL)
  86                 .writeAll()
  87                 .getOutput(Task.OutputKind.DIRECT);
  88 
  89         if (!log.contains("- compiler.err.illegal.argument.for.option: -modulepath, dummy.txt"))
  90             throw new Exception("expected output not found");
  91     }
  92 
  93     @Test
  94     public void testNotADirOnPath_2(Path base) throws Exception {
  95         Path src = base.resolve("src");
  96         tb.writeJavaFiles(src, "class C { }");
  97         tb.writeFile("dummy.jimage", "");
  98 
  99         String log = new JavacTask(tb, Task.Mode.CMDLINE)
 100                 .options("-XDrawDiagnostics",
 101                         "-modulepath", "dummy.jimage")
 102                 .files(findJavaFiles(src))
 103                 .run(Task.Expect.FAIL)
 104                 .writeAll()
 105                 .getOutput(Task.OutputKind.DIRECT);
 106 
 107         if (!log.contains("- compiler.err.illegal.argument.for.option: -modulepath, dummy.jimage"))
 108             throw new Exception("expected output not found");
 109     }
 110 
 111     @Test
 112     public void testExplodedModuleOnPath(Path base) throws Exception {
 113         Path modSrc = base.resolve("modSrc");
 114         tb.writeJavaFiles(modSrc,
 115                 "module m1 { exports p; }",
 116                 "package p; public class CC { }");
 117         Path modClasses = base.resolve("modClasses");
 118         Files.createDirectories(modClasses);
 119 
 120         new JavacTask(tb, Task.Mode.CMDLINE)
 121                 .outdir(modClasses)
 122                 .files(findJavaFiles(modSrc))
 123                 .run()
 124                 .writeAll();
 125 
 126         Path src = base.resolve("src");
 127         tb.writeJavaFiles(src,
 128                 "module m { requires m1 ; }",
 129                 "class C { }");
 130         Path classes = base.resolve("classes");
 131         Files.createDirectories(classes);
 132 
 133         new JavacTask(tb, Task.Mode.CMDLINE)
 134                 .outdir(classes)
 135                 .options("-modulepath", modClasses.toString())
 136                 .files(findJavaFiles(src))
 137                 .run()
 138                 .writeAll();
 139     }
 140 
 141     @Test
 142     public void testBadExplodedModuleOnPath(Path base) throws Exception {
 143         Path modClasses = base.resolve("modClasses");
 144         tb.writeFile(modClasses.resolve("module-info.class"), "module m1 { }");
 145 
 146         Path src = base.resolve("src");
 147         tb.writeJavaFiles(src,
 148                 "module m { requires m1 ; }",
 149                 "class C { }");
 150         Path classes = base.resolve("classes");
 151         Files.createDirectories(classes);
 152 
 153         String log = new JavacTask(tb, Task.Mode.CMDLINE)
 154                 .outdir(classes)
 155                 .options("-XDrawDiagnostics",
 156                         "-modulepath", modClasses.toString())
 157                 .files(findJavaFiles(src))
 158                 .run(Task.Expect.FAIL)
 159                 .writeAll()
 160                 .getOutput(Task.OutputKind.DIRECT);
 161 
 162         if (!log.contains("- compiler.err.locn.bad.module-info: " + modClasses.toString()))
 163             throw new Exception("expected output not found");
 164     }
 165 
 166     @Test
 167     public void testAutoJarOnPath(Path base) throws Exception {
 168         Path jarSrc = base.resolve("jarSrc");
 169         tb.writeJavaFiles(jarSrc,
 170                 "package p; public class CC { }");
 171         Path jarClasses = base.resolve("jarClasses");
 172         Files.createDirectories(jarClasses);
 173 
 174         new JavacTask(tb, Task.Mode.CMDLINE)
 175                 .outdir(jarClasses)
 176                 .files(findJavaFiles(jarSrc))
 177                 .run()
 178                 .writeAll();
 179 
 180         Path moduleJar = base.resolve("m1.jar");
 181         new JarTask(tb, moduleJar)
 182           .baseDir(jarClasses)
 183           .files("p/CC.class")
 184           .run();
 185 
 186         Path src = base.resolve("src");
 187         tb.writeJavaFiles(src, "class C { p.CC cc; }");
 188         Path classes = base.resolve("classes");
 189         Files.createDirectories(classes);
 190 
 191         new JavacTask(tb, Task.Mode.CMDLINE)
 192                 .outdir(classes)
 193                 .options("-modulepath", moduleJar.toString(), "-addmods", "m1")
 194                 .files(findJavaFiles(src))
 195                 .run()
 196                 .writeAll();
 197     }
 198 
 199     @Test
 200     public void testModJarOnPath(Path base) throws Exception {
 201         Path jarSrc = base.resolve("jarSrc");
 202         tb.writeJavaFiles(jarSrc,
 203                 "module m1 { exports p; }",
 204                 "package p; public class CC { }");
 205         Path jarClasses = base.resolve("jarClasses");
 206         Files.createDirectories(jarClasses);
 207 
 208         new JavacTask(tb, Task.Mode.CMDLINE)
 209                 .outdir(jarClasses)
 210                 .files(findJavaFiles(jarSrc))
 211                 .run()
 212                 .writeAll();
 213 
 214         Path moduleJar = base.resolve("myModule.jar"); // deliberately not m1
 215         new JarTask(tb, moduleJar)
 216           .baseDir(jarClasses)
 217           .files("module-info.class", "p/CC.class")
 218           .run();
 219 
 220         Path src = base.resolve("src");
 221         tb.writeJavaFiles(src,
 222                 "module m { requires m1 ; }",
 223                 "class C { }");
 224         Path classes = base.resolve("classes");
 225         Files.createDirectories(classes);
 226 
 227         new JavacTask(tb, Task.Mode.CMDLINE)
 228                 .outdir(classes)
 229                 .options("-modulepath", moduleJar.toString())
 230                 .files(findJavaFiles(src))
 231                 .run()
 232                 .writeAll();
 233     }
 234 
 235     @Test
 236     public void testBadJarOnPath(Path base) throws Exception {
 237         Path src = base.resolve("src");
 238         tb.writeJavaFiles(src, "class C { }");
 239         tb.writeFile("dummy.jar", "");
 240 
 241         String log = new JavacTask(tb, Task.Mode.CMDLINE)
 242                 .options("-XDrawDiagnostics",
 243                         "-modulepath", "dummy.jar")
 244                 .files(findJavaFiles(src))
 245                 .run(Task.Expect.FAIL)
 246                 .writeAll()
 247                 .getOutput(Task.OutputKind.DIRECT);
 248 
 249         if (!log.contains("- compiler.err.locn.cant.read.file: dummy.jar"))
 250             throw new Exception("expected output not found");
 251     }
 252 
 253     @Test
 254     public void testJModOnPath(Path base) throws Exception {
 255         Path jmodSrc = base.resolve("jmodSrc");
 256         tb.writeJavaFiles(jmodSrc,
 257                 "module m1 { exports p; }",
 258                 "package p; public class CC { }");
 259         Path jmodClasses = base.resolve("jmodClasses");
 260         Files.createDirectories(jmodClasses);
 261 
 262         new JavacTask(tb, Task.Mode.CMDLINE)
 263                 .outdir(jmodClasses)
 264                 .files(findJavaFiles(jmodSrc))
 265                 .run()
 266                 .writeAll();
 267 
 268         Path jmod = base.resolve("myModule.jmod"); // deliberately not m1
 269         jmod(jmodClasses, jmod);
 270 
 271         Path src = base.resolve("src");
 272         tb.writeJavaFiles(src,
 273                 "module m { requires m1 ; }",
 274                 "class C { }");
 275         Path classes = base.resolve("classes");
 276         Files.createDirectories(classes);
 277 
 278         new JavacTask(tb, Task.Mode.CMDLINE)
 279                 .outdir(classes)
 280                 .options("-modulepath", jmod.toString())
 281                 .files(findJavaFiles(src))
 282                 .run()
 283                 .writeAll();
 284     }
 285 
 286     @Test
 287     public void testBadJModOnPath(Path base) throws Exception {
 288         Path src = base.resolve("src");
 289         tb.writeJavaFiles(src, "class C { }");
 290         tb.writeFile("dummy.jmod", "");
 291 
 292         String log = new JavacTask(tb, Task.Mode.CMDLINE)
 293                 .options("-XDrawDiagnostics",
 294                         "-modulepath", "dummy.jmod")
 295                 .files(findJavaFiles(src))
 296                 .run(Task.Expect.FAIL)
 297                 .writeAll()
 298                 .getOutput(Task.OutputKind.DIRECT);
 299 
 300         if (!log.contains("- compiler.err.locn.cant.read.file: dummy.jmod"))
 301             throw new Exception("expected output not found");
 302     }
 303 
 304     @Test
 305     public void relativePath(Path base) throws Exception {
 306         Path modules = base.resolve("modules");
 307         new ModuleBuilder(tb, "m1").build(modules);
 308 
 309         Path src = base.resolve("src");
 310         tb.writeJavaFiles(src, "module m2 { requires m1; }", "class A { }");
 311 
 312         new JavacTask(tb, Task.Mode.CMDLINE)
 313                 .options("-XDrawDiagnostics",
 314                         "-modulepath", modules + "/./../modules")
 315                 .files(findJavaFiles(src))
 316                 .run()
 317                 .writeAll();
 318     }
 319 
 320     @Test
 321     public void duplicatePaths_1(Path base) throws Exception {
 322         Path modules = base.resolve("modules");
 323         new ModuleBuilder(tb, "m1").build(modules);
 324 
 325         Path src = base.resolve("src");
 326         tb.writeJavaFiles(src, "module m2 { requires m1; }", "class A { }");
 327 
 328         new JavacTask(tb, Task.Mode.CMDLINE)
 329                 .options("-XDrawDiagnostics",
 330                         "-modulepath", modules + "/./../modules" + PATH_SEP + modules)
 331                 .files(findJavaFiles(src))
 332                 .run()
 333                 .writeAll();
 334     }
 335 
 336     @Test
 337     public void duplicatePaths_2(Path base) throws Exception {
 338         Path modules = base.resolve("modules");
 339         new ModuleBuilder(tb, "m1").build(modules);
 340 
 341         Path src = base.resolve("src");
 342         tb.writeJavaFiles(src, "module m2 { requires m1; }", "class A { }");
 343 
 344         new JavacTask(tb, Task.Mode.CMDLINE)
 345                 .options("-XDrawDiagnostics",
 346                         "-modulepath", modules.toString(),
 347                         "-modulepath", modules.toString())
 348                 .files(findJavaFiles(src))
 349                 .run()
 350                 .writeAll();
 351     }
 352 
 353     @Test
 354     public void oneModuleHidesAnother(Path base) throws Exception {
 355         Path modules = base.resolve("modules");
 356         new ModuleBuilder(tb, "m1")
 357                 .exports("pkg1")
 358                 .classes("package pkg1; public class E { }")
 359                 .build(modules);
 360 
 361         Path deepModuleDirSrc = base.resolve("deepModuleDirSrc");
 362         Path deepModuleDir = modules.resolve("deepModuleDir");
 363         new ModuleBuilder(tb, "m1")
 364                 .exports("pkg2")
 365                 .classes("package pkg2; public class E { }")
 366                 .build(deepModuleDirSrc, deepModuleDir);
 367 
 368         Path src = base.resolve("src");
 369         tb.writeJavaFiles(src, "module m2 { requires m1; }", " package p; class A { void main() { pkg2.E.class.getName(); } }");
 370 
 371         new JavacTask(tb, Task.Mode.CMDLINE)
 372                 .options("-XDrawDiagnostics",
 373                         "-modulepath", deepModuleDir + PATH_SEP + modules)
 374                 .files(findJavaFiles(src))
 375                 .run()
 376                 .writeAll();
 377     }
 378 
 379     @Test
 380     public void modulesInDifferentContainers(Path base) throws Exception {
 381         Path modules = base.resolve("modules");
 382         new ModuleBuilder(tb, "m1")
 383                 .exports("one")
 384                 .classes("package one; public class A { }")
 385                 .build(modules);
 386 
 387         new ModuleBuilder(tb, "m2")
 388                 .requires("m1", modules)
 389                 .build(base.resolve("tmp"));
 390         jar(base.resolve("tmp/m2"), modules.resolve("m2.jar"));
 391 
 392         new ModuleBuilder(tb, "m3")
 393                 .requires("m2", modules)
 394                 .build(base.resolve("tmp"));
 395         jmod(base.resolve("tmp/m3"), modules.resolve("m3.jmod"));
 396 
 397         Path src = base.resolve("src");
 398         tb.writeJavaFiles(src, "module m { requires m3; requires m2; requires m1; }",
 399                 "package p; class A { void main() { one.A.class.getName(); } }");
 400 
 401         new JavacTask(tb, Task.Mode.CMDLINE)
 402                 .options("-XDrawDiagnostics",
 403                         "-modulepath", modules.toString())
 404                 .files(findJavaFiles(src))
 405                 .run()
 406                 .writeAll();
 407     }
 408 
 409     private void jar(Path dir, Path jar) throws IOException {
 410         new JarTask(tb, jar)
 411                 .baseDir(dir)
 412                 .files(".")
 413                 .run()
 414                 .writeAll();
 415     }
 416 
 417     private void jmod(Path dir, Path jmod) throws Exception {
 418         String[] args = {
 419                 "create",
 420                 "--class-path", dir.toString(),
 421                 jmod.toString()
 422         };
 423         jdk.tools.jmod.Main.run(args, System.out);
 424     }
 425 }