ProvidesTest.java revision 3314:97ec97671022
112238SN/A/* 212238SN/A * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 312238SN/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 412238SN/A * 512238SN/A * This code is free software; you can redistribute it and/or modify it 612238SN/A * under the terms of the GNU General Public License version 2 only, as 712238SN/A * published by the Free Software Foundation. 812238SN/A * 912238SN/A * This code is distributed in the hope that it will be useful, but WITHOUT 1012238SN/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1112238SN/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1212238SN/A * version 2 for more details (a copy is included in the LICENSE file that 1312238SN/A * accompanied this code). 1412238SN/A * 1512238SN/A * You should have received a copy of the GNU General Public License version 1612238SN/A * 2 along with this work; if not, write to the Free Software Foundation, 1712238SN/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1812238SN/A * 1912238SN/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2012238SN/A * or visit www.oracle.com if you need additional information or have any 2112238SN/A * questions. 2212238SN/A */ 2312238SN/A 2412238SN/A/** 2512238SN/A * @test 2612238SN/A * @summary simple tests of module provides 2712238SN/A * @library /tools/lib 2812238SN/A * @modules 2912238SN/A * jdk.compiler/com.sun.tools.javac.api 3012238SN/A * jdk.compiler/com.sun.tools.javac.main 3112238SN/A * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase 3212238SN/A * @run main ProvidesTest 3312238SN/A */ 3412238SN/A 3512238SN/Aimport java.nio.file.Files; 3612238SN/Aimport java.nio.file.Path; 3712238SN/Aimport java.util.Arrays; 3812238SN/Aimport java.util.List; 3912238SN/A 4012238SN/Aimport 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 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 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 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 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 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 "module-info.java:1:37: compiler.err.service.implementation.doesnt.have.a.no.args.constructor: <any>", 147 "3 errors"); 148 if (!output.containsAll(expected)) { 149 throw new Exception("Expected output not found"); 150 } 151 } 152 153 @Test 154 void testProvidesFromAnotherModule(Path base) throws Exception { 155 Path modules = base.resolve("modules"); 156 tb.writeJavaFiles(modules.resolve("M"), 157 "module M { exports p; }", 158 "package p; public class Service { }"); 159 tb.writeJavaFiles(modules.resolve("L"), 160 "module L { requires M; provides p.Service with p.Service; }"); 161 162 List<String> output = new JavacTask(tb) 163 .options("-XDrawDiagnostics", 164 "-modulesourcepath", modules.toString()) 165 .outdir(Files.createDirectories(base.resolve("classes"))) 166 .files(findJavaFiles(modules)) 167 .run(Task.Expect.FAIL) 168 .writeAll() 169 .getOutputLines(Task.OutputKind.DIRECT); 170 List<String> expected = Arrays.asList( 171 "module-info.java:1:24: compiler.err.service.implementation.not.in.right.module: M", 172 "1 error"); 173 if (!output.containsAll(expected)) { 174 throw new Exception("Expected output not found"); 175 } 176 177 } 178 179 @Test 180 void testServiceIsNotImplemented(Path base) throws Exception { 181 Path src = base.resolve("src"); 182 tb.writeJavaFiles(src, 183 "module m { provides p.A with p.B; }", 184 "package p; public class A { }", 185 "package p; public class B { }"); 186 187 List<String> output = new JavacTask(tb) 188 .options("-XDrawDiagnostics") 189 .outdir(Files.createDirectories(base.resolve("classes"))) 190 .files(findJavaFiles(src)) 191 .run(Task.Expect.FAIL) 192 .writeAll() 193 .getOutputLines(Task.OutputKind.DIRECT); 194 195 List<String> expected = Arrays.asList("module-info.java:1:31: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: p.B, p.A)", 196 "1 error"); 197 if (!output.containsAll(expected)) { 198 throw new Exception("Expected output not found"); 199 } 200 } 201 202 @Test 203 void testMissingImplementation(Path base) throws Exception { 204 Path src = base.resolve("src"); 205 tb.writeJavaFiles(src, 206 "module m { provides p.C with p.Impl; }", 207 "package p; public class C { }"); 208 209 List<String> output = new JavacTask(tb) 210 .options("-XDrawDiagnostics") 211 .outdir(Files.createDirectories(base.resolve("classes"))) 212 .files(findJavaFiles(src)) 213 .run(Task.Expect.FAIL) 214 .writeAll() 215 .getOutputLines(Task.OutputKind.DIRECT); 216 217 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)", 218 "1 error"); 219 if (!output.containsAll(expected)) { 220 throw new Exception("Expected output not found"); 221 } 222 } 223 224 @Test 225 void testSeveralImplementations(Path base) throws Exception { 226 Path src = base.resolve("src"); 227 tb.writeJavaFiles(src, 228 "module m { provides p.C with p.Impl1; provides p.C with p.Impl2; }", 229 "package p; public class C { }", 230 "package p; public class Impl1 extends p.C { }", 231 "package p; public class Impl2 extends p.C { }"); 232 233 new JavacTask(tb) 234 .outdir(Files.createDirectories(base.resolve("classes"))) 235 .files(findJavaFiles(src)) 236 .run(Task.Expect.SUCCESS) 237 .writeAll(); 238 } 239 240 @Test 241 void testOneImplementationsForServices(Path base) throws Exception { 242 Path src = base.resolve("src"); 243 tb.writeJavaFiles(src, 244 "module m { provides p.Service1 with p.Impl; provides p.Service2 with p.Impl; }", 245 "package p; public interface Service1 { }", 246 "package p; public abstract class Service2 { }", 247 "package p; public class Impl extends p.Service2 implements p.Service1 { }"); 248 249 new JavacTask(tb) 250 .outdir(Files.createDirectories(base.resolve("classes"))) 251 .files(findJavaFiles(src)) 252 .run(Task.Expect.SUCCESS) 253 .writeAll(); 254 } 255 256 @Test 257 void testAbstractImplementation(Path base) throws Exception { 258 Path src = base.resolve("src"); 259 tb.writeJavaFiles(src, 260 "module m { provides p1.C1 with p2.C2; }", 261 "package p1; public class C1 { }", 262 "package p2; public abstract class C2 extends p1.C1 { }"); 263 264 List<String> output = new JavacTask(tb) 265 .options("-XDrawDiagnostics") 266 .outdir(Files.createDirectories(base.resolve("classes"))) 267 .files(findJavaFiles(src)) 268 .run(Task.Expect.FAIL) 269 .writeAll() 270 .getOutputLines(Task.OutputKind.DIRECT); 271 272 List<String> expected = Arrays.asList( 273 "module-info.java:1:34: compiler.err.service.implementation.is.abstract: p2.C2"); 274 if (!output.containsAll(expected)) { 275 throw new Exception("Expected output not found"); 276 } 277 } 278 279 @Test 280 void testInterfaceImplementation(Path base) throws Exception { 281 Path src = base.resolve("src"); 282 tb.writeJavaFiles(src, 283 "module m { provides p1.Service with p2.Impl; }", 284 "package p1; public interface Service { }", 285 "package p2; public interface Impl extends p1.Service { }"); 286 287 List<String> output = new JavacTask(tb) 288 .options("-XDrawDiagnostics") 289 .outdir(Files.createDirectories(base.resolve("classes"))) 290 .files(findJavaFiles(src)) 291 .run(Task.Expect.FAIL) 292 .writeAll() 293 .getOutputLines(Task.OutputKind.DIRECT); 294 295 List<String> expected = Arrays.asList( 296 "module-info.java:1:39: compiler.err.service.implementation.is.abstract: p2.Impl"); 297 if (!output.containsAll(expected)) { 298 throw new Exception("Expected output not found"); 299 } 300 } 301 302 @Test 303 void testProtectedImplementation(Path base) throws Exception { 304 Path src = base.resolve("src"); 305 tb.writeJavaFiles(src, 306 "module m { provides p1.C1 with p2.C2; }", 307 "package p1; public class C1 { }", 308 "package p2; class C2 extends p1.C1 { }"); 309 310 List<String> output = new JavacTask(tb) 311 .options("-XDrawDiagnostics") 312 .outdir(Files.createDirectories(base.resolve("classes"))) 313 .files(findJavaFiles(src)) 314 .run(Task.Expect.FAIL) 315 .writeAll() 316 .getOutputLines(Task.OutputKind.DIRECT); 317 318 List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public.cant.access: p2.C2, p2", 319 "1 error"); 320 if (!output.containsAll(expected)) { 321 throw new Exception("Expected output not found"); 322 } 323 } 324 325 @Test 326 void testNoNoArgConstructor(Path base) throws Exception { 327 Path src = base.resolve("src"); 328 tb.writeJavaFiles(src, 329 "module m { uses p1.C1; provides p1.C1 with p2.C2; }", 330 "package p1; public class C1 { }", 331 "package p2; public class C2 extends p1.C1 { public C2(String str) { } }"); 332 333 List<String> output = new JavacTask(tb) 334 .options("-XDrawDiagnostics") 335 .outdir(Files.createDirectories(base.resolve("classes"))) 336 .files(findJavaFiles(src)) 337 .run(Task.Expect.FAIL) 338 .writeAll() 339 .getOutputLines(Task.OutputKind.DIRECT); 340 341 List<String> expected = Arrays.asList( 342 "module-info.java:1:46: compiler.err.service.implementation.doesnt.have.a.no.args.constructor: p2.C2"); 343 if (!output.containsAll(expected)) { 344 throw new Exception("Expected output not found"); 345 } 346 } 347 348 @Test 349 void testPrivateNoArgConstructor(Path base) throws Exception { 350 Path src = base.resolve("src"); 351 tb.writeJavaFiles(src, 352 "module m { uses p1.C1; provides p1.C1 with p2.C2; }", 353 "package p1; public class C1 { }", 354 "package p2; public class C2 extends p1.C1 { private C2() { } }"); 355 356 List<String> output = new JavacTask(tb) 357 .options("-XDrawDiagnostics") 358 .outdir(Files.createDirectories(base.resolve("classes"))) 359 .files(findJavaFiles(src)) 360 .run(Task.Expect.FAIL) 361 .writeAll() 362 .getOutputLines(Task.OutputKind.DIRECT); 363 364 List<String> expected = Arrays.asList( 365 "module-info.java:1:46: compiler.err.service.implementation.no.args.constructor.not.public: p2.C2"); 366 if (!output.containsAll(expected)) { 367 throw new Exception("Expected output not found"); 368 } 369 } 370 371 @Test 372 void testServiceIndirectlyImplemented(Path base) throws Exception { 373 Path src = base.resolve("src"); 374 tb.writeJavaFiles(src, 375 "module m { provides p1.C1 with p2.C3; }", 376 "package p1; public class C1 { }", 377 "package p2; public class C2 extends p1.C1 { }", 378 "package p2; public class C3 extends p2.C2 { }"); 379 380 new JavacTask(tb) 381 .outdir(Files.createDirectories(base.resolve("classes"))) 382 .files(findJavaFiles(src)) 383 .run(Task.Expect.SUCCESS) 384 .writeAll(); 385 } 386 387 @Test 388 void testServiceImplementationInnerClass(Path base) throws Exception { 389 Path src = base.resolve("src"); 390 tb.writeJavaFiles(src, 391 "module m { provides p1.C1 with p2.C2.Inner; }", 392 "package p1; public class C1 { }", 393 "package p2; public class C2 { public class Inner extends p1.C1 { } }"); 394 395 List<String> output = new JavacTask(tb) 396 .options("-XDrawDiagnostics") 397 .outdir(Files.createDirectories(base.resolve("classes"))) 398 .files(findJavaFiles(src)) 399 .run(Task.Expect.FAIL) 400 .writeAll() 401 .getOutputLines(Task.OutputKind.DIRECT); 402 403 List<String> expected = Arrays.asList( 404 "module-info.java:1:37: compiler.err.service.implementation.is.inner: p2.C2.Inner"); 405 if (!output.containsAll(expected)) { 406 throw new Exception("Expected output not found"); 407 } 408 } 409 410 @Test 411 void testServiceDefinitionInnerClass(Path base) throws Exception { 412 Path src = base.resolve("src"); 413 tb.writeJavaFiles(src, 414 "module m { provides p1.C1.InnerDefinition with p2.C2; }", 415 "package p1; public class C1 { public class InnerDefinition { } }", 416 "package p2; public class C2 extends p1.C1.InnerDefinition { }"); 417 418 List<String> output = new JavacTask(tb) 419 .options("-XDrawDiagnostics") 420 .outdir(Files.createDirectories(base.resolve("classes"))) 421 .files(findJavaFiles(src)) 422 .run(Task.Expect.FAIL) 423 .writeAll() 424 .getOutputLines(Task.OutputKind.DIRECT); 425 426 List<String> expected = Arrays.asList( 427 "module-info.java:1:26: compiler.err.service.definition.is.inner: p1.C1.InnerDefinition", 428 "module-info.java:1:12: compiler.warn.service.provided.but.not.exported.or.used: p1.C1.InnerDefinition", 429 "C2.java:1:20: compiler.err.encl.class.required: p1.C1.InnerDefinition", 430 "2 errors", 431 "1 warning"); 432 if (!output.containsAll(expected)) { 433 throw new Exception("Expected output not found"); 434 } 435 } 436} 437