1/* 2 * Copyright (c) 2017, 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 * @bug 8176327 27 * @summary javac produces wrong module-info 28 * @library /tools/lib 29 * @modules 30 * jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.main 32 * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase 33 * @run main SourcePathTest 34 */ 35 36import java.io.IOException; 37import java.nio.file.FileVisitResult; 38import java.nio.file.Files; 39import java.nio.file.Path; 40import java.nio.file.SimpleFileVisitor; 41import java.nio.file.attribute.BasicFileAttributes; 42import java.util.ArrayList; 43import java.util.List; 44 45import toolbox.JavacTask; 46import toolbox.Task; 47 48public class SourcePathTest extends ModuleTestBase { 49 public static void main(String... args) throws Exception { 50 SourcePathTest t = new SourcePathTest(); 51 t.runTests(); 52 } 53 54 @Test 55 public void test_unnamedModuleOnSourcePath_fileNotOnPath(Path base) throws IOException { 56 Path src = base.resolve("src"); 57 tb.writeJavaFiles(src, "package p; public class A { }"); 58 Path otherSrc = base.resolve("otherSrc"); 59 tb.writeJavaFiles(otherSrc, "package p2; public class B { }"); 60 61 Path classes = base.resolve("classes"); 62 Files.createDirectories(classes); 63 64 new JavacTask(tb) 65 .options("-sourcepath", src.toString()) 66 .outdir(classes) 67 .files(findJavaFiles(otherSrc)) 68 .run() 69 .writeAll(); 70 71 showFiles(classes); 72 } 73 74 @Test 75 public void test_unnamedModuleOnSourcePath_fileOnPath(Path base) throws IOException { 76 Path src = base.resolve("src"); 77 tb.writeJavaFiles(src, "package p; public class A { }"); 78 79 Path classes = base.resolve("classes"); 80 Files.createDirectories(classes); 81 82 new JavacTask(tb) 83 .options("-sourcepath", src.toString()) 84 .outdir(classes) 85 .files(findJavaFiles(src)) 86 .run() 87 .writeAll(); 88 89 showFiles(classes); 90 } 91 92 @Test 93 public void test_namedModuleOnSourcePath_fileNotOnPath_1(Path base) throws Exception { 94 Path src = base.resolve("src"); 95 tb.writeFile(src.resolve("module-info.java"), "module m { exports p; }"); 96 tb.writeJavaFiles(src, "package p; public class A { }"); 97 Path otherSrc = base.resolve("otherSrc"); 98 tb.writeJavaFiles(otherSrc, "package p2; public class B { }"); 99 100 Path classes = base.resolve("classes"); 101 Files.createDirectories(classes); 102 103 String log = new JavacTask(tb) 104 .options("-XDrawDiagnostics=true", "-sourcepath", src.toString()) 105 .outdir(classes) 106 .files(findJavaFiles(otherSrc)) 107 .run(Task.Expect.FAIL) 108 .writeAll() 109 .getOutput(Task.OutputKind.DIRECT); 110 111 showFiles(classes); 112 checkOutputContains(log, 113 "B.java:1:1: compiler.err.file.sb.on.source.or.patch.path.for.module"); 114 } 115 116 @Test 117 public void test_namedModuleOnSourcePath_fileNotOnPath_2(Path base) throws Exception { 118 // This is the original test case: 119 // the source path contains one module, but the file to be compiled appears to be 120 // in another module. 121 Path src = base.resolve("src"); 122 Path src_mA = src.resolve("mA"); 123 tb.writeJavaFiles(src_mA, 124 "module mA { exports p; }", 125 "package p; public class A { }"); 126 Path src_mB = src.resolve("mB"); 127 tb.writeJavaFiles(src_mB, 128 "module mA { exports p2; }", 129 "package p2; public class B { }"); 130 131 Path classes = base.resolve("classes"); 132 Files.createDirectories(classes); 133 134 String log = new JavacTask(tb) 135 .options("-XDrawDiagnostics=true", "-sourcepath", src_mA.toString()) 136 .outdir(classes) 137 .files(findJavaFiles(src_mB.resolve("p2"))) 138 .run(Task.Expect.FAIL) 139 .writeAll() 140 .getOutput(Task.OutputKind.DIRECT); 141 142 showFiles(classes); 143 checkOutputContains(log, 144 "B.java:1:1: compiler.err.file.sb.on.source.or.patch.path.for.module"); 145 } 146 147 @Test 148 public void test_namedModuleOnSourcePath_fileOnPath(Path base) throws Exception { 149 Path src = base.resolve("src"); 150 tb.writeFile(src.resolve("module-info.java"), "module m { exports p; }"); 151 tb.writeJavaFiles(src, "package p; public class A { }"); 152 153 Path classes = base.resolve("classes"); 154 Files.createDirectories(classes); 155 156 String log = new JavacTask(tb) 157 .options("-XDrawDiagnostics=true", "-sourcepath", src.toString()) 158 .outdir(classes) 159 .files(findJavaFiles(src.resolve("p"))) 160 .run() 161 .writeAll() 162 .getOutput(Task.OutputKind.DIRECT); 163 164 showFiles(classes); 165 } 166 167 @Test 168 public void test_namedModuleOnSourcePath_fileOnPatchPath(Path base) throws Exception { 169 // similar to test_namedModuleOnSourcePath_fileNotOnPath_1 170 // except that other src directory is not put on the patch path 171 Path src = base.resolve("src"); 172 tb.writeFile(src.resolve("module-info.java"), "module m { exports p; }"); 173 tb.writeJavaFiles(src, "package p; public class A { }"); 174 Path otherSrc = base.resolve("otherSrc"); 175 tb.writeJavaFiles(otherSrc, "package p2; public class B { }"); 176 177 Path classes = base.resolve("classes"); 178 Files.createDirectories(classes); 179 180 String log = new JavacTask(tb) 181 .options("-XDrawDiagnostics=true", 182 "-sourcepath", src.toString(), 183 "--patch-module", "m=" + otherSrc) 184 .outdir(classes) 185 .files(findJavaFiles(otherSrc)) 186 .run() 187 .writeAll() 188 .getOutput(Task.OutputKind.DIRECT); 189 190 showFiles(classes); 191 } 192 193 /* 194 * The following tests are not for the source path, but they exercise similar test 195 * cases for the module source path. 196 */ 197 198 @Test 199 public void test_moduleSourcePath_fileNotOnPath(Path base) throws Exception { 200 Path src = base.resolve("src"); 201 Path src_mA = src.resolve("mA"); 202 tb.writeJavaFiles(src_mA, 203 "module mA { exports p; }", 204 "package p; public class A { }"); 205 Path src_mB = src.resolve("mB"); 206 tb.writeJavaFiles(src_mB, 207 "module mB { exports p2; }", 208 "package p2; public class B { }"); 209 Path otherSrc = base.resolve("otherSrc"); 210 tb.writeJavaFiles(otherSrc, "package p3; public class C { }"); 211 212 Path classes = base.resolve("classes"); 213 Files.createDirectories(classes); 214 215 String log = new JavacTask(tb) 216 .options("-XDrawDiagnostics=true", 217 "--module-source-path", src.toString()) 218 .outdir(classes) 219 .files(findJavaFiles(otherSrc)) 220 .run(Task.Expect.FAIL) 221 .writeAll() 222 .getOutput(Task.OutputKind.DIRECT); 223 224 showFiles(classes); 225 checkOutputContains(log, 226 "C.java:1:1: compiler.err.not.in.module.on.module.source.path"); 227 } 228 229 @Test 230 public void test_moduleSourcePath_fileOnPath(Path base) throws Exception { 231 Path src = base.resolve("src"); 232 Path src_mA = src.resolve("mA"); 233 tb.writeJavaFiles(src_mA, 234 "module mA { exports p; }", 235 "package p; public class A { }"); 236 Path src_mB = src.resolve("mB"); 237 tb.writeJavaFiles(src_mB, 238 "module mB { exports p2; }", 239 "package p2; public class B { }"); 240 241 Path classes = base.resolve("classes"); 242 Files.createDirectories(classes); 243 244 String log = new JavacTask(tb) 245 .options("-XDrawDiagnostics=true", 246 "--module-source-path", src.toString()) 247 .outdir(classes) 248 .files(findJavaFiles(src_mB.resolve("p2"))) 249 .run() 250 .writeAll() 251 .getOutput(Task.OutputKind.DIRECT); 252 253 showFiles(classes); 254 255 } 256 257 @Test 258 public void test_moduleSourcePath_fileOnPatchPath(Path base) throws Exception { 259 // similar to test_moduleSourcePath_fileNotOnPath 260 // except that other src directory is not put on the patch path 261 Path src = base.resolve("src"); 262 Path src_mA = src.resolve("mA"); 263 tb.writeJavaFiles(src_mA, 264 "module mA { exports p; }", 265 "package p; public class A { }"); 266 Path src_mB = src.resolve("mB"); 267 tb.writeJavaFiles(src_mB, 268 "module mB { exports p2; }", 269 "package p2; public class B { }"); 270 Path otherSrc = base.resolve("otherSrc"); 271 tb.writeJavaFiles(otherSrc, "package p3; public class C { }"); 272 273 Path classes = base.resolve("classes"); 274 Files.createDirectories(classes); 275 276 String log = new JavacTask(tb) 277 .options("-XDrawDiagnostics=true", 278 "--module-source-path", src.toString(), 279 "--patch-module", "mA=" + otherSrc) 280 .outdir(classes) 281 .files(findJavaFiles(otherSrc)) 282 .run() 283 .writeAll() 284 .getOutput(Task.OutputKind.DIRECT); 285 286 showFiles(classes); 287 } 288 289 /** 290 * This method is primarily used to give visual confirmation that a test case 291 * generated files when the compilation succeeds and so generates no other output, 292 * such as error messages. 293 */ 294 List<Path> showFiles(Path dir) throws IOException { 295 List<Path> files = new ArrayList<>(); 296 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { 297 @Override 298 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 299 throws IOException { 300 if (Files.isRegularFile(file)) { 301 out.println("Found " + file); 302 files.add(file); 303 } 304 return FileVisitResult.CONTINUE; 305 } 306 }); 307 return files; 308 } 309} 310 311