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