1 /*
   2  * Copyright (c) 2018, 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  *  @bug 8198552
  27  *  @summary Check that multiple plugins can be specified when starting javac
  28  *  @library /tools/lib
  29  *  @modules 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.ToolBox toolbox.JavacTask toolbox.JarTask
  33  *  @run main MultiplePlugins
  34  */
  35 
  36 import java.io.File;
  37 import java.io.IOException;
  38 import java.nio.file.Path;
  39 import java.nio.file.Paths;
  40 import java.util.Arrays;
  41 import java.util.List;
  42 
  43 import javax.tools.JavaCompiler;
  44 import javax.tools.StandardJavaFileManager;
  45 import javax.tools.StandardLocation;
  46 import javax.tools.ToolProvider;
  47 
  48 import toolbox.JarTask;
  49 import toolbox.JavacTask;
  50 import toolbox.Task;
  51 import toolbox.ToolBox;
  52 
  53 public class MultiplePlugins {
  54     public static void main(String... args) throws Exception {
  55         new MultiplePlugins().run();
  56     }
  57 
  58     final File pluginClasses;
  59     final File pluginJar;
  60     final JavaCompiler compiler;
  61     final StandardJavaFileManager fm;
  62     final ToolBox tb = new ToolBox();
  63 
  64     MultiplePlugins() throws Exception {
  65         pluginClasses = new File("plugin");
  66         tb.createDirectories(pluginClasses.toPath());
  67         pluginJar = new File("plugin.jar");
  68         compiler = ToolProvider.getSystemJavaCompiler();
  69         fm = compiler.getStandardFileManager(null, null, null);
  70     }
  71 
  72     void run() throws Exception {
  73         try {
  74             // compile the plugins:
  75             new JavacTask(tb)
  76               .options("-d", pluginClasses.getPath())
  77               .sources(PLUGIN1, PLUGIN2)
  78               .run();
  79 
  80             File plugin = new File(pluginClasses.getPath(), "META-INF/services/com.sun.source.util.Plugin");
  81             tb.writeFile(plugin.getPath(), "Plugin1\nPlugin2\n");
  82             new JarTask(tb)
  83               .run("cf", pluginJar.getPath(), "-C", pluginClasses.getPath(), ".");
  84 
  85             testCommandLine("-Xplugin:plugin1", "-Xplugin:plugin2", EXPECTED);
  86             testAPI("-Xplugin:plugin1", "-Xplugin:plugin2", EXPECTED);
  87 
  88             if (errors > 0)
  89                 throw new Exception(errors + " errors occurred");
  90         } finally {
  91             fm.close();
  92         }
  93     }
  94 
  95     void testAPI(String opt1, String opt2, List<String> ref) throws Exception {
  96         fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, Arrays.asList(pluginJar));
  97         fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
  98 
  99         System.err.println("test api: " + opt1 + " " + opt2);
 100         Task.Result result = new JavacTask(tb, Task.Mode.API)
 101                                   .fileManager(fm)
 102                                   .options(opt1, opt2)
 103                                   .sources(TEST)
 104                                   .run(Task.Expect.SUCCESS)
 105                                   .writeAll();
 106         List<String> out = result.getOutputLines(Task.OutputKind.STDERR);
 107         checkOutput(out, ref);
 108     }
 109 
 110     void testCommandLine(String opt1, String opt2, List<String> ref) throws IOException {
 111         Path testJavaFile = Paths.get("Test.java");
 112 
 113         tb.writeFile(testJavaFile, TEST);
 114 
 115         String[] args = {
 116             "-d", ".",
 117             "-processorpath", pluginJar.getPath(),
 118             opt1,
 119             opt2};
 120 
 121         System.err.println("test command line: " + Arrays.asList(args));
 122         Task.Result result = new JavacTask(tb, Task.Mode.CMDLINE)
 123                                   .options(args)
 124                                   .files(testJavaFile)
 125                                   .run(Task.Expect.SUCCESS)
 126                                   .writeAll();
 127         List<String> out = result.getOutputLines(Task.OutputKind.STDERR);
 128         checkOutput(out, ref);
 129     }
 130 
 131     private void checkOutput(List<String> lines, List<String> ref) {
 132         if (!lines.equals(ref)) {
 133             error("unexpected output");
 134         }
 135     }
 136 
 137     private void error(String msg) {
 138         System.err.println(msg);
 139         errors++;
 140     }
 141 
 142     int errors;
 143 
 144     private static final String PLUGIN1 =
 145             "import com.sun.source.util.*;\n" +
 146             "public class Plugin1 implements Plugin {\n" +
 147             "    public String getName() {\n" +
 148             "        return \"plugin1\";\n" +
 149             "    }\n" +
 150             "    public void init(JavacTask task, String... args) {\n" +
 151             "        System.err.println(\"plugin1\");\n" +
 152             "    }\n" +
 153             "}";
 154     private static final String PLUGIN2 =
 155             "import com.sun.source.util.*;\n" +
 156             "public class Plugin2 implements Plugin {\n" +
 157             "    public String getName() {\n" +
 158             "        return \"plugin2\";\n" +
 159             "    }\n" +
 160             "    public void init(JavacTask task, String... args) {\n" +
 161             "        System.err.println(\"plugin2\");\n" +
 162             "    }\n" +
 163             "}";
 164     private static final String TEST =
 165             "public class Test {}";
 166     private static final List<String> EXPECTED = List.of(
 167             "plugin1",
 168             "plugin2"
 169     );
 170 
 171 }