ProvidesTest.java revision 3946:fa6d7795efcd
14Srgrimes/*
24Srgrimes * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
34Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44Srgrimes *
54Srgrimes * This code is free software; you can redistribute it and/or modify it
64Srgrimes * under the terms of the GNU General Public License version 2 only, as
74Srgrimes * published by the Free Software Foundation.
84Srgrimes *
94Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
104Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
114Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
124Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
134Srgrimes * accompanied this code).
144Srgrimes *
154Srgrimes * You should have received a copy of the GNU General Public License version
164Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
174Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
184Srgrimes *
194Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
204Srgrimes * or visit www.oracle.com if you need additional information or have any
214Srgrimes * questions.
224Srgrimes */
234Srgrimes
244Srgrimes/**
25118Srgrimes * @test
262056Swollman * @summary simple tests of module provides
274Srgrimes * @bug 8168854 8172807
284Srgrimes * @library /tools/lib
294Srgrimes * @modules
304Srgrimes *      jdk.compiler/com.sun.tools.javac.api
314Srgrimes *      jdk.compiler/com.sun.tools.javac.main
322056Swollman * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
332056Swollman * @run main ProvidesTest
342056Swollman */
352056Swollman
364Srgrimesimport java.nio.file.Files;
374Srgrimesimport java.nio.file.Path;
384Srgrimesimport java.util.Arrays;
394Srgrimesimport java.util.List;
404Srgrimes
414Srgrimesimport toolbox.JavacTask;
424Srgrimesimport toolbox.Task;
434Srgrimesimport toolbox.Task.Expect;
444Srgrimes
454Srgrimespublic class ProvidesTest extends ModuleTestBase {
464Srgrimes    public static void main(String... args) throws Exception {
474Srgrimes        ProvidesTest t = new ProvidesTest();
484Srgrimes        t.runTests();
494Srgrimes    }
504Srgrimes
514Srgrimes    @Test
524Srgrimes    public void testSimple(Path base) throws Exception {
534Srgrimes        Path src = base.resolve("src");
544Srgrimes        tb.writeJavaFiles(src,
554Srgrimes                "module m { provides p1.C1 with p2.C2; }",
564Srgrimes                "package p1; public class C1 { }",
574Srgrimes                "package p2; public class C2 extends p1.C1 { }");
584Srgrimes        Path classes = base.resolve("classes");
594Srgrimes        Files.createDirectories(classes);
604Srgrimes
614Srgrimes        new JavacTask(tb)
624Srgrimes                .outdir(classes)
634Srgrimes                .files(findJavaFiles(src))
644Srgrimes                .run(Task.Expect.SUCCESS)
654Srgrimes                .writeAll();
664Srgrimes    }
674Srgrimes
684Srgrimes    @Test
694Srgrimes    public void testMulti(Path base) throws Exception {
704Srgrimes        Path src = base.resolve("src");
714Srgrimes        tb.writeJavaFiles(src.resolve("m1x"),
724Srgrimes                "module m1x { exports p1; }",
734Srgrimes                "package p1; public class C1 { }");
744Srgrimes        tb.writeJavaFiles(src.resolve("m2x"),
754Srgrimes                "module m2x { requires m1x; provides p1.C1 with p2.C2; }",
764Srgrimes                "package p2; public class C2 extends p1.C1 { }");
774Srgrimes        Path modules = base.resolve("modules");
784Srgrimes        Files.createDirectories(modules);
794Srgrimes
804Srgrimes        new JavacTask(tb)
814Srgrimes                .options("--module-source-path", src.toString())
824Srgrimes                .outdir(modules)
834Srgrimes                .files(findJavaFiles(src))
844Srgrimes                .run(Task.Expect.SUCCESS)
854Srgrimes                .writeAll();
864Srgrimes
874Srgrimes    }
884Srgrimes
894Srgrimes    @Test
904Srgrimes    public void testMissingWith(Path base) throws Exception {
914Srgrimes        Path src = base.resolve("src");
924Srgrimes        tb.writeJavaFiles(src,
934Srgrimes                "module m { provides p.C; }",
944Srgrimes                "package p; public class C { }");
954Srgrimes        Path classes = base.resolve("classes");
964Srgrimes        Files.createDirectories(classes);
974Srgrimes
984Srgrimes        String log = new JavacTask(tb)
994Srgrimes                .options("-XDrawDiagnostics")
1004Srgrimes                .outdir(classes)
1014Srgrimes                .files(findJavaFiles(src))
1024Srgrimes                .run(Task.Expect.FAIL)
1034Srgrimes                .writeAll()
1044Srgrimes                .getOutput(Task.OutputKind.DIRECT);
1054Srgrimes
1064Srgrimes        if (!log.contains("module-info.java:1:24: compiler.err.expected: 'with'"))
1074Srgrimes            throw new Exception("expected output not found");
1084Srgrimes
1094Srgrimes    }
1104Srgrimes
1114Srgrimes    @Test
1124Srgrimes    public void testDuplicateImplementations1(Path base) throws Exception {
1134Srgrimes        Path src = base.resolve("src");
1144Srgrimes        tb.writeJavaFiles(src,
1154Srgrimes                "module m { exports p1; exports p2; provides p1.C1 with p2.C2, p2.C2; }",
1164Srgrimes                "package p1; public class C1 { }",
1174Srgrimes                "package p2; public class C2 extends p1.C1 { }");
1184Srgrimes        Path classes = base.resolve("classes");
1194Srgrimes        Files.createDirectories(classes);
1204Srgrimes
1214Srgrimes        List<String> output = new JavacTask(tb)
1224Srgrimes                .options("-XDrawDiagnostics")
1234Srgrimes                .outdir(classes)
1244Srgrimes                .files(findJavaFiles(src))
1254Srgrimes                .run(Task.Expect.FAIL)
1264Srgrimes                .writeAll()
1274Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
1284Srgrimes
1294Srgrimes        List<String> expected = Arrays.asList(
1304Srgrimes                "module-info.java:1:65: compiler.err.duplicate.provides: p1.C1, p2.C2",
1314Srgrimes                "1 error");
1324Srgrimes        if (!output.containsAll(expected)) {
1334Srgrimes            throw new Exception("Expected output not found");
1344Srgrimes        }
1354Srgrimes    }
1364Srgrimes
1374Srgrimes    @Test
1384Srgrimes    public void testDuplicateImplementations2(Path base) throws Exception {
1394Srgrimes        Path src = base.resolve("src");
1404Srgrimes        tb.writeJavaFiles(src,
1414Srgrimes                "module m { exports p1; provides p1.C1 with p2.C2; provides p1.C1 with p2.C2; }",
1424Srgrimes                "package p1; public class C1 { }",
1434Srgrimes                "package p2; public class C2 extends p1.C1 { }");
1444Srgrimes        Path classes = base.resolve("classes");
1454Srgrimes        Files.createDirectories(classes);
1464Srgrimes
1474Srgrimes        List<String> output = new JavacTask(tb)
1484Srgrimes                .options("-XDrawDiagnostics")
1494Srgrimes                .outdir(classes)
1504Srgrimes                .files(findJavaFiles(src))
1514Srgrimes                .run(Task.Expect.FAIL)
1524Srgrimes                .writeAll()
1534Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
1544Srgrimes
1554Srgrimes        List<String> expected = Arrays.asList(
1564Srgrimes                "module-info.java:1:62: compiler.err.repeated.provides.for.service: p1.C1",
1574Srgrimes                "module-info.java:1:73: compiler.err.duplicate.provides: p1.C1, p2.C2",
1584Srgrimes                "2 errors");
1594Srgrimes        if (!output.containsAll(expected)) {
1604Srgrimes            throw new Exception("Expected output not found");
1614Srgrimes        }
1624Srgrimes    }
1634Srgrimes
1644Srgrimes    @Test
1654Srgrimes    public void testMissingService(Path base) throws Exception {
1664Srgrimes        Path src = base.resolve("src");
1674Srgrimes        tb.writeJavaFiles(src,
1684Srgrimes                "module m { provides p.Missing with p.C; }",
1694Srgrimes                "package p; public class C extends p.Missing { }");
1704Srgrimes
1714Srgrimes        List<String> output = new JavacTask(tb)
1724Srgrimes                .options("-XDrawDiagnostics")
1734Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
1744Srgrimes                .files(findJavaFiles(src))
1754Srgrimes                .run(Task.Expect.FAIL)
1764Srgrimes                .writeAll()
1774Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
1784Srgrimes
1794Srgrimes        List<String> expected = Arrays.asList(
1804Srgrimes                "C.java:1:36: compiler.err.cant.resolve.location: kindname.class, Missing, , , (compiler.misc.location: kindname.package, p, null)",
1814Srgrimes                "module-info.java:1:22: compiler.err.cant.resolve.location: kindname.class, Missing, , , (compiler.misc.location: kindname.package, p, null)",
1824Srgrimes                "2 errors");
1834Srgrimes        if (!output.containsAll(expected)) {
1844Srgrimes            throw new Exception("Expected output not found");
1854Srgrimes        }
1864Srgrimes    }
1874Srgrimes
1884Srgrimes    @Test
1894Srgrimes    public void testProvidesFromAnotherModule(Path base) throws Exception {
1904Srgrimes        Path modules = base.resolve("modules");
1914Srgrimes        tb.writeJavaFiles(modules.resolve("M"),
1924Srgrimes                "module M { exports p; }",
1934Srgrimes                "package p; public class Service { }");
1944Srgrimes        tb.writeJavaFiles(modules.resolve("L"),
1954Srgrimes                "module L { requires M; provides p.Service with p.Service; }");
1964Srgrimes
1974Srgrimes        List<String> output = new JavacTask(tb)
1984Srgrimes                .options("-XDrawDiagnostics",
1994Srgrimes                        "--module-source-path", modules.toString())
2004Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
2014Srgrimes                .files(findJavaFiles(modules))
2024Srgrimes                .run(Task.Expect.FAIL)
2034Srgrimes                .writeAll()
2044Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
2054Srgrimes        List<String> expected = Arrays.asList(
2064Srgrimes                "module-info.java:1:24: compiler.err.service.implementation.not.in.right.module: M",
2074Srgrimes                "1 error");
2084Srgrimes        if (!output.containsAll(expected)) {
2094Srgrimes            throw new Exception("Expected output not found");
2104Srgrimes        }
2114Srgrimes
2124Srgrimes    }
2134Srgrimes
2144Srgrimes    @Test
2154Srgrimes    public void testServiceIsNotImplemented(Path base) throws Exception {
2164Srgrimes        Path src = base.resolve("src");
2174Srgrimes        tb.writeJavaFiles(src,
2184Srgrimes                "module m { provides p.A with p.B; }",
2194Srgrimes                "package p; public class A { }",
2204Srgrimes                "package p; public class B { }");
2214Srgrimes
2224Srgrimes        List<String> output = new JavacTask(tb)
2234Srgrimes                .options("-XDrawDiagnostics")
2244Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
2254Srgrimes                .files(findJavaFiles(src))
2264Srgrimes                .run(Task.Expect.FAIL)
2274Srgrimes                .writeAll()
2284Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
2294Srgrimes
2304Srgrimes        List<String> expected = Arrays.asList(
2314Srgrimes                "module-info.java:1:31: compiler.err.service.implementation.must.be.subtype.of.service.interface",
2324Srgrimes                "module-info.java:1:12: compiler.warn.service.provided.but.not.exported.or.used: p.A",
2334Srgrimes                "1 error",
2344Srgrimes                "1 warning");
2354Srgrimes        if (!output.containsAll(expected)) {
2364Srgrimes            throw new Exception("Expected output not found");
2374Srgrimes        }
2384Srgrimes    }
2394Srgrimes
2404Srgrimes    @Test
2414Srgrimes    public void testMissingImplementation(Path base) throws Exception {
2424Srgrimes        Path src = base.resolve("src");
2434Srgrimes        tb.writeJavaFiles(src,
2444Srgrimes                "module m { provides p.C with p.Impl; }",
2454Srgrimes                "package p; public class C { }");
2464Srgrimes
2474Srgrimes        List<String> output = new JavacTask(tb)
2484Srgrimes                .options("-XDrawDiagnostics")
2494Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
2504Srgrimes                .files(findJavaFiles(src))
2514Srgrimes                .run(Task.Expect.FAIL)
2524Srgrimes                .writeAll()
2534Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
2544Srgrimes
2554Srgrimes        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)",
2564Srgrimes                "1 error");
2574Srgrimes        if (!output.containsAll(expected)) {
2584Srgrimes            throw new Exception("Expected output not found");
2594Srgrimes        }
2604Srgrimes    }
2614Srgrimes
2624Srgrimes    @Test
2634Srgrimes    public void testSeveralImplementations(Path base) throws Exception {
2644Srgrimes        Path src = base.resolve("src");
2654Srgrimes        tb.writeJavaFiles(src,
2664Srgrimes                "module m { provides p.C with p.Impl1, p.Impl2; }",
2674Srgrimes                "package p; public class C { }",
2684Srgrimes                "package p; public class Impl1 extends p.C { }",
2694Srgrimes                "package p; public class Impl2 extends p.C { }");
2704Srgrimes
2714Srgrimes        new JavacTask(tb)
2724Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
2734Srgrimes                .files(findJavaFiles(src))
2744Srgrimes                .run(Task.Expect.SUCCESS)
2754Srgrimes                .writeAll();
2764Srgrimes    }
2774Srgrimes
2784Srgrimes    @Test
2794Srgrimes    public void testRepeatedProvides(Path base) throws Exception {
2804Srgrimes        Path src = base.resolve("src");
2814Srgrimes        tb.writeJavaFiles(src,
2824Srgrimes                "module m { exports p; provides p.C with p.Impl1; provides p.C with p.Impl2; }",
2834Srgrimes                "package p; public class C { }",
2844Srgrimes                "package p; public class Impl1 extends p.C { }",
2854Srgrimes                "package p; public class Impl2 extends p.C { }");
2864Srgrimes
2874Srgrimes        List<String> output = new JavacTask(tb)
2884Srgrimes                .options("-XDrawDiagnostics")
2894Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
2904Srgrimes                .files(findJavaFiles(src))
2914Srgrimes                .run(Task.Expect.FAIL)
2924Srgrimes                .writeAll()
2934Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
2944Srgrimes
2954Srgrimes        List<String> expected = Arrays.asList("module-info.java:1:60: compiler.err.repeated.provides.for.service: p.C",
2964Srgrimes                "1 error");
2974Srgrimes        if (!output.containsAll(expected)) {
2984Srgrimes            throw new Exception("Expected output not found");
2994Srgrimes        }
3004Srgrimes    }
3014Srgrimes
3024Srgrimes    @Test
3034Srgrimes    public void testOneImplementationsForServices(Path base) throws Exception {
3044Srgrimes        Path src = base.resolve("src");
3054Srgrimes        tb.writeJavaFiles(src,
3064Srgrimes                "module m { provides p.Service1 with p.Impl; provides p.Service2 with p.Impl; }",
3074Srgrimes                "package p; public interface Service1 { }",
3084Srgrimes                "package p; public abstract class Service2 { }",
3094Srgrimes                "package p; public class Impl extends p.Service2 implements p.Service1 { }");
3104Srgrimes
3114Srgrimes        new JavacTask(tb)
3124Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
3134Srgrimes                .files(findJavaFiles(src))
3144Srgrimes                .run(Task.Expect.SUCCESS)
3154Srgrimes                .writeAll();
3164Srgrimes    }
3174Srgrimes
3184Srgrimes    @Test
3194Srgrimes    public void testAbstractImplementation(Path base) throws Exception {
3204Srgrimes        Path src = base.resolve("src");
3214Srgrimes        tb.writeJavaFiles(src,
3224Srgrimes                "module m { provides p1.C1 with p2.C2; }",
3234Srgrimes                "package p1; public class C1 { }",
3244Srgrimes                "package p2; public abstract class C2 extends p1.C1 { }");
3254Srgrimes
3264Srgrimes        List<String> output = new JavacTask(tb)
3274Srgrimes                .options("-XDrawDiagnostics")
3284Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
3294Srgrimes                .files(findJavaFiles(src))
3304Srgrimes                .run(Task.Expect.FAIL)
3314Srgrimes                .writeAll()
3324Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
3334Srgrimes
3344Srgrimes        List<String> expected = Arrays.asList(
3354Srgrimes                "module-info.java:1:34: compiler.err.service.implementation.is.abstract: p2.C2");
3364Srgrimes        if (!output.containsAll(expected)) {
3374Srgrimes            throw new Exception("Expected output not found");
3384Srgrimes        }
3394Srgrimes    }
3404Srgrimes
3414Srgrimes    @Test
3424Srgrimes    public void testInterfaceImplementation(Path base) throws Exception {
3434Srgrimes        Path src = base.resolve("src");
3444Srgrimes        tb.writeJavaFiles(src,
3454Srgrimes                "module m { provides p1.Service with p2.Impl; }",
3464Srgrimes                "package p1; public interface Service { }",
3474Srgrimes                "package p2; public interface Impl extends p1.Service { }");
3484Srgrimes
3494Srgrimes        List<String> output = new JavacTask(tb)
3504Srgrimes                .options("-XDrawDiagnostics")
3514Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
3524Srgrimes                .files(findJavaFiles(src))
3534Srgrimes                .run(Task.Expect.FAIL)
3544Srgrimes                .writeAll()
3554Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
3564Srgrimes
3574Srgrimes        List<String> expected = Arrays.asList(
3584Srgrimes                "module-info.java:1:39: compiler.err.service.implementation.is.abstract: p2.Impl");
3594Srgrimes        if (!output.containsAll(expected)) {
3604Srgrimes            throw new Exception("Expected output not found");
3614Srgrimes        }
3624Srgrimes    }
3634Srgrimes
3644Srgrimes    @Test
3654Srgrimes    public void testProtectedImplementation(Path base) throws Exception {
3664Srgrimes        Path src = base.resolve("src");
3674Srgrimes        tb.writeJavaFiles(src,
3684Srgrimes                "module m { provides p1.C1 with p2.C2; }",
3694Srgrimes                "package p1; public class C1 { }",
3704Srgrimes                "package p2; class C2 extends p1.C1 { }");
3714Srgrimes
3724Srgrimes        List<String> output = new JavacTask(tb)
3734Srgrimes                .options("-XDrawDiagnostics")
3744Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
3754Srgrimes                .files(findJavaFiles(src))
3764Srgrimes                .run(Task.Expect.FAIL)
3774Srgrimes                .writeAll()
3784Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
3794Srgrimes
3804Srgrimes        List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public.cant.access: p2.C2, p2",
3814Srgrimes                "1 error");
3824Srgrimes        if (!output.containsAll(expected)) {
3834Srgrimes            throw new Exception("Expected output not found");
3844Srgrimes        }
3854Srgrimes    }
3864Srgrimes
3874Srgrimes    @Test
3884Srgrimes    public void testNoNoArgConstructor(Path base) throws Exception {
3894Srgrimes        Path src = base.resolve("src");
3904Srgrimes        tb.writeJavaFiles(src,
3914Srgrimes                "module m { uses p1.C1; provides p1.C1 with p2.C2; }",
3924Srgrimes                "package p1; public class C1 { }",
3934Srgrimes                "package p2; public class C2 extends p1.C1 { public C2(String str) { } }");
3944Srgrimes
3954Srgrimes        List<String> output = new JavacTask(tb)
3964Srgrimes                .options("-XDrawDiagnostics")
3974Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
3984Srgrimes                .files(findJavaFiles(src))
3994Srgrimes                .run(Task.Expect.FAIL)
4004Srgrimes                .writeAll()
4014Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
4024Srgrimes
4034Srgrimes        List<String> expected = Arrays.asList(
4044Srgrimes                "module-info.java:1:46: compiler.err.service.implementation.doesnt.have.a.no.args.constructor: p2.C2");
4054Srgrimes        if (!output.containsAll(expected)) {
4064Srgrimes            throw new Exception("Expected output not found");
4074Srgrimes        }
4084Srgrimes    }
4094Srgrimes
4104Srgrimes    @Test
4114Srgrimes    public void testPrivateNoArgConstructor(Path base) throws Exception {
4124Srgrimes        Path src = base.resolve("src");
4134Srgrimes        tb.writeJavaFiles(src,
4144Srgrimes                "module m { uses p1.C1; provides p1.C1 with p2.C2; }",
4154Srgrimes                "package p1; public class C1 { }",
4164Srgrimes                "package p2; public class C2 extends p1.C1 { private C2() { } }");
4174Srgrimes
4184Srgrimes        List<String> output = new JavacTask(tb)
4194Srgrimes                .options("-XDrawDiagnostics")
4204Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
4214Srgrimes                .files(findJavaFiles(src))
4224Srgrimes                .run(Task.Expect.FAIL)
4234Srgrimes                .writeAll()
4244Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
4254Srgrimes
4264Srgrimes        List<String> expected = Arrays.asList(
4274Srgrimes                "module-info.java:1:46: compiler.err.service.implementation.no.args.constructor.not.public: p2.C2");
4284Srgrimes        if (!output.containsAll(expected)) {
4294Srgrimes            throw new Exception("Expected output not found");
4304Srgrimes        }
4314Srgrimes    }
4324Srgrimes
4334Srgrimes    @Test
4344Srgrimes    public void testServiceIndirectlyImplemented(Path base) throws Exception {
4354Srgrimes        Path src = base.resolve("src");
4364Srgrimes        tb.writeJavaFiles(src,
4374Srgrimes                "module m { provides p1.C1 with p2.C3; }",
4384Srgrimes                "package p1; public class C1 { }",
4394Srgrimes                "package p2; public class C2 extends p1.C1 {  }",
4404Srgrimes                "package p2; public class C3 extends p2.C2 {  }");
4414Srgrimes
4424Srgrimes        new JavacTask(tb)
4434Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
4444Srgrimes                .files(findJavaFiles(src))
4454Srgrimes                .run(Task.Expect.SUCCESS)
4464Srgrimes                .writeAll();
4474Srgrimes    }
4484Srgrimes
4494Srgrimes    @Test
4504Srgrimes    public void testServiceImplementationInnerClass(Path base) throws Exception {
4514Srgrimes        Path src = base.resolve("src");
4524Srgrimes        tb.writeJavaFiles(src,
4534Srgrimes                "module m { provides p1.C1 with p2.C2.Inner; }",
4544Srgrimes                "package p1; public class C1 { }",
4554Srgrimes                "package p2; public class C2  { public class Inner extends p1.C1 { } }");
4564Srgrimes
4574Srgrimes        List<String> output = new JavacTask(tb)
4584Srgrimes                .options("-XDrawDiagnostics")
4594Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
4604Srgrimes                .files(findJavaFiles(src))
4614Srgrimes                .run(Task.Expect.FAIL)
4624Srgrimes                .writeAll()
4634Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
4644Srgrimes
4654Srgrimes        List<String> expected = Arrays.asList(
4664Srgrimes                "module-info.java:1:37: compiler.err.service.implementation.is.inner: p2.C2.Inner");
4674Srgrimes        if (!output.containsAll(expected)) {
4684Srgrimes            throw new Exception("Expected output not found");
4694Srgrimes        }
4704Srgrimes    }
4714Srgrimes
4724Srgrimes    @Test
4734Srgrimes    public void testServiceDefinitionInnerClass(Path base) throws Exception {
4744Srgrimes        Path src = base.resolve("src");
4754Srgrimes        tb.writeJavaFiles(src,
4764Srgrimes                "module m { provides p1.C1.InnerDefinition with p2.C2; }",
4774Srgrimes                "package p1; public class C1 { public class InnerDefinition { } }",
4784Srgrimes                "package p2; public class C2 extends p1.C1.InnerDefinition { public C2() { new p1.C1().super(); } }");
4794Srgrimes
4804Srgrimes        new JavacTask(tb)
4814Srgrimes                .options("-XDrawDiagnostics")
4824Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
4834Srgrimes                .files(findJavaFiles(src))
4844Srgrimes                .run(Expect.SUCCESS)
4854Srgrimes                .writeAll();
4864Srgrimes    }
4874Srgrimes
4884Srgrimes    @Test
4894Srgrimes    public void testFactory(Path base) throws Exception {
4904Srgrimes        Path src = base.resolve("src");
4914Srgrimes        tb.writeJavaFiles(src,
4924Srgrimes                "module m { exports p1; provides p1.C1 with p2.C2; }",
4934Srgrimes                "package p1; public interface C1 { }",
4944Srgrimes                "package p2; public class C2 { public static p1.C1 provider() { return null; } }");
4954Srgrimes
4964Srgrimes        new JavacTask(tb)
4974Srgrimes                .options("-XDrawDiagnostics")
4984Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
4994Srgrimes                .files(findJavaFiles(src))
5004Srgrimes                .run()
5014Srgrimes                .writeAll()
5024Srgrimes                .getOutput(Task.OutputKind.DIRECT);
5034Srgrimes
5044Srgrimes        List<String> output;
5054Srgrimes        List<String> expected;
5064Srgrimes
5074Srgrimes        tb.writeJavaFiles(src,
5084Srgrimes                "package p2; public class C2 { public p1.C1 provider() { return null; } }");
5094Srgrimes
5104Srgrimes        output = new JavacTask(tb)
5114Srgrimes                .options("-XDrawDiagnostics")
5124Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
5134Srgrimes                .files(findJavaFiles(src))
5144Srgrimes                .run(Task.Expect.FAIL)
5154Srgrimes                .writeAll()
5164Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
5174Srgrimes
5184Srgrimes        expected = Arrays.asList("module-info.java:1:46: compiler.err.service.implementation.must.be.subtype.of.service.interface",
5194Srgrimes                                 "1 error");
5204Srgrimes
5214Srgrimes        if (!expected.equals(output)) {
5224Srgrimes            throw new Exception("Expected output not found. Output: " + output);
5234Srgrimes        }
5244Srgrimes
5254Srgrimes        tb.writeJavaFiles(src,
5264Srgrimes                "package p2; public class C2 { static p1.C1 provider() { return null; } }");
5274Srgrimes
5284Srgrimes        output = new JavacTask(tb)
5294Srgrimes                .options("-XDrawDiagnostics")
5304Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
5314Srgrimes                .files(findJavaFiles(src))
5324Srgrimes                .run(Task.Expect.FAIL)
5334Srgrimes                .writeAll()
5344Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
5354Srgrimes
5364Srgrimes        expected = Arrays.asList("module-info.java:1:46: compiler.err.service.implementation.must.be.subtype.of.service.interface",
5374Srgrimes                                 "1 error");
5384Srgrimes
5394Srgrimes        if (!expected.equals(output)) {
5404Srgrimes            throw new Exception("Expected output not found. Output: " + output);
5414Srgrimes        }
5424Srgrimes
5434Srgrimes        tb.writeJavaFiles(src,
5444Srgrimes                "package p2; public class C2 { public static Object provider() { return null; } }");
5454Srgrimes
5464Srgrimes        output = new JavacTask(tb)
5474Srgrimes                .options("-XDrawDiagnostics")
5484Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
5494Srgrimes                .files(findJavaFiles(src))
5504Srgrimes                .run(Task.Expect.FAIL)
5514Srgrimes                .writeAll()
5524Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
5534Srgrimes
5544Srgrimes        expected = Arrays.asList("module-info.java:1:46: compiler.err.service.implementation.provider.return.must.be.subtype.of.service.interface",
5554Srgrimes                                 "1 error");
5564Srgrimes
5574Srgrimes        if (!expected.equals(output)) {
5584Srgrimes            throw new Exception("Expected output not found. Output: " + output);
5594Srgrimes        }
5604Srgrimes
5614Srgrimes        tb.writeJavaFiles(src,
5624Srgrimes                "package p2; public class C2 { public static p1.C1 provider = new p1.C1() {}; }");
5634Srgrimes
5644Srgrimes        output = new JavacTask(tb)
5654Srgrimes                .options("-XDrawDiagnostics")
5664Srgrimes                .outdir(Files.createDirectories(base.resolve("classes")))
5674Srgrimes                .files(findJavaFiles(src))
5684Srgrimes                .run(Task.Expect.FAIL)
5694Srgrimes                .writeAll()
5704Srgrimes                .getOutputLines(Task.OutputKind.DIRECT);
5714Srgrimes
5724Srgrimes        expected = Arrays.asList("module-info.java:1:46: compiler.err.service.implementation.must.be.subtype.of.service.interface",
5734Srgrimes                                 "1 error");
5744Srgrimes
5754Srgrimes        if (!expected.equals(output)) {
5764Srgrimes            throw new Exception("Expected output not found. Output: " + output);
5774Srgrimes        }
5784Srgrimes    }
5794Srgrimes}
5804Srgrimes