CompilationService.java revision 3356:b99518745035
1/* 2 * Copyright (c) 2015, 2016, 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 26package com.sun.tools.sjavac.comp; 27 28import java.io.File; 29import java.io.IOException; 30import java.io.PrintWriter; 31import java.io.StringWriter; 32import java.net.URI; 33import java.util.Arrays; 34import java.util.Iterator; 35import java.util.List; 36import java.util.Set; 37 38import javax.tools.JavaFileObject; 39import javax.tools.StandardJavaFileManager; 40import javax.tools.StandardLocation; 41import javax.tools.ToolProvider; 42 43import com.sun.tools.javac.api.JavacTaskImpl; 44import com.sun.tools.javac.api.JavacTool; 45import com.sun.tools.javac.main.Main; 46import com.sun.tools.javac.main.Main.Result; 47import com.sun.tools.javac.util.Context; 48import com.sun.tools.javac.util.Dependencies; 49import com.sun.tools.javac.util.ListBuffer; 50import com.sun.tools.sjavac.Log; 51import com.sun.tools.sjavac.Util; 52import com.sun.tools.sjavac.comp.dependencies.NewDependencyCollector; 53import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector; 54import com.sun.tools.sjavac.server.CompilationSubResult; 55import com.sun.tools.sjavac.server.SysInfo; 56 57/** 58 * <p><b>This is NOT part of any supported API. 59 * If you write code that depends on this, you do so at your own risk. 60 * This code and its internal interfaces are subject to change or 61 * deletion without notice.</b> 62 */ 63public class CompilationService { 64 65 public SysInfo getSysInfo() { 66 return new SysInfo(Runtime.getRuntime().availableProcessors(), 67 Runtime.getRuntime().maxMemory()); 68 } 69 70 public CompilationSubResult compile(String protocolId, 71 String invocationId, 72 String[] args, 73 List<File> explicitSources, 74 Set<URI> sourcesToCompile, 75 Set<URI> visibleSources) { 76 77 JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler(); 78 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 79 SmartFileManager sfm = new SmartFileManager(fm); 80 Context context = new Context(); 81 82 Dependencies.GraphDependencies.preRegister(context); 83 84 // Now setup the actual compilation 85 CompilationSubResult compilationResult = new CompilationSubResult(Result.OK); 86 87 // First deal with explicit source files on cmdline and in at file 88 ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>(); 89 for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(explicitSources)) { 90 explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH)); 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 jfo : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) 98 explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH)); 99 100 // Create a log to capture compiler output 101 StringWriter stderrLog = new StringWriter(); 102 Result result; 103 PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs); 104 PathAndPackageVerifier papVerifier = new PathAndPackageVerifier(); 105 NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs); 106 try { 107 if (explicitJFOs.size() > 0) { 108 sfm.setVisibleSources(visibleSources); 109 sfm.cleanArtifacts(); 110 111 // Do the compilation! 112 JavacTaskImpl task = 113 (JavacTaskImpl) compiler.getTask(new PrintWriter(stderrLog), 114 sfm, 115 null, 116 Arrays.asList(args), 117 null, 118 explicitJFOs, 119 context); 120 sfm.setSymbolFileEnabled(!com.sun.tools.javac.util.Options.instance(context).isSet("ignore.symbol.file")); 121 task.addTaskListener(depsCollector); 122 task.addTaskListener(pubApiCollector); 123 task.addTaskListener(papVerifier); 124 logJavacInvocation(args); 125 result = task.doCall(); 126 Log.debug("javac result: " + result); 127 sfm.flush(); 128 } else { 129 result = Result.ERROR; 130 } 131 } catch (Exception e) { 132 Log.error(Util.getStackTrace(e)); 133 stderrLog.append(Util.getStackTrace(e)); 134 result = Result.ERROR; 135 } 136 137 compilationResult.packageArtifacts = sfm.getPackageArtifacts(); 138 139 if (papVerifier.errorsDiscovered()) { 140 result = Result.ERROR; 141 } 142 143 compilationResult.packageDependencies = depsCollector.getDependencies(false); 144 compilationResult.packageCpDependencies = depsCollector.getDependencies(true); 145 146 compilationResult.packagePubapis = pubApiCollector.getPubApis(true); 147 compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false); 148 compilationResult.stderr = stderrLog.toString(); 149 compilationResult.result = result; 150 151 return compilationResult; 152 } catch (IOException e) { 153 throw new Error(e); 154 } 155 } 156 157 private void logJavacInvocation(String[] args) { 158 Log.debug("Invoking javac with args"); 159 Iterator<String> argIter = Arrays.asList(args).iterator(); 160 while (argIter.hasNext()) { 161 String arg = argIter.next(); 162 String line = " " + arg; 163 if (arg.matches("\\-(d|cp|classpath|sourcepath|source|target)") 164 && argIter.hasNext()) { 165 line += " " + argIter.next(); 166 } 167 Log.debug(line); 168 } 169 } 170 171} 172