1 /* 2 * Copyright (c) 2014, 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 */ 25 package com.sun.tools.sjavac.comp; 26 27 import java.io.File; 28 import java.io.IOException; 29 import java.io.PrintWriter; 30 import java.io.StringWriter; 31 import java.net.URI; 32 import java.util.Arrays; 33 import java.util.List; 34 import java.util.Set; 35 36 import javax.tools.JavaFileObject; 37 import javax.tools.StandardJavaFileManager; 38 import javax.tools.ToolProvider; 39 40 import com.sun.tools.javac.api.JavacTaskImpl; 41 import com.sun.tools.javac.api.JavacTool; 42 import com.sun.tools.javac.util.Context; 43 import com.sun.tools.javac.util.ListBuffer; 44 import com.sun.tools.javac.util.Options; 45 import com.sun.tools.sjavac.Log; 46 import com.sun.tools.sjavac.Util; 47 import com.sun.tools.sjavac.comp.dependencies.DependencyCollector; 48 import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector; 49 import com.sun.tools.sjavac.server.CompilationResult; 50 import com.sun.tools.sjavac.server.Sjavac; 51 import com.sun.tools.sjavac.server.SysInfo; 52 53 /** 54 * The sjavac implementation that interacts with javac and performs the actual 55 * compilation. 56 * 57 * <p><b>This is NOT part of any supported API. 58 * If you write code that depends on this, you do so at your own risk. 59 * This code and its internal interfaces are subject to change or 60 * deletion without notice.</b> 61 */ 62 public class SjavacImpl implements Sjavac { 63 static Object lock = new Object(); 64 @Override 65 public SysInfo getSysInfo() { 66 return new SysInfo(Runtime.getRuntime().availableProcessors(), 67 Runtime.getRuntime().maxMemory()); 68 } 69 70 @Override 71 public CompilationResult compile(String protocolId, 72 String invocationId, 73 String[] args, 74 List<File> explicitSources, 75 Set<URI> sourcesToCompile, 76 Set<URI> visibleSources) { 77 78 JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler(); 79 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 80 SmartFileManager sfm = new SmartFileManager(fm); 81 Context context = new Context(); 82 83 // Now setup the actual compilation 84 CompilationResult compilationResult = new CompilationResult(0); 85 86 // First deal with explicit source files on cmdline and in at file 87 ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>(); 88 for (JavaFileObject i : fm.getJavaFileObjectsFromFiles(explicitSources)) { 89 explicitJFOs.append(i); 90 } 91 // Now deal with sources supplied as source_to_compile 92 ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>(); 93 for (URI u : sourcesToCompile) 94 sourcesToCompileFiles.append(new File(u)); 95 96 for (JavaFileObject i : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) 97 explicitJFOs.append(i); 98 99 // Create a new logger 100 StringWriter stdoutLog = new StringWriter(); 101 StringWriter stderrLog = new StringWriter(); 102 PrintWriter stdout = new PrintWriter(stdoutLog); 103 PrintWriter stderr = new PrintWriter(stderrLog); 104 com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK; 105 DependencyCollector depsCollector = new DependencyCollector(context); 106 PublicApiCollector pubApiCollector = new PublicApiCollector(context); 107 PathAndPackageVerifier papVerifier = new PathAndPackageVerifier(); 108 try { 109 if (explicitJFOs.size() > 0) { 110 sfm.setVisibleSources(visibleSources); 111 sfm.cleanArtifacts(); 112 sfm.setLog(stdout); 113 114 // Do the compilation! 115 JavacTaskImpl task = 116 (JavacTaskImpl) compiler.getTask(stderr, 117 sfm, 118 null, 119 Arrays.asList(args), 120 null, 121 explicitJFOs, 122 context); 123 sfm.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file")); 124 task.addTaskListener(depsCollector); 125 task.addTaskListener(pubApiCollector); 126 task.addTaskListener(papVerifier); 127 Log.debug("Invoking javac with args"); 128 Arrays.asList(args).forEach(arg -> Log.debug(" " + arg)); 129 rc = task.doCall(); 130 Log.debug("javac returned with code " + rc); 131 sfm.flush(); 132 } 133 } catch (Exception e) { 134 Log.error(Util.getStackTrace(e)); 135 stderrLog.append(Util.getStackTrace(e)); 136 rc = com.sun.tools.javac.main.Main.Result.ERROR; 137 } 138 139 compilationResult.packageArtifacts = sfm.getPackageArtifacts(); 140 141 if (papVerifier.errorsDiscovered()) 142 rc = com.sun.tools.javac.main.Main.Result.ERROR; 143 144 Dependencies deps = Dependencies.instance(context); 145 compilationResult.packageDependencies = deps.getDependencies(explicitJFOs); 146 compilationResult.packageCpDependencies = deps.getCpDependencies(explicitJFOs); 147 compilationResult.packagePubapis = deps.getPubapis(explicitJFOs, true); 148 compilationResult.dependencyPubapis = deps.getPubapis(explicitJFOs, false); 149 compilationResult.stdout = stdoutLog.toString(); 150 compilationResult.stderr = stderrLog.toString(); 151 compilationResult.returnCode = rc.exitCode; 152 153 return compilationResult; 154 } catch (IOException e) { 155 throw new Error(e); 156 } 157 } 158 159 @Override 160 public void shutdown() { 161 // Nothing to clean up 162 // ... maybe we should wait for any current request to finish? 163 } 164 165 166 @Override 167 public String serverSettings() { 168 return ""; 169 } 170 171 }