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