jjg@1416: /* jjg@1416: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. jjg@1416: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jjg@1416: * jjg@1416: * This code is free software; you can redistribute it and/or modify it jjg@1416: * under the terms of the GNU General Public License version 2 only, as jjg@1416: * published by the Free Software Foundation. jjg@1416: * jjg@1416: * This code is distributed in the hope that it will be useful, but WITHOUT jjg@1416: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jjg@1416: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jjg@1416: * version 2 for more details (a copy is included in the LICENSE file that jjg@1416: * accompanied this code). jjg@1416: * jjg@1416: * You should have received a copy of the GNU General Public License version jjg@1416: * 2 along with this work; if not, write to the Free Software Foundation, jjg@1416: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jjg@1416: * jjg@1416: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jjg@1416: * or visit www.oracle.com if you need additional information or have any jjg@1416: * questions. jjg@1416: */ jjg@1416: jjg@1416: /** jjg@1416: * @test jjg@1457: * @bug 8001098 8004961 jjg@1416: * @summary Provide a simple light-weight "plug-in" mechanism for javac jjg@1416: */ jjg@1416: jjg@1457: import java.io.File; jjg@1457: import java.io.FileWriter; jjg@1457: import java.io.IOException; jjg@1457: import java.io.PrintWriter; jjg@1457: import java.io.StringWriter; jjg@1457: import java.nio.charset.Charset; jjg@1457: import java.nio.file.Files; jjg@1457: import java.util.Arrays; jjg@1457: import java.util.List; jjg@1457: import java.util.Locale; jjg@1457: import java.util.Objects; jjg@1457: import javax.tools.JavaCompiler; jjg@1457: import javax.tools.JavaFileManager; jjg@1457: import javax.tools.JavaFileObject; jjg@1457: import javax.tools.StandardJavaFileManager; jjg@1457: import javax.tools.StandardLocation; jjg@1457: import javax.tools.ToolProvider; jjg@1457: jjg@1416: public class Test { jjg@1416: public static void main(String... args) throws Exception { jjg@1416: new Test().run(); jjg@1416: } jjg@1416: jjg@1416: final File testSrc; jjg@1416: final File pluginSrc; jjg@1416: final File pluginClasses ; jjg@1416: final File pluginJar; jjg@1416: final List ref1; jjg@1416: final List ref2; jjg@1416: final JavaCompiler compiler; jjg@1416: final StandardJavaFileManager fm; jjg@1416: jjg@1416: Test() throws Exception { jjg@1416: testSrc = new File(System.getProperty("test.src")); jjg@1416: pluginSrc = new File(testSrc, "ShowTypePlugin.java"); jjg@1416: pluginClasses = new File("plugin"); jjg@1416: pluginJar = new File("plugin.jar"); jjg@1416: ref1 = readFile(testSrc, "Identifiers.out"); jjg@1416: ref2 = readFile(testSrc, "Identifiers_PI.out"); jjg@1416: compiler = ToolProvider.getSystemJavaCompiler(); jjg@1416: fm = compiler.getStandardFileManager(null, null, null); jjg@1416: } jjg@1416: jjg@1416: void run() throws Exception { jjg@1416: // compile the plugin explicitly, to a non-standard directory jjg@1416: // so that we don't find it on the wrong path by accident jjg@1416: pluginClasses.mkdirs(); jjg@1416: compile("-d", pluginClasses.getPath(), pluginSrc.getPath()); jjg@1416: writeFile(new File(pluginClasses, "META-INF/services/com.sun.source.util.Plugin"), jjg@1416: "ShowTypePlugin\n"); jjg@1416: jar("cf", pluginJar.getPath(), "-C", pluginClasses.getPath(), "."); jjg@1416: jjg@1416: testCommandLine("-Xplugin:showtype", ref1); jjg@1416: testCommandLine("-Xplugin:showtype PI", ref2); jjg@1416: testAPI("-Xplugin:showtype", ref1); jjg@1416: testAPI("-Xplugin:showtype PI", ref2); jjg@1416: jjg@1416: if (errors > 0) jjg@1416: throw new Exception(errors + " errors occurred"); jjg@1416: } jjg@1416: jjg@1416: void testAPI(String opt, List ref) throws Exception { jjg@1416: File identifiers = new File(testSrc, "Identifiers.java"); jjg@1416: fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, Arrays.asList(pluginJar)); jjg@1416: fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); jjg@1416: List options = Arrays.asList(opt); jjg@1416: Iterable files = fm.getJavaFileObjects(identifiers); jjg@1416: jjg@1416: System.err.println("test api: " + options + " " + files); jjg@1416: jjg@1416: StringWriter sw = new StringWriter(); jjg@1416: PrintWriter pw = new PrintWriter(sw); jjg@1416: boolean ok = compiler.getTask(pw, fm, null, options, null, files).call(); jjg@1416: String out = sw.toString(); jjg@1416: System.err.println(out); jjg@1416: if (!ok) jjg@1416: error("testCommandLine: compilation failed"); jjg@1416: checkOutput(out, ref); jjg@1416: } jjg@1416: jjg@1416: void testCommandLine(String opt, List ref) { jjg@1416: File identifiers = new File(testSrc, "Identifiers.java"); jjg@1416: String[] args = { jjg@1416: "-d", ".", jjg@1416: "-processorpath", pluginJar.getPath(), jjg@1416: opt, jjg@1416: identifiers.getPath() }; jjg@1416: jjg@1416: System.err.println("test command line: " + Arrays.asList(args)); jjg@1416: jjg@1416: StringWriter sw = new StringWriter(); jjg@1416: PrintWriter pw = new PrintWriter(sw); jjg@1416: int rc = com.sun.tools.javac.Main.compile(args, pw); jjg@1416: String out = sw.toString(); jjg@1416: System.err.println(out); jjg@1416: if (rc != 0) jjg@1416: error("testCommandLine: compilation failed"); jjg@1416: checkOutput(out, ref); jjg@1416: } jjg@1416: jjg@1416: private void checkOutput(String out, List ref) { jjg@1416: List lines = Arrays.asList(out jjg@1416: .replaceAll(".*?([A-Za-z.]+:[0-9]+: .*)", "$1") // remove file directory jjg@1416: .split("[\r\n]+")); // allow for newline formats jjg@1416: if (!lines.equals(ref)) { jjg@1416: error("unexpected output"); jjg@1416: } jjg@1416: } jjg@1416: jjg@1416: private void compile(String... args) throws Exception { jjg@1416: System.err.println("compile: " + Arrays.asList(args)); jjg@1416: int rc = com.sun.tools.javac.Main.compile(args); jjg@1416: if (rc != 0) jjg@1416: throw new Exception("compiled failed, rc=" + rc); jjg@1416: } jjg@1416: jjg@1416: private void jar(String... args) throws Exception { jjg@1416: System.err.println("jar: " + Arrays.asList(args)); jjg@1416: boolean ok = new sun.tools.jar.Main(System.out, System.err, "jar").run(args); jjg@1416: if (!ok) jjg@1416: throw new Exception("jar failed"); jjg@1416: } jjg@1416: jjg@1416: private List readFile(File dir, String name) throws IOException { jjg@1416: return Files.readAllLines(new File(dir, name).toPath(), Charset.defaultCharset()); jjg@1416: } jjg@1416: jjg@1416: private void writeFile(File f, String body) throws IOException { jjg@1416: f.getParentFile().mkdirs(); jjg@1416: try (FileWriter out = new FileWriter(f)) { jjg@1416: out.write(body); jjg@1416: } jjg@1416: } jjg@1416: jjg@1416: private void error(String msg) { jjg@1416: System.err.println(msg); jjg@1416: errors++; jjg@1416: } jjg@1416: jjg@1416: int errors; jjg@1416: }