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 test module/package conflicts
  27  * @library /tools/lib
  28  * @modules
  29  *      jdk.compiler/com.sun.tools.javac.api
  30  *      jdk.compiler/com.sun.tools.javac.main
  31  * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
  32  * @run main PackageConflictTest
  33  */
  34 
  35 import java.nio.file.Files;
  36 import java.nio.file.Path;
  37 import java.util.Arrays;
  38 import java.util.List;
  39 
  40 import toolbox.JavacTask;
  41 import toolbox.ModuleBuilder;
  42 import toolbox.Task;
  43 import toolbox.ToolBox;
  44 
  45 public class PackageConflictTest extends ModuleTestBase {
  46     public static void main(String... args) throws Exception {
  47         PackageConflictTest t = new PackageConflictTest();
  48         t.runTests();
  49     }
  50 
  51     @Test
  52     public void testSimple(Path base) throws Exception {
  53         Path src = base.resolve("src");
  54         tb.writeJavaFiles(src,
  55                 "package java.util; public class MyList { }");
  56         Path classes = base.resolve("classes");
  57         Files.createDirectories(classes);
  58 
  59         String log = new JavacTask(tb)
  60                 .options("-XDrawDiagnostics")
  61                 .outdir(classes)
  62                 .files(findJavaFiles(src))
  63                 .run(Task.Expect.FAIL)
  64                 .writeAll()
  65                 .getOutput(Task.OutputKind.DIRECT);
  66 
  67         if (!log.contains("MyList.java:1:1: compiler.err.package.in.other.module: java.base"))
  68             throw new Exception("expected output not found");
  69     }
  70 
  71     @Test
  72     public void testDisjoint(Path base) throws Exception {
  73         Path m1 = base.resolve("m1");
  74         Path m2 = base.resolve("m2");
  75         tb.writeJavaFiles(m1,
  76                           "module m1 { }",
  77                           "package test; public class A { }");
  78         tb.writeJavaFiles(m2,
  79                           "module m2 { }",
  80                           "package test; public class B { }");
  81         Path classes = base.resolve("classes");
  82         Files.createDirectories(classes);
  83 
  84         new JavacTask(tb)
  85           .options("-Werror", "--module-source-path", base.toString())
  86           .outdir(classes)
  87           .files(findJavaFiles(base))
  88           .run()
  89           .writeAll();
  90     }
  91 
  92     @Test
  93     public void testConflictInDependencies(Path base) throws Exception {
  94         Path m1 = base.resolve("m1");
  95         Path m2 = base.resolve("m2");
  96         Path m3 = base.resolve("m3");
  97         tb.writeJavaFiles(m1,
  98                           "module m1 { exports test; }",
  99                           "package test; public class A { }");
 100         tb.writeJavaFiles(m2,
 101                           "module m2 { exports test; }",
 102                           "package test; public class B { }");
 103         tb.writeJavaFiles(m3,
 104                           "module m3 { requires m1; requires m2; }",
 105                           "package impl; public class Impl { }");
 106         Path classes = base.resolve("classes");
 107         Files.createDirectories(classes);
 108 
 109         List<String> log = new JavacTask(tb)
 110                        .options("-XDrawDiagnostics", "--module-source-path", base.toString())
 111                        .outdir(classes)
 112                        .files(findJavaFiles(base))
 113                        .run(Task.Expect.FAIL)
 114                        .writeAll()
 115                        .getOutputLines(Task.OutputKind.DIRECT);
 116 
 117         List<String> expected =
 118                 Arrays.asList("module-info.java:1:1: compiler.err.package.clash.from.requires: m3, test, m1, m2",
 119                               "1 error");
 120 
 121         if (!expected.equals(log)) {
 122             throw new AssertionError("Unexpected output: " + log);
 123         }
 124     }
 125 
 126     @Test
 127     public void testSimple2(Path base) throws Exception {
 128         Path modSrc = base.resolve("modSrc");
 129         Path modules = base.resolve("modules");
 130         new ModuleBuilder(tb, "N")
 131                 .exports("pack")
 132                 .classes("package pack; public class A { }")
 133                 .build(modules);
 134         new ModuleBuilder(tb, "M")
 135                 .requires("N")
 136                 .classes("package pack; public class B { pack.A f; }")
 137                 .write(modSrc);
 138 
 139         String log = new JavacTask(tb)
 140                 .options("-XDrawDiagnostics", "-p", modules.toString())
 141                 .outdir(Files.createDirectories(base.resolve("classes")))
 142                 .files(findJavaFiles(modSrc.resolve("M")))
 143                 .run(Task.Expect.FAIL)
 144                 .writeAll()
 145                 .getOutput(Task.OutputKind.DIRECT);
 146 
 147         if (!log.contains("B.java:1:1: compiler.err.package.in.other.module: N"))
 148             throw new Exception("expected output not found");
 149     }
 150 
 151     @Test
 152     public void testPrivateConflict(Path base) throws Exception {
 153         Path modSrc = base.resolve("modSrc");
 154         new ModuleBuilder(tb, "N")
 155                 .exports("publ")
 156                 .classes("package pack; public class A { }")
 157                 .classes("package publ; public class B { }")
 158                 .write(modSrc);
 159         new ModuleBuilder(tb, "M")
 160                 .requires("N")
 161                 .classes("package pack; public class C { publ.B b; }")
 162                 .write(modSrc);
 163 
 164         String log = new JavacTask(tb)
 165                 .options("-XDrawDiagnostics", "--module-source-path", modSrc.toString())
 166                 .outdir(Files.createDirectories(base.resolve("classes")))
 167                 .files(findJavaFiles(modSrc))
 168                 .run(Task.Expect.SUCCESS)
 169                 .writeAll()
 170                 .getOutput(Task.OutputKind.DIRECT);
 171 
 172         if (!log.contains(""))
 173             throw new Exception("unexpected output not found");
 174 
 175     }
 176 
 177     @Test
 178     public void testPrivateConflictOnModulePath(Path base) throws Exception {
 179         Path modSrc = base.resolve("modSrc");
 180         Path modules = base.resolve("modules");
 181         new ModuleBuilder(tb, "N")
 182                 .exports("publ")
 183                 .classes("package pack; public class A { }")
 184                 .classes("package publ; public class B { }")
 185                 .build(modules);
 186         new ModuleBuilder(tb, "M")
 187                 .requires("N")
 188                 .classes("package pack; public class C { publ.B b; }")
 189                 .write(modSrc);
 190 
 191         String log = new JavacTask(tb)
 192                 .options("-XDrawDiagnostics", "-p", modules.toString())
 193                 .outdir(Files.createDirectories(base.resolve("classes")))
 194                 .files(findJavaFiles(modSrc.resolve("M")))
 195                 .run(Task.Expect.SUCCESS)
 196                 .writeAll()
 197                 .getOutput(Task.OutputKind.DIRECT);
 198 
 199         if (!log.contains(""))
 200             throw new Exception("expected output not found");
 201 
 202     }
 203 
 204     @Test
 205     public void testRequiresConflictExports(Path base) throws Exception {
 206         Path modSrc = base.resolve("modSrc");
 207         Path modules = base.resolve("modules");
 208         new ModuleBuilder(tb, "M")
 209                 .exports("pack")
 210                 .classes("package pack; public class A { }")
 211                 .build(modules);
 212         new ModuleBuilder(tb, "N")
 213                 .exports("pack")
 214                 .classes("package pack; public class B { }")
 215                 .build(modules);
 216         new ModuleBuilder(tb, "K")
 217                 .requires("M")
 218                 .requires("N")
 219                 .classes("package pkg; public class C { pack.A a; pack.B b; }")
 220                 .write(modSrc);
 221 
 222         List<String> log = new JavacTask(tb)
 223                 .options("-XDrawDiagnostics", "-p", modules.toString())
 224                 .outdir(Files.createDirectories(base.resolve("classes")))
 225                 .files(findJavaFiles(modSrc.resolve("K")))
 226                 .run(Task.Expect.FAIL)
 227                 .writeAll()
 228                 .getOutputLines(Task.OutputKind.DIRECT);
 229 
 230         List<String> expected =
 231                 Arrays.asList("module-info.java:1:1: compiler.err.package.clash.from.requires: K, pack, M, N",
 232                         "1 error");
 233         if (!log.containsAll(expected))
 234             throw new Exception("expected output not found");
 235     }
 236 
 237     @Test
 238     public void testQualifiedExportsToDifferentModules(Path base) throws Exception {
 239         Path modSrc = base.resolve("modSrc");
 240         new ModuleBuilder(tb, "U").write(modSrc);
 241         new ModuleBuilder(tb, "M")
 242                 .exports("pkg to U")
 243                 .classes("package pkg; public class A { public static boolean flagM; }")
 244                 .write(modSrc);
 245         new ModuleBuilder(tb, "N")
 246                 .exports("pkg to K")
 247                 .classes("package pkg; public class A { public static boolean flagN; }")
 248                 .write(modSrc);
 249         ModuleBuilder moduleK = new ModuleBuilder(tb, "K");
 250         moduleK.requires("M")
 251                 .requires("N")
 252                 .classes("package p; public class DependsOnN { boolean f = pkg.A.flagN; } ")
 253                 .write(modSrc);
 254         new JavacTask(tb)
 255                 .options("--module-source-path", modSrc.toString())
 256                 .outdir(Files.createDirectories(base.resolve("classes")))
 257                 .files(findJavaFiles(modSrc.resolve("K")))
 258                 .run(Task.Expect.SUCCESS)
 259                 .writeAll();
 260 
 261         //negative case
 262         moduleK.classes("package pkg; public class DuplicatePackage { } ")
 263                 .classes("package p; public class DependsOnM { boolean f = pkg.A.flagM; } ")
 264                 .write(modSrc);
 265 
 266         List<String> output = new JavacTask(tb)
 267                 .options("-XDrawDiagnostics",
 268                         "--module-source-path", modSrc.toString())
 269                 .outdir(Files.createDirectories(base.resolve("classes")))
 270                 .files(findJavaFiles(modSrc.resolve("K")))
 271                 .run(Task.Expect.FAIL)
 272                 .writeAll()
 273                 .getOutputLines(Task.OutputKind.DIRECT);
 274 
 275         List<String> expected = Arrays.asList(
 276                 "DependsOnM.java:1:55: compiler.err.cant.resolve.location: kindname.variable, flagM, , , (compiler.misc.location: kindname.class, pkg.A, null)");
 277         if (!output.containsAll(expected)) {
 278             throw new Exception("expected output not found");
 279         }
 280     }
 281 }