ConvenientAccessErrorsTest.java revision 3875:f94e974fe589
1/* 2 * Copyright (c) 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 Check convenient errors are produced for inaccessible classes. 27 * @library /tools/lib 28 * @modules jdk.compiler/com.sun.tools.javac.api 29 * jdk.compiler/com.sun.tools.javac.main 30 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase 31 * @run main ConvenientAccessErrorsTest 32 */ 33 34import java.nio.file.Files; 35import java.nio.file.Path; 36import java.util.Arrays; 37import java.util.List; 38 39import toolbox.JarTask; 40import toolbox.JavacTask; 41import toolbox.Task; 42 43public class ConvenientAccessErrorsTest extends ModuleTestBase { 44 45 public static void main(String... args) throws Exception { 46 new ConvenientAccessErrorsTest().runTests(); 47 } 48 49 @Test 50 public void testNoDep(Path base) throws Exception { 51 Path src = base.resolve("src"); 52 Path src_m1 = src.resolve("m1x"); 53 tb.writeJavaFiles(src_m1, 54 "module m1x { exports api; }", 55 "package api; public class Api { public void call() { } }"); 56 Path src_m2 = src.resolve("m2x"); 57 tb.writeJavaFiles(src_m2, 58 "module m2x { }", 59 "package test; public class Test { api.Api api; }"); 60 Path classes = base.resolve("classes"); 61 tb.createDirectories(classes); 62 63 List<String> log = new JavacTask(tb) 64 .options("-XDrawDiagnostics", 65 "--module-source-path", src.toString()) 66 .outdir(classes) 67 .files(findJavaFiles(src)) 68 .run(Task.Expect.FAIL) 69 .writeAll() 70 .getOutputLines(Task.OutputKind.DIRECT); 71 72 List<String> expected = Arrays.asList( 73 "Test.java:1:35: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m2x, api, m1x)", 74 "1 error"); 75 76 if (!expected.equals(log)) 77 throw new Exception("expected output not found; actual: " + log); 78 } 79 80 @Test 81 public void testNotExported(Path base) throws Exception { 82 Path src = base.resolve("src"); 83 Path src_m1 = src.resolve("m1x"); 84 tb.writeJavaFiles(src_m1, 85 "module m1x { exports api; }", 86 "package api; public class Api { }", 87 "package impl; public class Impl { }"); 88 Path src_m2 = src.resolve("m2x"); 89 tb.writeJavaFiles(src_m2, 90 "module m2x { requires m1x; }", 91 "package test; public class Test { impl.Impl api; }"); 92 Path src_m3 = src.resolve("m3x"); 93 tb.writeJavaFiles(src_m3, 94 "module m3x { requires m1x; }"); 95 Path classes = base.resolve("classes"); 96 tb.createDirectories(classes); 97 98 List<String> log = new JavacTask(tb) 99 .options("-XDrawDiagnostics", 100 "--module-source-path", src.toString()) 101 .outdir(classes) 102 .files(findJavaFiles(src)) 103 .run(Task.Expect.FAIL) 104 .writeAll() 105 .getOutputLines(Task.OutputKind.DIRECT); 106 107 List<String> expected = Arrays.asList( 108 "Test.java:1:35: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.not.exported: impl, m1x)", 109 "1 error"); 110 111 if (!expected.equals(log)) 112 throw new Exception("expected output not found; actual: " + log); 113 114 tb.writeJavaFiles(src_m1, 115 "module m1x { exports api; exports impl to m3x;}"); 116 117 log = new JavacTask(tb) 118 .options("-XDrawDiagnostics", 119 "--module-source-path", src.toString()) 120 .outdir(classes) 121 .files(findJavaFiles(src)) 122 .run(Task.Expect.FAIL) 123 .writeAll() 124 .getOutputLines(Task.OutputKind.DIRECT); 125 126 expected = Arrays.asList( 127 "Test.java:1:35: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.not.exported.to.module: impl, m1x, m2x)", 128 "1 error"); 129 130 if (!expected.equals(log)) 131 throw new Exception("expected output not found; actual: " + log); 132 } 133 134 @Test 135 public void testInaccessibleInExported(Path base) throws Exception { 136 Path src = base.resolve("src"); 137 Path src_m1 = src.resolve("m1x"); 138 tb.writeJavaFiles(src_m1, 139 "module m1x { exports api; }", 140 "package api; class Api { }"); 141 Path src_m2 = src.resolve("m2x"); 142 tb.writeJavaFiles(src_m2, 143 "module m2x { requires m1x; }", 144 "package test; public class Test { api.Api api; }"); 145 Path classes = base.resolve("classes"); 146 tb.createDirectories(classes); 147 148 List<String> log = new JavacTask(tb) 149 .options("-XDrawDiagnostics", 150 "--module-source-path", src.toString()) 151 .outdir(classes) 152 .files(findJavaFiles(src)) 153 .run(Task.Expect.FAIL) 154 .writeAll() 155 .getOutputLines(Task.OutputKind.DIRECT); 156 157 List<String> expected = Arrays.asList( 158 "Test.java:1:38: compiler.err.not.def.public.cant.access: api.Api, api", 159 "1 error"); 160 161 if (!expected.equals(log)) 162 throw new Exception("expected output not found; actual: " + log); 163 } 164 165// @Test 166 public void testInaccessibleUnnamedModule(Path base) throws Exception { 167 Path jar = prepareTestJar(base, "package api; class Api { public static class Foo {} }"); 168 169 Path moduleSrc = base.resolve("module-src"); 170 Path m1x = moduleSrc.resolve("m1x"); 171 172 Path classes = base.resolve("classes"); 173 174 Files.createDirectories(classes); 175 176 tb.writeJavaFiles(m1x, 177 "module m1x { }", 178 "package test; public class Test { api.Api api; api.Api.Foo api; }"); 179 180 List<String> log = new JavacTask(tb) 181 .options("-classpath", jar.toString(), 182 "-XDrawDiagnostics") 183 .outdir(classes) 184 .files(findJavaFiles(moduleSrc)) 185 .run(Task.Expect.FAIL) 186 .writeAll() 187 .getOutputLines(Task.OutputKind.DIRECT); 188 189 List<String> expected = Arrays.asList( 190 "Test.java:1:38: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.does.not.read.unnamed: api, m1x)", 191 "Test.java:1:51: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.does.not.read.unnamed: api, m1x)", 192 "2 errors"); 193 194 if (!expected.equals(log)) 195 throw new Exception("expected output not found; actual: " + log); 196 } 197 198 @Test 199 public void testIndirectReferenceToUnnamedModule(Path base) throws Exception { 200 Path jar = prepareTestJar(base, "package api; public class Api { public void test() {} }"); 201 202 Path moduleSrc = base.resolve("module-src"); 203 Path m1x = moduleSrc.resolve("m1x"); 204 Path auxiliary = moduleSrc.resolve("auxiliary"); 205 206 Path classes = base.resolve("classes"); 207 208 Files.createDirectories(classes); 209 210 tb.writeJavaFiles(m1x, 211 "module m1x { requires auxiliary; }", 212 "package test; public class Test { { auxiliary.Auxiliary.get().test(); } }"); 213 214 tb.writeJavaFiles(auxiliary, 215 "module auxiliary { exports auxiliary; }", 216 "package auxiliary; public class Auxiliary { public static api.Api get() { return null; } }"); 217 218 List<String> log = new JavacTask(tb) 219 .options("-classpath", jar.toString(), 220 "-XDrawDiagnostics", 221 "--add-reads", "auxiliary=ALL-UNNAMED", 222 "--module-source-path", moduleSrc.toString()) 223 .outdir(classes) 224 .files(findJavaFiles(moduleSrc)) 225 .run(Task.Expect.FAIL) 226 .writeAll() 227 .getOutputLines(Task.OutputKind.DIRECT); 228 229 List<String> expected = Arrays.asList( 230 "Test.java:1:62: compiler.err.not.def.access.class.intf.cant.access.reason: test(), api.Api, api, (compiler.misc.not.def.access.does.not.read.unnamed: api, m1x)", 231 "1 error"); 232 233 if (!expected.equals(log)) 234 throw new Exception("expected output not found; actual: " + log); 235 } 236 237 private Path prepareTestJar(Path base, String code) throws Exception { 238 Path legacySrc = base.resolve("legacy-src"); 239 tb.writeJavaFiles(legacySrc, code); 240 Path legacyClasses = base.resolve("legacy-classes"); 241 Files.createDirectories(legacyClasses); 242 243 String log = new JavacTask(tb) 244 .options() 245 .outdir(legacyClasses) 246 .files(findJavaFiles(legacySrc)) 247 .run() 248 .writeAll() 249 .getOutput(Task.OutputKind.DIRECT); 250 251 if (!log.isEmpty()) { 252 throw new Exception("unexpected output: " + log); 253 } 254 255 Path lib = base.resolve("lib"); 256 257 Files.createDirectories(lib); 258 259 Path jar = lib.resolve("test-api-1.0.jar"); 260 261 new JarTask(tb, jar) 262 .baseDir(legacyClasses) 263 .files("api/Api.class") 264 .run(); 265 266 return jar; 267 } 268 269 @Test 270 public void testUnnamedModuleAccess(Path base) throws Exception { 271 Path src = base.resolve("src"); 272 Path src_m1 = src.resolve("m1x"); 273 tb.writeJavaFiles(src_m1, 274 "module m1x { exports api to m2x; }", 275 "package api; class Api { }", 276 "package impl; class Impl { }"); 277 Path src_m2 = src.resolve("m2x"); 278 tb.writeJavaFiles(src_m2, 279 "module m2x { requires m1x; }"); 280 Path modulepath = base.resolve("modulepath"); 281 tb.createDirectories(modulepath); 282 283 new JavacTask(tb) 284 .options("--module-source-path", src.toString()) 285 .outdir(modulepath) 286 .files(findJavaFiles(src)) 287 .run() 288 .writeAll(); 289 290 Path unnamedSrc = base.resolve("unnamedSrc"); 291 tb.writeJavaFiles(unnamedSrc, 292 "public class Test { api.Api api; impl.Impl impl; }"); 293 Path unnamedClasses = base.resolve("unnamed-classes"); 294 Files.createDirectories(unnamedClasses); 295 296 List<String> log = new JavacTask(tb) 297 .options("--module-path", modulepath.toString(), 298 "-XDrawDiagnostics") 299 .outdir(unnamedClasses) 300 .files(findJavaFiles(unnamedSrc)) 301 .run(Task.Expect.FAIL) 302 .writeAll() 303 .getOutputLines(Task.OutputKind.DIRECT); 304 305 List<String> expected = Arrays.asList( 306 "Test.java:1:21: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read.from.unnamed: api, m1x)", 307 "Test.java:1:34: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.does.not.read.from.unnamed: impl, m1x)", 308 "2 errors" 309 ); 310 311 if (!expected.equals(log)) { 312 throw new Exception("unexpected output: " + log); 313 } 314 315 log = new JavacTask(tb) 316 .options("--module-path", modulepath.toString(), 317 "--add-modules", "m1x", 318 "-XDrawDiagnostics") 319 .outdir(unnamedClasses) 320 .files(findJavaFiles(unnamedSrc)) 321 .run(Task.Expect.FAIL) 322 .writeAll() 323 .getOutputLines(Task.OutputKind.DIRECT); 324 325 expected = Arrays.asList( 326 "Test.java:1:21: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported.to.module.from.unnamed: api, m1x)", 327 "Test.java:1:34: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.not.exported.from.unnamed: impl, m1x)", 328 "2 errors" 329 ); 330 331 if (!expected.equals(log)) { 332 throw new Exception("unexpected output: " + log); 333 } 334 } 335 336 @Test 337 public void testInImport(Path base) throws Exception { 338 Path src = base.resolve("src"); 339 Path src_m1 = src.resolve("m1x"); 340 tb.writeJavaFiles(src_m1, 341 "module m1x { }", 342 "package api; public class Api { public String test() { return null; } }"); 343 Path src_m2 = src.resolve("m2x"); 344 tb.writeJavaFiles(src_m2, 345 "module m2x { requires m1x; }", 346 "package test; import api.Api; public class Test { Api api; { api.test().length(); } }"); 347 Path classes = base.resolve("classes"); 348 tb.createDirectories(classes); 349 350 List<String> log = new JavacTask(tb) 351 .options("-XDrawDiagnostics", 352 "--module-source-path", src.toString()) 353 .outdir(classes) 354 .files(findJavaFiles(src)) 355 .run(Task.Expect.FAIL) 356 .writeAll() 357 .getOutputLines(Task.OutputKind.DIRECT); 358 359 List<String> expected = Arrays.asList( 360 "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)", 361 "1 error"); 362 363 if (!expected.equals(log)) 364 throw new Exception("expected output not found; actual: " + log); 365 } 366 367 @Test 368 public void testInImportOnDemand(Path base) throws Exception { 369 Path src = base.resolve("src"); 370 Path src_m1 = src.resolve("m1x"); 371 tb.writeJavaFiles(src_m1, 372 "module m1x { }", 373 "package api; public class Api { public String test() { return null; } }"); 374 Path src_m2 = src.resolve("m2x"); 375 tb.writeJavaFiles(src_m2, 376 "module m2x { requires m1x; }", 377 "package test; import api.*; public class Test { Api api; { api.test().length(); } }"); 378 Path classes = base.resolve("classes"); 379 tb.createDirectories(classes); 380 381 List<String> log = new JavacTask(tb) 382 .options("-XDrawDiagnostics", 383 "--module-source-path", src.toString()) 384 .outdir(classes) 385 .files(findJavaFiles(src)) 386 .run(Task.Expect.FAIL) 387 .writeAll() 388 .getOutputLines(Task.OutputKind.DIRECT); 389 390 List<String> expected = Arrays.asList( 391 "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)", 392 "Test.java:1:49: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.not.exported: api, m1x)", 393 "2 errors"); 394 395 if (!expected.equals(log)) 396 throw new Exception("expected output not found; actual: " + log); 397 } 398 399 @Test 400 public void testUnusedImportOnDemand1(Path base) throws Exception { 401 Path src = base.resolve("src"); 402 tb.writeJavaFiles(src, 403 "package test; import javax.annotation.*; public class Test { }"); 404 Path classes = base.resolve("classes"); 405 tb.createDirectories(classes); 406 407 List<String> log = new JavacTask(tb) 408 .options("-XDrawDiagnostics", 409 "--add-modules", "java.compiler") 410 .outdir(classes) 411 .files(findJavaFiles(src)) 412 .run() 413 .writeAll() 414 .getOutputLines(Task.OutputKind.DIRECT); 415 416 List<String> expected = Arrays.asList(""); 417 418 if (!expected.equals(log)) 419 throw new Exception("expected output not found; actual: " + log); 420 } 421 422 @Test 423 public void testUnusedImportOnDemand2(Path base) throws Exception { 424 Path src = base.resolve("src"); 425 Path src_m1 = src.resolve("m1x"); 426 tb.writeJavaFiles(src_m1, 427 "module m1x { }", 428 "package api; public class Api { }"); 429 Path src_m2 = src.resolve("m2x"); 430 tb.writeJavaFiles(src_m2, 431 "module m2x { requires m1x; }", 432 "package test; import api.*; public class Test { }"); 433 Path classes = base.resolve("classes"); 434 tb.createDirectories(classes); 435 436 List<String> log = new JavacTask(tb) 437 .options("-XDrawDiagnostics", 438 "--module-source-path", src.toString()) 439 .outdir(classes) 440 .files(findJavaFiles(src)) 441 .run(Task.Expect.FAIL) 442 .writeAll() 443 .getOutputLines(Task.OutputKind.DIRECT); 444 445 List<String> expected = Arrays.asList( 446 "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)", 447 "1 error"); 448 449 if (!expected.equals(log)) 450 throw new Exception("expected output not found; actual: " + log); 451 } 452 453 @Test 454 public void testClassPackageConflict(Path base) throws Exception { 455 Path libSrc = base.resolve("libSrc"); 456 tb.writeJavaFiles(libSrc, 457 "package test.desktop; public class Any { }"); 458 Path libClasses = base.resolve("libClasses"); 459 tb.createDirectories(libClasses); 460 461 new JavacTask(tb) 462 .outdir(libClasses) 463 .files(findJavaFiles(libSrc)) 464 .run() 465 .writeAll() 466 .getOutputLines(Task.OutputKind.DIRECT); 467 468 Path src = base.resolve("src"); 469 tb.writeJavaFiles(src, 470 "package test; public class desktop { public static class Action { } }", 471 "package use; import test.desktop.*; public class Use { test.desktop.Action a; }"); 472 Path classes = base.resolve("classes"); 473 tb.createDirectories(classes); 474 475 new JavacTask(tb) 476 .options("-XDrawDiagnostics") 477 .classpath(libClasses) 478 .outdir(classes) 479 .files(findJavaFiles(src)) 480 .run() 481 .writeAll(); 482 } 483 484 @Test 485 public void testClassPackageConflictInUnnamed(Path base) throws Exception { 486 Path libSrc = base.resolve("libSrc"); 487 tb.writeJavaFiles(libSrc, 488 "package desktop; public class Any { }"); 489 Path libClasses = base.resolve("libClasses"); 490 tb.createDirectories(libClasses); 491 492 new JavacTask(tb) 493 .outdir(libClasses) 494 .files(findJavaFiles(libSrc)) 495 .run() 496 .writeAll() 497 .getOutputLines(Task.OutputKind.DIRECT); 498 499 Path src = base.resolve("src"); 500 tb.writeJavaFiles(src, 501 "public class desktop { public static class Action { } }", 502 "import desktop.*; public class Use { desktop.Action a; }"); 503 Path classes = base.resolve("classes"); 504 tb.createDirectories(classes); 505 506 new JavacTask(tb) 507 .options("-XDrawDiagnostics") 508 .classpath(libClasses) 509 .outdir(classes) 510 .files(findJavaFiles(src)) 511 .run() 512 .writeAll(); 513 } 514 515} 516