SjavacImpl.java revision 2958:27da0c3ac83a
1/* 2 * Copyright (c) 2014, 2015, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25package com.sun.tools.sjavac.comp; 26 27import java.io.File; 28import java.io.IOException; 29import java.io.PrintWriter; 30import java.io.StringWriter; 31import java.net.URI; 32import java.util.Arrays; 33import java.util.Iterator; 34import java.util.List; 35import java.util.Set; 36 37import javax.tools.JavaFileObject; 38import javax.tools.StandardJavaFileManager; 39import javax.tools.StandardLocation; 40import javax.tools.ToolProvider; 41 42import com.sun.tools.javac.api.JavacTaskImpl; 43import com.sun.tools.javac.api.JavacTool; 44import com.sun.tools.javac.util.Context; 45import com.sun.tools.javac.util.Dependencies; 46import com.sun.tools.javac.util.ListBuffer; 47import com.sun.tools.javac.util.Options; 48import com.sun.tools.sjavac.Log; 49import com.sun.tools.sjavac.Util; 50import com.sun.tools.sjavac.comp.dependencies.NewDependencyCollector; 51import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector; 52import com.sun.tools.sjavac.server.CompilationResult; 53import com.sun.tools.sjavac.server.Sjavac; 54import com.sun.tools.sjavac.server.SysInfo; 55 56/** 57 * The sjavac implementation that interacts with javac and performs the actual 58 * compilation. 59 * 60 * <p><b>This is NOT part of any supported API. 61 * If you write code that depends on this, you do so at your own risk. 62 * This code and its internal interfaces are subject to change or 63 * deletion without notice.</b> 64 */ 65public class SjavacImpl implements Sjavac { 66 67 @Override 68 public SysInfo getSysInfo() { 69 return new SysInfo(Runtime.getRuntime().availableProcessors(), 70 Runtime.getRuntime().maxMemory()); 71 } 72 73 @Override 74 public CompilationResult compile(String protocolId, 75 String invocationId, 76 String[] args, 77 List<File> explicitSources, 78 Set<URI> sourcesToCompile, 79 Set<URI> visibleSources) { 80 81 JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler(); 82 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 83 SmartFileManager sfm = new SmartFileManager(fm); 84 Context context = new Context(); 85 86 Dependencies.GraphDependencies.preRegister(context); 87 88 // Now setup the actual compilation 89 CompilationResult compilationResult = new CompilationResult(0); 90 91 // First deal with explicit source files on cmdline and in at file 92 ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>(); 93 for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(explicitSources)) { 94 explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH)); 95 } 96 // Now deal with sources supplied as source_to_compile 97 ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>(); 98 for (URI u : sourcesToCompile) 99 sourcesToCompileFiles.append(new File(u)); 100 101 for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) 102 explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH)); 103 104 // Create a new logger 105 StringWriter stdoutLog = new StringWriter(); 106 StringWriter stderrLog = new StringWriter(); 107 PrintWriter stdout = new PrintWriter(stdoutLog); 108 PrintWriter stderr = new PrintWriter(stderrLog); 109 com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK; 110 PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs); 111 PathAndPackageVerifier papVerifier = new PathAndPackageVerifier(); 112 NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs); 113 try { 114 if (explicitJFOs.size() > 0) { 115 sfm.setVisibleSources(visibleSources); 116 sfm.cleanArtifacts(); 117 sfm.setLog(stdout); 118 119 // Do the compilation! 120 JavacTaskImpl task = 121 (JavacTaskImpl) compiler.getTask(stderr, 122 sfm, 123 null, 124 Arrays.asList(args), 125 null, 126 explicitJFOs, 127 context); 128 sfm.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file")); 129 task.addTaskListener(depsCollector); 130 task.addTaskListener(pubApiCollector); 131 task.addTaskListener(papVerifier); 132 logJavacInvocation(args); 133 rc = task.doCall(); 134 Log.debug("javac returned with code " + rc); 135 sfm.flush(); 136 } 137 } catch (Exception e) { 138 Log.error(Util.getStackTrace(e)); 139 stderrLog.append(Util.getStackTrace(e)); 140 rc = com.sun.tools.javac.main.Main.Result.ERROR; 141 } 142 143 compilationResult.packageArtifacts = sfm.getPackageArtifacts(); 144 145 if (papVerifier.errorsDiscovered()) 146 rc = com.sun.tools.javac.main.Main.Result.ERROR; 147 148 compilationResult.packageDependencies = depsCollector.getDependencies(false); 149 compilationResult.packageCpDependencies = depsCollector.getDependencies(true); 150 151 compilationResult.packagePubapis = pubApiCollector.getPubApis(true); // pubApis.getPubapis(explicitJFOs, true); 152 compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false); // pubApis.getPubapis(explicitJFOs, false); 153 compilationResult.stdout = stdoutLog.toString(); 154 compilationResult.stderr = stderrLog.toString(); 155 compilationResult.returnCode = rc.exitCode; 156 157 return compilationResult; 158 } catch (IOException e) { 159 throw new Error(e); 160 } 161 } 162 163 @Override 164 public void shutdown() { 165 // Nothing to clean up 166 // ... maybe we should wait for any current request to finish? 167 } 168 169 @Override 170 public String serverSettings() { 171 return ""; 172 } 173 174 private void logJavacInvocation(String[] args) { 175 Log.debug("Invoking javac with args"); 176 Iterator<String> argIter = Arrays.asList(args).iterator(); 177 while (argIter.hasNext()) { 178 String arg = argIter.next(); 179 String line = " " + arg; 180 if (arg.matches("\\-(d|cp|classpath|sourcepath|source|target)") 181 && argIter.hasNext()) { 182 line += " " + argIter.next(); 183 } 184 Log.debug(line); 185 } 186 } 187} 188