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 module graph resolution issues 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.JarTask toolbox.JavacTask toolbox.ModuleBuilder 32 * ModuleTestBase 33 * @run main GraphsTest 34 */ 35 36 import java.io.File; 37 import java.nio.file.Files; 38 import java.nio.file.Path; 39 import java.util.Arrays; 40 import java.util.List; 41 import java.util.regex.Pattern; 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 GraphsTest extends ModuleTestBase { 50 51 public static void main(String... args) throws Exception { 52 GraphsTest t = new GraphsTest(); 53 t.runTests(); 54 } 55 56 /** 57 * Tests diamond graph with an automatic module added in. 58 * +-------------+ +--------------------+ +------------------+ 59 * | module M | | module N | | module O | 60 * | | -----> | | ---> | | --> J.jar 61 * | require N | | requires public O | | | 62 * | require L | | | +------------------+ 63 * +-------------+ +--------------------+ ^ 64 * | | 65 * | +--------------------+ | 66 * ------------------>| module L | | 67 * | |------------------ 68 * | requires public O | 69 * | | 70 * +--------------------+ 71 * 72 */ 73 @Test 74 public void diamond(Path base) throws Exception { 75 76 Path modSrc = Files.createDirectories(base.resolve("modSrc")); 77 Path modules = Files.createDirectories(base.resolve("modules")); 78 79 new ModuleBuilder(tb, "J") 80 .exports("openJ") 81 .classes("package openJ; public class J { }") 82 .classes("package closedJ; public class J { }") 83 .build(base.resolve("jar")); 84 85 Path jarModules = Files.createDirectories(base.resolve("jarModules")); 86 Path jar = jarModules.resolve("J.jar"); 87 new JarTask(tb, jar) 88 .baseDir(base.resolve("jar/J")) 89 .files(".") 90 .run() 91 .writeAll(); 92 93 new ModuleBuilder(tb, "O") 94 .exports("openO") 95 .requiresPublic("J", jarModules) 96 .classes("package openO; public class O { openJ.J j; }") 97 .classes("package closedO; public class O { }") 98 .build(modSrc, modules); 99 new ModuleBuilder(tb, "N") 100 .requiresPublic("O", modules, jarModules) 101 .exports("openN") 102 .classes("package openN; public class N { }") 103 .classes("package closedN; public class N { }") 104 .build(modSrc, modules); 105 new ModuleBuilder(tb, "L") 106 .requiresPublic("O", modules, jarModules) 107 .exports("openL") 108 .classes("package openL; public class L { }") 109 .classes("package closedL; public class L { }") 110 .build(modSrc, modules); 111 ModuleBuilder m = new ModuleBuilder(tb, "M"); 112 //positive case 113 Path positiveSrc = m 114 .requires("N", modules) 115 .requires("L", modules) 116 .classes("package p; public class Positive { openO.O o; openN.N n; openL.L l; }") 117 .write(base.resolve("positiveSrc")); 118 119 new JavacTask(tb) 120 .options("-XDrawDiagnostics", "-p", modules + File.pathSeparator + jarModules) 121 .outdir(Files.createDirectories(base.resolve("positive"))) 122 .files(findJavaFiles(positiveSrc)) 123 .run() 124 .writeAll(); 125 //negative case 126 Path negativeSrc = m.classes("package p; public class Negative { closedO.O o; closedN.N n; closedL.L l; }") 127 .write(base.resolve("negativeSrc")); 128 List<String> log = new JavacTask(tb) 129 .options("-XDrawDiagnostics", "-p", modules + File.pathSeparator + jarModules) 130 .outdir(Files.createDirectories(base.resolve("negative"))) 131 .files(findJavaFiles(negativeSrc)) 132 .run(Task.Expect.FAIL) 133 .writeAll() 134 .getOutputLines(Task.OutputKind.DIRECT); 135 136 List<String> expected = Arrays.asList( 137 "Negative.java:1:43: compiler.err.doesnt.exist: closedO", 138 "Negative.java:1:56: compiler.err.doesnt.exist: closedN", 139 "Negative.java:1:69: compiler.err.doesnt.exist: closedL"); 140 if (!log.containsAll(expected)) { 141 throw new Exception("Expected output not found"); 142 } 143 //multi module mode 144 m.write(modSrc); 145 List<String> out = new JavacTask(tb) 146 .options("-XDrawDiagnostics", 147 "--module-source-path", modSrc.toString(), 148 "-p", jarModules.toString() 149 ) 150 .outdir(Files.createDirectories(base.resolve("negative"))) 151 .files(findJavaFiles(modSrc)) 152 .run(Task.Expect.FAIL) 153 .writeAll() 154 .getOutputLines(Task.OutputKind.DIRECT); 155 expected = Arrays.asList( 156 "Negative.java:1:43: compiler.err.not.def.access.package.cant.access: closedO.O, closedO", 157 "Negative.java:1:56: compiler.err.not.def.access.package.cant.access: closedN.N, closedN", 158 "Negative.java:1:69: compiler.err.not.def.access.package.cant.access: closedL.L, closedL"); 159 if (!out.containsAll(expected)) { 160 throw new Exception("Expected output not found"); 161 } 162 //checks if the output does not contain messages about exported packages. 163 Pattern regex = Pattern.compile("compiler\\.err.*(openO\\.O|openN\\.N|openL\\.L)"); 164 for (String s : out) { 165 if (regex.matcher(s).find()) { 166 throw new Exception("Unexpected output: " + s); 167 } 168 } 169 } 170 171 /** 172 * Tests graph where module M reexport package of N, but N export the package only to M. 173 * 174 +-------------+ +--------------------+ +---------------+ 175 | module L | | module M | | module N | 176 | | -----> | | -----> | | 177 | requires M | | requires public N | | exports P to M| 178 +-------------+ | | +---------------+ 179 +--------------------+ 180 */ 181 @Test 182 public void reexportOfQualifiedExport(Path base) throws Exception { 183 Path modSrc = base.resolve("modSrc"); 184 new ModuleBuilder(tb, "M") 185 .requiresPublic("N") 186 .write(modSrc); 187 new ModuleBuilder(tb, "N") 188 .exportsTo("pack", "M") 189 .classes("package pack; public class Clazz { }") 190 .write(modSrc); 191 new ModuleBuilder(tb, "L") 192 .requires("M") 193 .classes("package p; public class A { A(pack.Clazz cl){} } ") 194 .write(modSrc); 195 String log = new JavacTask(tb) 196 .options("-XDrawDiagnostics", 197 "-modulesourcepath", modSrc.toString()) 198 .outdir(Files.createDirectories(base.resolve("negative"))) 199 .files(findJavaFiles(modSrc)) 200 .run(Task.Expect.FAIL) 201 .writeAll() 202 .getOutput(Task.OutputKind.DIRECT); 203 204 String expected = "A.java:1:35: compiler.err.not.def.access.package.cant.access: pack.Clazz, pack"; 205 if (!log.contains(expected)) { 206 throw new Exception("Expected output not found"); 207 } 208 } 209 }