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