AnnotationProcessorsInModulesTest.java revision 3294:9adfb22ff08f
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 Verify that annotation processors inside modules works
27 * @library /tools/lib
28 * @modules
29 *      jdk.compiler/com.sun.tools.javac.api
30 *      jdk.compiler/com.sun.tools.javac.main
31 *      jdk.jdeps/com.sun.tools.javap
32 * @build ToolBox ModuleTestBase
33 * @run main AnnotationProcessorsInModulesTest
34 */
35
36import java.nio.file.Files;
37import java.nio.file.Path;
38import java.util.Arrays;
39import java.util.List;
40
41public class AnnotationProcessorsInModulesTest extends ModuleTestBase {
42
43    public static void main(String... args) throws Exception {
44        new AnnotationProcessorsInModulesTest().runTests();
45    }
46
47    private static final String annotationProcessorModule1 =
48            "module anno_proc1 {\n" +
49            "    requires java.compiler;\n" +
50            "\n" +
51            "    provides javax.annotation.processing.Processor\n" +
52            "      with mypkg1.MyProcessor1;\n" +
53            "}";
54
55    private static final String annotationProcessorModule2 =
56            "module anno_proc2 {\n" +
57            "    requires java.compiler;\n" +
58            "\n" +
59            "    provides javax.annotation.processing.Processor\n" +
60            "      with mypkg2.MyProcessor2;\n" +
61            "}";
62
63    private static final String annotationProcessor1 =
64            "package mypkg1;\n" +
65            "\n" +
66            "import javax.annotation.processing.AbstractProcessor;\n" +
67            "import javax.annotation.processing.RoundEnvironment;\n" +
68            "import javax.annotation.processing.SupportedAnnotationTypes;\n" +
69            "import javax.lang.model.SourceVersion;\n" +
70            "import javax.lang.model.element.*;\n" +
71            "\n" +
72            "import java.util.*;\n" +
73            "\n" +
74            "@SupportedAnnotationTypes(\"*\")\n" +
75            "public final class MyProcessor1 extends AbstractProcessor {\n" +
76            "\n" +
77            "    @Override\n" +
78            "    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n" +
79            "        return false;\n" +
80            "    }\n" +
81            "\n" +
82            "    @Override\n" +
83            "    public SourceVersion getSupportedSourceVersion() {\n" +
84            "        System.out.println(\"the annotation processor 1 is working!\");\n" +
85            "        return SourceVersion.latest();\n" +
86            "    }\n" +
87            "}";
88
89    private static final String annotationProcessor2 =
90            "package mypkg2;\n" +
91            "\n" +
92            "import javax.annotation.processing.AbstractProcessor;\n" +
93            "import javax.annotation.processing.RoundEnvironment;\n" +
94            "import javax.annotation.processing.SupportedAnnotationTypes;\n" +
95            "import javax.lang.model.SourceVersion;\n" +
96            "import javax.lang.model.element.*;\n" +
97            "\n" +
98            "import java.util.*;\n" +
99            "\n" +
100            "@SupportedAnnotationTypes(\"*\")\n" +
101            "public final class MyProcessor2 extends AbstractProcessor {\n" +
102            "\n" +
103            "    @Override\n" +
104            "    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n" +
105            "        return false;\n" +
106            "    }\n" +
107            "\n" +
108            "    @Override\n" +
109            "    public SourceVersion getSupportedSourceVersion() {\n" +
110            "        System.out.println(\"the annotation processor 2 is working!\");\n" +
111            "        return SourceVersion.latest();\n" +
112            "    }\n" +
113            "}";
114
115    private static final String testClass = "class Test{}";
116
117    void initialization(Path base) throws Exception {
118        moduleSrc = base.resolve("anno_proc_src");
119        Path anno_proc1 = moduleSrc.resolve("anno_proc1");
120        Path anno_proc2 = moduleSrc.resolve("anno_proc2");
121
122        processorCompiledModules = base.resolve("mods");
123
124        Files.createDirectories(processorCompiledModules);
125
126        tb.writeJavaFiles(
127                anno_proc1,
128                annotationProcessorModule1,
129                annotationProcessor1);
130
131        tb.writeJavaFiles(
132                anno_proc2,
133                annotationProcessorModule2,
134                annotationProcessor2);
135
136        String log = tb.new JavacTask()
137                .options("-modulesourcepath", moduleSrc.toString())
138                .outdir(processorCompiledModules)
139                .files(findJavaFiles(moduleSrc))
140                .run()
141                .writeAll()
142                .getOutput(ToolBox.OutputKind.DIRECT);
143
144        if (!log.isEmpty()) {
145            throw new AssertionError("Unexpected output: " + log);
146        }
147
148        classes = base.resolve("classes");
149        Files.createDirectories(classes);
150    }
151
152    Path processorCompiledModules;
153    Path moduleSrc;
154    Path classes;
155
156    @Test
157    void testUseOnlyOneProcessor(Path base) throws Exception {
158        initialization(base);
159        String log = tb.new JavacTask()
160                .options("-processormodulepath", processorCompiledModules.toString(),
161                        "-processor", "mypkg2.MyProcessor2")
162                .outdir(classes)
163                .sources(testClass)
164                .run()
165                .writeAll()
166                .getOutput(ToolBox.OutputKind.STDOUT);
167        if (!log.trim().equals("the annotation processor 2 is working!")) {
168            throw new AssertionError("Unexpected output: " + log);
169        }
170    }
171
172    @Test
173    void testAnnotationProcessorExecutionOrder(Path base) throws Exception {
174        initialization(base);
175        List<String> log = tb.new JavacTask()
176                .options("-processormodulepath", processorCompiledModules.toString(),
177                        "-processor", "mypkg1.MyProcessor1,mypkg2.MyProcessor2")
178                .outdir(classes)
179                .sources(testClass)
180                .run()
181                .writeAll()
182                .getOutputLines(ToolBox.OutputKind.STDOUT);
183        if (!log.equals(Arrays.asList("the annotation processor 1 is working!",
184                                      "the annotation processor 2 is working!"))) {
185            throw new AssertionError("Unexpected output: " + log);
186        }
187
188        log = tb.new JavacTask()
189                .options("-processormodulepath", processorCompiledModules.toString(),
190                        "-processor", "mypkg2.MyProcessor2,mypkg1.MyProcessor1")
191                .outdir(classes)
192                .sources(testClass)
193                .run()
194                .writeAll()
195                .getOutputLines(ToolBox.OutputKind.STDOUT);
196        if (!log.equals(Arrays.asList("the annotation processor 2 is working!",
197                                      "the annotation processor 1 is working!"))) {
198            throw new AssertionError("Unexpected output: " + log);
199        }
200    }
201
202    @Test
203    void testErrorOutputIfOneProcessorNameIsIncorrect(Path base) throws Exception {
204        initialization(base);
205        String log = tb.new JavacTask()
206                .options("-XDrawDiagnostics", "-processormodulepath", processorCompiledModules.toString(),
207                         "-processor", "mypkg2.MyProcessor2,noPackage.noProcessor,mypkg1.MyProcessor1")
208                .outdir(classes)
209                .sources(testClass)
210                .run(ToolBox.Expect.FAIL)
211                .writeAll()
212                .getOutputLines(ToolBox.OutputKind.STDOUT, ToolBox.OutputKind.DIRECT).toString();
213        if (!log.trim().equals("[the annotation processor 2 is working!, - compiler.err.proc.processor.not.found: noPackage.noProcessor, 1 error]")) {
214            throw new AssertionError("Unexpected output: " + log);
215        }
216    }
217
218    @Test
219    void testOptionsExclusion(Path base) throws Exception {
220        initialization(base);
221        List<String> log = tb.new JavacTask()
222                .options("-XDrawDiagnostics", "-processormodulepath", processorCompiledModules.toString(),
223                        "-processorpath", processorCompiledModules.toString())
224                .outdir(classes)
225                .sources(testClass)
226                .run(ToolBox.Expect.FAIL)
227                .writeAll()
228                .getOutputLines(ToolBox.OutputKind.DIRECT);
229        if (!log.equals(Arrays.asList("- compiler.err.processorpath.no.processormodulepath",
230                                      "1 error"))) {
231            throw new AssertionError("Unexpected output: " + log);
232        }
233    }
234}
235