SjavacImpl.java revision 2656:a0125e2a10e8
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 */
25package com.sun.tools.sjavac.comp;
26
27import java.io.File;
28import java.io.PrintWriter;
29import java.io.StringWriter;
30import java.net.URI;
31import java.util.Arrays;
32import java.util.List;
33import java.util.Set;
34import java.util.concurrent.atomic.AtomicBoolean;
35
36import javax.tools.JavaFileObject;
37import javax.tools.StandardJavaFileManager;
38
39import com.sun.tools.javac.api.JavacTaskImpl;
40import com.sun.tools.javac.api.JavacTool;
41import com.sun.tools.javac.code.Symbol.PackageSymbol;
42import com.sun.tools.javac.util.Context;
43import com.sun.tools.javac.util.ListBuffer;
44import com.sun.tools.javac.util.Options;
45import com.sun.tools.sjavac.Util;
46import com.sun.tools.sjavac.comp.dependencies.DependencyCollector;
47import com.sun.tools.sjavac.server.CompilationResult;
48import com.sun.tools.sjavac.server.Sjavac;
49import com.sun.tools.sjavac.server.SysInfo;
50
51/**
52 * The sjavac implementation that interacts with javac and performs the actual
53 * compilation.
54 *
55 *  <p><b>This is NOT part of any supported API.
56 *  If you write code that depends on this, you do so at your own risk.
57 *  This code and its internal interfaces are subject to change or
58 *  deletion without notice.</b>
59 */
60public class SjavacImpl implements Sjavac {
61
62    @Override
63    public SysInfo getSysInfo() {
64        return new SysInfo(Runtime.getRuntime().availableProcessors(),
65                           Runtime.getRuntime().maxMemory());
66    }
67
68    @Override
69    public CompilationResult compile(String protocolId,
70                                     String invocationId,
71                                     String[] args,
72                                     List<File> explicitSources,
73                                     Set<URI> sourcesToCompile,
74                                     Set<URI> visibleSources) {
75        final AtomicBoolean forcedExit = new AtomicBoolean();
76
77        JavacTool compiler = JavacTool.create();
78        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
79        SmartFileManager smartFileManager = new SmartFileManager(fileManager);
80        Context context = new Context();
81        JavaCompilerWithDeps.preRegister(context, new SjavacErrorHandler() {
82            @Override
83            public void logError(String msg) {
84                forcedExit.set(true);
85            }
86        });
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> compilationUnits = new ListBuffer<>();
93        for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
94            compilationUnits.append(i);
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 i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
102            compilationUnits.append(i);
103        }
104        forcedExit.set(false);
105
106
107        // Create a new logger.
108        StringWriter stdoutLog = new StringWriter();
109        StringWriter stderrLog = new StringWriter();
110        PrintWriter stdout = new PrintWriter(stdoutLog);
111        PrintWriter stderr = new PrintWriter(stderrLog);
112        com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
113        DependencyCollector depsCollector = new DependencyCollector();
114        try {
115            if (compilationUnits.size() > 0) {
116                smartFileManager.setVisibleSources(visibleSources);
117                smartFileManager.cleanArtifacts();
118                smartFileManager.setLog(stdout);
119
120                // Do the compilation!
121                JavacTaskImpl task =
122                        (JavacTaskImpl) compiler.getTask(stderr,
123                                                         smartFileManager,
124                                                         null,
125                                                         Arrays.asList(args),
126                                                         null,
127                                                         compilationUnits,
128                                                         context);
129                smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
130                task.addTaskListener(depsCollector);
131                rc = task.doCall();
132                smartFileManager.flush();
133            }
134        } catch (Exception e) {
135            stderrLog.append(Util.getStackTrace(e));
136            forcedExit.set(true);
137        }
138
139        compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
140
141        Dependencies deps = Dependencies.instance(context);
142        for (PackageSymbol from : depsCollector.getSourcePackages()) {
143            for (PackageSymbol to : depsCollector.getDependenciesForPkg(from))
144                deps.collect(from.fullname, to.fullname);
145        }
146
147        compilationResult.packageDependencies = deps.getDependencies();
148        compilationResult.packagePubapis = deps.getPubapis();
149
150        compilationResult.stdout = stdoutLog.toString();
151        compilationResult.stderr = stderrLog.toString();
152
153        compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
154
155        return compilationResult;
156    }
157
158    @Override
159    public void shutdown() {
160        // Nothing to clean up
161        // ... maybe we should wait for any current request to finish?
162    }
163
164
165    @Override
166    public String serverSettings() {
167        return "";
168    }
169
170}
171