ProvidesTest.java revision 3751:82a50c8d9a43
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 simple tests of module provides 27 * @bug 8168854 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 ProvidesTest 34 */ 35 36import java.nio.file.Files; 37import java.nio.file.Path; 38import java.util.Arrays; 39import java.util.List; 40 41import toolbox.JavacTask; 42import toolbox.Task; 43import toolbox.Task.Expect; 44import toolbox.ToolBox; 45 46public class ProvidesTest extends ModuleTestBase { 47 public static void main(String... args) throws Exception { 48 ProvidesTest t = new ProvidesTest(); 49 t.runTests(); 50 } 51 52 @Test 53 public void testSimple(Path base) throws Exception { 54 Path src = base.resolve("src"); 55 tb.writeJavaFiles(src, 56 "module m { provides p1.C1 with p2.C2; }", 57 "package p1; public class C1 { }", 58 "package p2; public class C2 extends p1.C1 { }"); 59 Path classes = base.resolve("classes"); 60 Files.createDirectories(classes); 61 62 new JavacTask(tb) 63 .outdir(classes) 64 .files(findJavaFiles(src)) 65 .run(Task.Expect.SUCCESS) 66 .writeAll(); 67 } 68 69 @Test 70 public void testMulti(Path base) throws Exception { 71 Path src = base.resolve("src"); 72 tb.writeJavaFiles(src.resolve("m1"), 73 "module m1 { exports p1; }", 74 "package p1; public class C1 { }"); 75 tb.writeJavaFiles(src.resolve("m2"), 76 "module m2 { requires m1; provides p1.C1 with p2.C2; }", 77 "package p2; public class C2 extends p1.C1 { }"); 78 Path modules = base.resolve("modules"); 79 Files.createDirectories(modules); 80 81 new JavacTask(tb) 82 .options("--module-source-path", src.toString()) 83 .outdir(modules) 84 .files(findJavaFiles(src)) 85 .run(Task.Expect.SUCCESS) 86 .writeAll(); 87 88 } 89 90 @Test 91 public void testMissingWith(Path base) throws Exception { 92 Path src = base.resolve("src"); 93 tb.writeJavaFiles(src, 94 "module m { provides p.C; }", 95 "package p; public class C { }"); 96 Path classes = base.resolve("classes"); 97 Files.createDirectories(classes); 98 99 String log = new JavacTask(tb) 100 .options("-XDrawDiagnostics") 101 .outdir(classes) 102 .files(findJavaFiles(src)) 103 .run(Task.Expect.FAIL) 104 .writeAll() 105 .getOutput(Task.OutputKind.DIRECT); 106 107 if (!log.contains("module-info.java:1:24: compiler.err.expected: 'with'")) 108 throw new Exception("expected output not found"); 109 110 } 111 112 @Test 113 public void testDuplicateProvides(Path base) throws Exception { 114 Path src = base.resolve("src"); 115 tb.writeJavaFiles(src, 116 "module m { provides p1.C1 with p2.C2; provides p1.C1 with p2.C2; }", 117 "package p1; public class C1 { }", 118 "package p2; public class C2 extends p1.C1 { }"); 119 Path classes = base.resolve("classes"); 120 Files.createDirectories(classes); 121 122 new JavacTask(tb) 123 .options("-XDrawDiagnostic") 124 .outdir(classes) 125 .files(findJavaFiles(src)) 126 .run(Task.Expect.FAIL) 127 .writeAll(); 128 } 129 130 @Test 131 public void testMissingService(Path base) throws Exception { 132 Path src = base.resolve("src"); 133 tb.writeJavaFiles(src, 134 "module m { provides p.Missing with p.C; }", 135 "package p; public class C extends p.Missing { }"); 136 137 List<String> output = new JavacTask(tb) 138 .options("-XDrawDiagnostics") 139 .outdir(Files.createDirectories(base.resolve("classes"))) 140 .files(findJavaFiles(src)) 141 .run(Task.Expect.FAIL) 142 .writeAll() 143 .getOutputLines(Task.OutputKind.DIRECT); 144 145 List<String> expected = Arrays.asList( 146 "C.java:1:36: compiler.err.cant.resolve.location: kindname.class, Missing, , , (compiler.misc.location: kindname.package, p, null)", 147 "module-info.java:1:22: compiler.err.cant.resolve.location: kindname.class, Missing, , , (compiler.misc.location: kindname.package, p, null)", 148 "2 errors"); 149 if (!output.containsAll(expected)) { 150 throw new Exception("Expected output not found"); 151 } 152 } 153 154 @Test 155 public void testProvidesFromAnotherModule(Path base) throws Exception { 156 Path modules = base.resolve("modules"); 157 tb.writeJavaFiles(modules.resolve("M"), 158 "module M { exports p; }", 159 "package p; public class Service { }"); 160 tb.writeJavaFiles(modules.resolve("L"), 161 "module L { requires M; provides p.Service with p.Service; }"); 162 163 List<String> output = new JavacTask(tb) 164 .options("-XDrawDiagnostics", 165 "--module-source-path", modules.toString()) 166 .outdir(Files.createDirectories(base.resolve("classes"))) 167 .files(findJavaFiles(modules)) 168 .run(Task.Expect.FAIL) 169 .writeAll() 170 .getOutputLines(Task.OutputKind.DIRECT); 171 List<String> expected = Arrays.asList( 172 "module-info.java:1:24: compiler.err.service.implementation.not.in.right.module: M", 173 "1 error"); 174 if (!output.containsAll(expected)) { 175 throw new Exception("Expected output not found"); 176 } 177 178 } 179 180 @Test 181 public void testServiceIsNotImplemented(Path base) throws Exception { 182 Path src = base.resolve("src"); 183 tb.writeJavaFiles(src, 184 "module m { provides p.A with p.B; }", 185 "package p; public class A { }", 186 "package p; public class B { }"); 187 188 List<String> output = new JavacTask(tb) 189 .options("-XDrawDiagnostics") 190 .outdir(Files.createDirectories(base.resolve("classes"))) 191 .files(findJavaFiles(src)) 192 .run(Task.Expect.FAIL) 193 .writeAll() 194 .getOutputLines(Task.OutputKind.DIRECT); 195 196 List<String> expected = Arrays.asList( 197 "module-info.java:1:31: compiler.err.service.implementation.must.be.subtype.of.service.interface", 198 "module-info.java:1:12: compiler.warn.service.provided.but.not.exported.or.used: p.A", 199 "1 error", 200 "1 warning"); 201 if (!output.containsAll(expected)) { 202 throw new Exception("Expected output not found"); 203 } 204 } 205 206 @Test 207 public void testMissingImplementation(Path base) throws Exception { 208 Path src = base.resolve("src"); 209 tb.writeJavaFiles(src, 210 "module m { provides p.C with p.Impl; }", 211 "package p; public class C { }"); 212 213 List<String> output = new JavacTask(tb) 214 .options("-XDrawDiagnostics") 215 .outdir(Files.createDirectories(base.resolve("classes"))) 216 .files(findJavaFiles(src)) 217 .run(Task.Expect.FAIL) 218 .writeAll() 219 .getOutputLines(Task.OutputKind.DIRECT); 220 221 List<String> expected = Arrays.asList("module-info.java:1:31: compiler.err.cant.resolve.location: kindname.class, Impl, , , (compiler.misc.location: kindname.package, p, null)", 222 "1 error"); 223 if (!output.containsAll(expected)) { 224 throw new Exception("Expected output not found"); 225 } 226 } 227 228 @Test 229 public void testSeveralImplementations(Path base) throws Exception { 230 Path src = base.resolve("src"); 231 tb.writeJavaFiles(src, 232 "module m { provides p.C with p.Impl1; provides p.C with p.Impl2; }", 233 "package p; public class C { }", 234 "package p; public class Impl1 extends p.C { }", 235 "package p; public class Impl2 extends p.C { }"); 236 237 new JavacTask(tb) 238 .outdir(Files.createDirectories(base.resolve("classes"))) 239 .files(findJavaFiles(src)) 240 .run(Task.Expect.SUCCESS) 241 .writeAll(); 242 } 243 244 @Test 245 public void testOneImplementationsForServices(Path base) throws Exception { 246 Path src = base.resolve("src"); 247 tb.writeJavaFiles(src, 248 "module m { provides p.Service1 with p.Impl; provides p.Service2 with p.Impl; }", 249 "package p; public interface Service1 { }", 250 "package p; public abstract class Service2 { }", 251 "package p; public class Impl extends p.Service2 implements p.Service1 { }"); 252 253 new JavacTask(tb) 254 .outdir(Files.createDirectories(base.resolve("classes"))) 255 .files(findJavaFiles(src)) 256 .run(Task.Expect.SUCCESS) 257 .writeAll(); 258 } 259 260 @Test 261 public void testAbstractImplementation(Path base) throws Exception { 262 Path src = base.resolve("src"); 263 tb.writeJavaFiles(src, 264 "module m { provides p1.C1 with p2.C2; }", 265 "package p1; public class C1 { }", 266 "package p2; public abstract class C2 extends p1.C1 { }"); 267 268 List<String> output = new JavacTask(tb) 269 .options("-XDrawDiagnostics") 270 .outdir(Files.createDirectories(base.resolve("classes"))) 271 .files(findJavaFiles(src)) 272 .run(Task.Expect.FAIL) 273 .writeAll() 274 .getOutputLines(Task.OutputKind.DIRECT); 275 276 List<String> expected = Arrays.asList( 277 "module-info.java:1:34: compiler.err.service.implementation.is.abstract: p2.C2"); 278 if (!output.containsAll(expected)) { 279 throw new Exception("Expected output not found"); 280 } 281 } 282 283 @Test 284 public void testInterfaceImplementation(Path base) throws Exception { 285 Path src = base.resolve("src"); 286 tb.writeJavaFiles(src, 287 "module m { provides p1.Service with p2.Impl; }", 288 "package p1; public interface Service { }", 289 "package p2; public interface Impl extends p1.Service { }"); 290 291 List<String> output = new JavacTask(tb) 292 .options("-XDrawDiagnostics") 293 .outdir(Files.createDirectories(base.resolve("classes"))) 294 .files(findJavaFiles(src)) 295 .run(Task.Expect.FAIL) 296 .writeAll() 297 .getOutputLines(Task.OutputKind.DIRECT); 298 299 List<String> expected = Arrays.asList( 300 "module-info.java:1:39: compiler.err.service.implementation.is.abstract: p2.Impl"); 301 if (!output.containsAll(expected)) { 302 throw new Exception("Expected output not found"); 303 } 304 } 305 306 @Test 307 public void testProtectedImplementation(Path base) throws Exception { 308 Path src = base.resolve("src"); 309 tb.writeJavaFiles(src, 310 "module m { provides p1.C1 with p2.C2; }", 311 "package p1; public class C1 { }", 312 "package p2; class C2 extends p1.C1 { }"); 313 314 List<String> output = new JavacTask(tb) 315 .options("-XDrawDiagnostics") 316 .outdir(Files.createDirectories(base.resolve("classes"))) 317 .files(findJavaFiles(src)) 318 .run(Task.Expect.FAIL) 319 .writeAll() 320 .getOutputLines(Task.OutputKind.DIRECT); 321 322 List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public.cant.access: p2.C2, p2", 323 "1 error"); 324 if (!output.containsAll(expected)) { 325 throw new Exception("Expected output not found"); 326 } 327 } 328 329 @Test 330 public void testNoNoArgConstructor(Path base) throws Exception { 331 Path src = base.resolve("src"); 332 tb.writeJavaFiles(src, 333 "module m { uses p1.C1; provides p1.C1 with p2.C2; }", 334 "package p1; public class C1 { }", 335 "package p2; public class C2 extends p1.C1 { public C2(String str) { } }"); 336 337 List<String> output = new JavacTask(tb) 338 .options("-XDrawDiagnostics") 339 .outdir(Files.createDirectories(base.resolve("classes"))) 340 .files(findJavaFiles(src)) 341 .run(Task.Expect.FAIL) 342 .writeAll() 343 .getOutputLines(Task.OutputKind.DIRECT); 344 345 List<String> expected = Arrays.asList( 346 "module-info.java:1:46: compiler.err.service.implementation.doesnt.have.a.no.args.constructor: p2.C2"); 347 if (!output.containsAll(expected)) { 348 throw new Exception("Expected output not found"); 349 } 350 } 351 352 @Test 353 public void testPrivateNoArgConstructor(Path base) throws Exception { 354 Path src = base.resolve("src"); 355 tb.writeJavaFiles(src, 356 "module m { uses p1.C1; provides p1.C1 with p2.C2; }", 357 "package p1; public class C1 { }", 358 "package p2; public class C2 extends p1.C1 { private C2() { } }"); 359 360 List<String> output = new JavacTask(tb) 361 .options("-XDrawDiagnostics") 362 .outdir(Files.createDirectories(base.resolve("classes"))) 363 .files(findJavaFiles(src)) 364 .run(Task.Expect.FAIL) 365 .writeAll() 366 .getOutputLines(Task.OutputKind.DIRECT); 367 368 List<String> expected = Arrays.asList( 369 "module-info.java:1:46: compiler.err.service.implementation.no.args.constructor.not.public: p2.C2"); 370 if (!output.containsAll(expected)) { 371 throw new Exception("Expected output not found"); 372 } 373 } 374 375 @Test 376 public void testServiceIndirectlyImplemented(Path base) throws Exception { 377 Path src = base.resolve("src"); 378 tb.writeJavaFiles(src, 379 "module m { provides p1.C1 with p2.C3; }", 380 "package p1; public class C1 { }", 381 "package p2; public class C2 extends p1.C1 { }", 382 "package p2; public class C3 extends p2.C2 { }"); 383 384 new JavacTask(tb) 385 .outdir(Files.createDirectories(base.resolve("classes"))) 386 .files(findJavaFiles(src)) 387 .run(Task.Expect.SUCCESS) 388 .writeAll(); 389 } 390 391 @Test 392 public void testServiceImplementationInnerClass(Path base) throws Exception { 393 Path src = base.resolve("src"); 394 tb.writeJavaFiles(src, 395 "module m { provides p1.C1 with p2.C2.Inner; }", 396 "package p1; public class C1 { }", 397 "package p2; public class C2 { public class Inner extends p1.C1 { } }"); 398 399 List<String> output = new JavacTask(tb) 400 .options("-XDrawDiagnostics") 401 .outdir(Files.createDirectories(base.resolve("classes"))) 402 .files(findJavaFiles(src)) 403 .run(Task.Expect.FAIL) 404 .writeAll() 405 .getOutputLines(Task.OutputKind.DIRECT); 406 407 List<String> expected = Arrays.asList( 408 "module-info.java:1:37: compiler.err.service.implementation.is.inner: p2.C2.Inner"); 409 if (!output.containsAll(expected)) { 410 throw new Exception("Expected output not found"); 411 } 412 } 413 414 @Test 415 public void testServiceDefinitionInnerClass(Path base) throws Exception { 416 Path src = base.resolve("src"); 417 tb.writeJavaFiles(src, 418 "module m { provides p1.C1.InnerDefinition with p2.C2; }", 419 "package p1; public class C1 { public class InnerDefinition { } }", 420 "package p2; public class C2 extends p1.C1.InnerDefinition { public C2() { new p1.C1().super(); } }"); 421 422 new JavacTask(tb) 423 .options("-XDrawDiagnostics") 424 .outdir(Files.createDirectories(base.resolve("classes"))) 425 .files(findJavaFiles(src)) 426 .run(Expect.SUCCESS) 427 .writeAll(); 428 } 429} 430