# HG changeset patch # User lana # Date 1442001683 25200 # Node ID 618ea3c86a0d9d9ab77f28b296040dd1724f3b9a # Parent e20c281d78181a75d4532ded9ea8008ac6faf500# Parent dea8ac70d849f96df307a6822a33eb3d1b5ccf09 Merge diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 11 13:01:23 2015 -0700 @@ -1436,6 +1436,7 @@ } Assert.check(!sym.kind.isResolutionError()); try { + types.noWarnings.clear(); Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, allowBoxing, useVarargs, types.noWarnings); currentResolutionContext.addApplicableCandidate(sym, mt); diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/AutoFlushWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/AutoFlushWriter.java Fri Sep 11 13:01:23 2015 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac; + +import java.io.FilterWriter; +import java.io.IOException; +import java.io.Writer; + +public class AutoFlushWriter extends FilterWriter { + + public AutoFlushWriter(Writer out) { + super(out); + } + + @Override + public void write(int c) throws IOException { + super.write(c); + if (c == '\n' || c == '\r') + flush(); + } + + @Override + public void write(String str, int off, int len) throws IOException { + super.write(str, off, len); + if (str.contains("\n") || str.contains("\r")) + flush(); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + super.write(cbuf, off, len); + for (char c : cbuf) { + if (c == '\n' || c == '\r') { + flush(); + break; + } + } + } +} diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java Fri Sep 11 13:01:23 2015 -0700 @@ -31,7 +31,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import java.io.PrintStream; import java.io.Writer; import java.net.URI; import java.util.ArrayList; @@ -78,8 +77,8 @@ int debugLevel, boolean incremental, int numCores, - PrintStream out, - PrintStream err) { + Writer out, + Writer err) { boolean rc = true; for (String pkgName : pkgSrcs.keySet()) { String pkgNameF = pkgName.replace('.',File.separatorChar); diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Fri Sep 11 13:01:23 2015 -0700 @@ -26,14 +26,22 @@ package com.sun.tools.sjavac; import java.io.File; -import java.io.PrintStream; +import java.io.IOException; +import java.io.Writer; import java.net.URI; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import com.sun.tools.sjavac.comp.CompilationService; import com.sun.tools.sjavac.options.Options; @@ -83,8 +91,8 @@ int debugLevel, boolean incremental, int numCores, - final PrintStream out, - final PrintStream err) { + final Writer out, + final Writer err) { Log.debug("Performing CompileJavaPackages transform..."); @@ -200,102 +208,83 @@ } } - // The return values for each chunked compile. - final CompilationSubResult[] rn = new CompilationSubResult[numCompiles]; - // The requets, might or might not run as a background thread. - final Thread[] requests = new Thread[numCompiles]; - long start = System.currentTimeMillis(); - for (int i=0; iemptyList(), - cc.srcs, - visibleSources); - // In the code below we have to keep in mind that two - // different compilation results may include results for - // the same package. - synchronized (lock) { - - for (String pkg : rn[ii].packageArtifacts.keySet()) { - Set pkgArtifacts = rn[ii].packageArtifacts.get(pkg); - packageArtifacts.merge(pkg, pkgArtifacts, Util::union); - } - - for (String pkg : rn[ii].packageDependencies.keySet()) { - packageDependencies.putIfAbsent(pkg, new HashMap<>()); - packageDependencies.get(pkg).putAll(rn[ii].packageDependencies.get(pkg)); - } - - for (String pkg : rn[ii].packageCpDependencies.keySet()) { - packageCpDependencies.putIfAbsent(pkg, new HashMap<>()); - packageCpDependencies.get(pkg).putAll(rn[ii].packageCpDependencies.get(pkg)); - } + // Prepare compilation calls + List> compilationCalls = new ArrayList<>(); + final Object lock = new Object(); + for (int i = 0; i < numCompiles; i++) { + CompileChunk cc = compileChunks[i]; + if (cc.srcs.isEmpty()) { + continue; + } - for (String pkg : rn[ii].packagePubapis.keySet()) { - packagePubapis.merge(pkg, rn[ii].packagePubapis.get(pkg), PubApi::mergeTypes); - } - - for (String pkg : rn[ii].dependencyPubapis.keySet()) { - dependencyPubapis.merge(pkg, rn[ii].dependencyPubapis.get(pkg), PubApi::mergeTypes); - } - } + String chunkId = id + "-" + String.valueOf(i); + compilationCalls.add(() -> { + CompilationSubResult result = sjavac.compile("n/a", + chunkId, + args.prepJavacArgs(), + Collections.emptyList(), + cc.srcs, + visibleSources); + synchronized (lock) { + safeWrite(result.stdout, out); + safeWrite(result.stderr, err); } - }; + return result; + }); + } - if (cc.srcs.size() > 0) { - String numdeps = ""; - if (cc.numDependents > 0) numdeps = "(with "+cc.numDependents+" dependents) "; - if (!incremental || cc.numPackages > 16) { - String info = "("+cc.pkgFromTos+")"; - if (info.equals("( to )")) { - info = ""; - } - Log.info("Compiling "+cc.srcs.size()+" files "+numdeps+"in "+cc.numPackages+" packages "+info); - } else { - Log.info("Compiling "+cc.pkgNames+numdeps); - } - if (concurrentCompiles) { - requests[ii].start(); - } - else { - requests[ii].run(); - // If there was an error, then stop early when running single threaded. - if (rn[i].returnCode != 0) { - Log.info(rn[i].stdout); - Log.error(rn[i].stderr); - return false; - } - } + // Perform compilations and collect results + List subResults = new ArrayList<>(); + List> futs = new ArrayList<>(); + ExecutorService exec = Executors.newFixedThreadPool(concurrentCompiles ? compilationCalls.size() : 1); + for (Callable compilationCall : compilationCalls) { + futs.add(exec.submit(compilationCall)); + } + for (Future fut : futs) { + try { + subResults.add(fut.get()); + } catch (ExecutionException ee) { + Log.error("Compilation failed: " + ee.getMessage()); + } catch (InterruptedException ee) { + Log.error("Compilation interrupted: " + ee.getMessage()); + Thread.currentThread().interrupt(); } } - if (concurrentCompiles) { - // If there are background threads for the concurrent compiles, then join them. - for (int i=0; i pkgArtifacts = subResult.packageArtifacts.get(pkg); + packageArtifacts.merge(pkg, pkgArtifacts, Util::union); + } + + for (String pkg : subResult.packageDependencies.keySet()) { + packageDependencies.putIfAbsent(pkg, new HashMap<>()); + packageDependencies.get(pkg).putAll(subResult.packageDependencies.get(pkg)); + } + + for (String pkg : subResult.packageCpDependencies.keySet()) { + packageCpDependencies.putIfAbsent(pkg, new HashMap<>()); + packageCpDependencies.get(pkg).putAll(subResult.packageCpDependencies.get(pkg)); + } + + for (String pkg : subResult.packagePubapis.keySet()) { + packagePubapis.merge(pkg, subResult.packagePubapis.get(pkg), PubApi::mergeTypes); + } + + for (String pkg : subResult.dependencyPubapis.keySet()) { + dependencyPubapis.merge(pkg, subResult.dependencyPubapis.get(pkg), PubApi::mergeTypes); + } + + // Check the return values. + if (subResult.returnCode != 0) { + rc = false; } } - // Check the return values. - for (int i=0; i 0) { - if (rn[i].returnCode != 0) { - Log.info(rn[i].stdout); - Log.error(rn[i].stderr); - rc = false; - } - } - } long duration = System.currentTimeMillis() - start; long minutes = duration/60000; long seconds = (duration-minutes*60000)/1000; @@ -304,6 +293,16 @@ return rc; } + private void safeWrite(String str, Writer w) { + if (str.length() > 0) { + try { + w.write(str); + } catch (IOException e) { + Log.error("Could not print compilation output."); + } + } + } + /** * Split up the sources into compile chunks. If old package dependents information * is available, sort the order of the chunks into the most dependent first! diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java Fri Sep 11 13:01:23 2015 -0700 @@ -85,8 +85,8 @@ int debugLevel, boolean incremental, int numCores, - PrintStream out, - PrintStream err) { + Writer out, + Writer err) { boolean rc = true; for (String pkgName : pkgSrcs.keySet()) { String pkgNameF = Util.toFileSystemPath(pkgName); diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java Fri Sep 11 13:01:23 2015 -0700 @@ -31,7 +31,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.PrintStream; +import java.io.Writer; import java.net.URI; import java.util.HashSet; import java.util.Map; @@ -72,8 +72,8 @@ int debugLevel, boolean incremental, int numCores, - PrintStream out, - PrintStream err) + Writer out, + Writer err) { boolean rc = true; String dest_filename; diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java Fri Sep 11 13:01:23 2015 -0700 @@ -31,7 +31,7 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.io.PrintStream; +import java.io.Writer; import java.net.URI; import java.nio.file.NoSuchFileException; import java.text.SimpleDateFormat; @@ -131,12 +131,12 @@ private CompileJavaPackages compileJavaPackages = new CompileJavaPackages(); // Where to send stdout and stderr. - private PrintStream out, err; + private Writer out, err; // Command line options. private Options options; - JavacState(Options op, boolean removeJavacState, PrintStream o, PrintStream e) { + JavacState(Options op, boolean removeJavacState, Writer o, Writer e) { options = op; out = o; err = e; @@ -311,7 +311,7 @@ /** * Load a javac_state file. */ - public static JavacState load(Options options, PrintStream out, PrintStream err) { + public static JavacState load(Options options, Writer out, Writer err) { JavacState db = new JavacState(options, false, out, err); Module lastModule = null; Package lastPackage = null; diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java Fri Sep 11 13:01:23 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package com.sun.tools.sjavac; -import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Writer; /** * Utility class only for sjavac logging. @@ -37,7 +38,7 @@ * deletion without notice. */ public class Log { - private static PrintStream out, err; + private static PrintWriter out, err; public final static int WARN = 1; public final static int INFO = 2; @@ -71,9 +72,9 @@ err.println(msg); } - static public void initializeLog(PrintStream o, PrintStream e) { - out = o; - err = e; + static public void initializeLog(Writer o, Writer e) { + out = new PrintWriter(o); + err = new PrintWriter(e); } static public void setLogLevel(String l) { diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java Fri Sep 11 13:01:23 2015 -0700 @@ -25,7 +25,7 @@ package com.sun.tools.sjavac; -import java.io.PrintStream; +import java.io.Writer; import java.net.URI; import java.util.Map; import java.util.Set; @@ -97,8 +97,8 @@ int debugLevel, boolean incremental, int numCores, - PrintStream out, - PrintStream err); + Writer out, + Writer err); void setExtra(String e); void setExtra(Options args); diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java Fri Sep 11 13:01:23 2015 -0700 @@ -25,13 +25,14 @@ package com.sun.tools.sjavac.client; -import java.io.PrintStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import com.sun.tools.sjavac.AutoFlushWriter; import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.comp.SjavacImpl; import com.sun.tools.sjavac.options.Options; -import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.Sjavac; /** @@ -43,10 +44,12 @@ public class ClientMain { public static int run(String[] args) { - return run(args, System.out, System.err); + return run(args, + new AutoFlushWriter(new OutputStreamWriter(System.out)), + new AutoFlushWriter(new OutputStreamWriter(System.err))); } - public static int run(String[] args, PrintStream out, PrintStream err) { + public static int run(String[] args, Writer out, Writer err) { Log.initializeLog(out, err); @@ -78,14 +81,11 @@ sjavac = new SjavacImpl(); } - CompilationResult cr = sjavac.compile(args); - - out.print(cr.stdout); - err.print(cr.stderr); + int rc = sjavac.compile(args, out, err); if (!background) sjavac.shutdown(); - return cr.returnCode; + return rc; } } diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java Fri Sep 11 13:01:23 2015 -0700 @@ -25,11 +25,14 @@ package com.sun.tools.sjavac.client; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Writer; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; @@ -43,7 +46,6 @@ import com.sun.tools.sjavac.options.OptionHelper; import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.server.CompilationSubResult; -import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.PortFile; import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.SjavacServer; @@ -119,29 +121,47 @@ } @Override - public CompilationResult compile(String[] args) { - CompilationResult result; + public int compile(String[] args, Writer stdout, Writer stderr) { + int result = -1; try (Socket socket = tryConnect()) { - // The ObjectInputStream constructor will block until the - // corresponding ObjectOutputStream has written and flushed the - // header, so it is important that the ObjectOutputStreams on server - // and client are opened before the ObjectInputStreams. - ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); - ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); - oos.writeObject(id); - oos.writeObject(SjavacServer.CMD_COMPILE); - oos.writeObject(args); - oos.flush(); - result = (CompilationResult) ois.readObject(); - } catch (IOException | ClassNotFoundException ex) { - Log.error("[CLIENT] Exception caught: " + ex); - result = new CompilationResult(CompilationSubResult.ERROR_FATAL); - result.stderr = Util.getStackTrace(ex); + PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + // Send args array to server + out.println(args.length); + for (String arg : args) + out.println(arg); + out.flush(); + + // Read server response line by line + String line; + while (null != (line = in.readLine())) { + String[] typeAndContent = line.split(":", 2); + String type = typeAndContent[0]; + String content = typeAndContent[1]; + switch (type) { + case SjavacServer.LINE_TYPE_STDOUT: + stdout.write(content); + stdout.write('\n'); + break; + case SjavacServer.LINE_TYPE_STDERR: + stderr.write(content); + stderr.write('\n'); + break; + case SjavacServer.LINE_TYPE_RC: + result = Integer.parseInt(content); + break; + } + } + } catch (IOException ioe) { + Log.error("[CLIENT] Exception caught: " + ioe); + result = CompilationSubResult.ERROR_FATAL; + ioe.printStackTrace(new PrintWriter(stderr)); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // Restore interrupt Log.error("[CLIENT] compile interrupted."); - result = new CompilationResult(CompilationSubResult.ERROR_FATAL); - result.stderr = Util.getStackTrace(ie); + result = CompilationSubResult.ERROR_FATAL; + ie.printStackTrace(new PrintWriter(stderr)); } return result; } diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java Fri Sep 11 13:01:23 2015 -0700 @@ -24,13 +24,13 @@ */ package com.sun.tools.sjavac.comp; +import java.io.Writer; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import com.sun.tools.sjavac.Log; -import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.Sjavac; /** @@ -54,10 +54,10 @@ } @Override - public CompilationResult compile(String[] args) { + public int compile(String[] args, Writer out, Writer err) { try { return pool.submit(() -> { - return delegate.compile(args); + return delegate.compile(args, out, err); }).get(); } catch (Exception e) { e.printStackTrace(); diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Fri Sep 11 13:01:23 2015 -0700 @@ -24,12 +24,9 @@ */ package com.sun.tools.sjavac.comp; -import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL; -import static java.nio.charset.StandardCharsets.UTF_8; - -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -49,7 +46,6 @@ import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.SourceLocation; -import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.Sjavac; /** @@ -64,39 +60,33 @@ public class SjavacImpl implements Sjavac { @Override - public CompilationResult compile(String[] args) { - - ByteArrayOutputStream outBaos = new ByteArrayOutputStream(); - ByteArrayOutputStream errBaos = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(outBaos); - PrintStream err = new PrintStream(errBaos); - + public int compile(String[] args, Writer out, Writer err) { Options options; try { options = Options.parseArgs(args); } catch (IllegalArgumentException e) { Log.error(e.getMessage()); - return new CompilationResult(ERROR_FATAL); + return RC_FATAL; } Log.setLogLevel(options.getLogLevel()); if (!validateOptions(options)) - return new CompilationResult(ERROR_FATAL); + return RC_FATAL; if (!createIfMissing(options.getDestDir())) - return new CompilationResult(ERROR_FATAL); + return RC_FATAL; if (!createIfMissing(options.getStateDir())) - return new CompilationResult(ERROR_FATAL); + return RC_FATAL; Path gensrc = options.getGenSrcDir(); if (gensrc != null && !createIfMissing(gensrc)) - return new CompilationResult(ERROR_FATAL); + return RC_FATAL; Path hdrdir = options.getHeaderDir(); if (hdrdir != null && !createIfMissing(hdrdir)) - return new CompilationResult(ERROR_FATAL); + return RC_FATAL; // Load the prev build state database. JavacState javac_state = JavacState.load(options, out, err); @@ -132,9 +122,7 @@ if (sources.isEmpty()) { Log.error("Found nothing to compile!"); - return new CompilationResult(CompilationResult.ERROR_FATAL, - new String(outBaos.toByteArray(), UTF_8), - new String(errBaos.toByteArray(), UTF_8)); + return RC_FATAL; } @@ -251,19 +239,13 @@ javac_state.removeSuperfluousArtifacts(recently_compiled); } - return new CompilationResult(rc[0] ? 0 : ERROR_FATAL, - new String(outBaos.toByteArray(), UTF_8), - new String(errBaos.toByteArray(), UTF_8)); + return rc[0] ? RC_OK : RC_FATAL; } catch (ProblemException e) { Log.error(e.getMessage()); - return new CompilationResult(ERROR_FATAL, - new String(outBaos.toByteArray(), UTF_8), - new String(errBaos.toByteArray(), UTF_8)); + return RC_FATAL; } catch (Exception e) { - e.printStackTrace(err); - return new CompilationResult(ERROR_FATAL, - new String(outBaos.toByteArray(), UTF_8), - new String(errBaos.toByteArray(), UTF_8)); + e.printStackTrace(new PrintWriter(err)); + return RC_FATAL; } } diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java Fri Sep 11 10:26:41 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.sjavac.server; - -import java.io.Serializable; - -/** - *

This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. - */ -public class CompilationResult implements Serializable { - - static final long serialVersionUID = 46739181113L; - - // Return code constants - public final static int ERROR_FATAL = -1; - - public String stdout; - public String stderr; - public int returnCode; - - public CompilationResult(int returnCode) { - this(returnCode, "", ""); - } - - public CompilationResult(int returnCode, String stdout, String stderr) { - this.returnCode = returnCode; - this.stdout = stdout; - this.stderr = stderr; - } - - public void setReturnCode(int returnCode) { - this.returnCode = returnCode; - } -} diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java Fri Sep 11 13:01:23 2015 -0700 @@ -24,6 +24,7 @@ */ package com.sun.tools.sjavac.server; +import java.io.Writer; import java.util.Timer; import java.util.TimerTask; @@ -60,10 +61,10 @@ } @Override - public CompilationResult compile(String[] args) { + public int compile(String[] args, Writer out, Writer err) { startCall(); try { - return delegate.compile(args); + return delegate.compile(args, out, err); } finally { endCall(); } diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/LinePrefixFilterWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/LinePrefixFilterWriter.java Fri Sep 11 13:01:23 2015 -0700 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac.server; + +import java.io.FilterWriter; +import java.io.IOException; +import java.io.Writer; + +/** + * Inserts {@literal prefix} in front of each line written. + * + * A line is considered to be terminated by any one of a line feed, a carriage + * return, or a carriage return followed immediately by a line feed. + */ +public class LinePrefixFilterWriter extends FilterWriter { + + private final String prefix; + private boolean atBeginningOfLine = true; + private char lastChar = '\0'; + + protected LinePrefixFilterWriter(Writer out, String prefix) { + super(out); + this.prefix = prefix; + } + + @Override + public void write(String str, int off, int len) throws IOException { + for (int i = 0; i < len; i++) { + write(str.charAt(off + i)); + } + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + for (int i = 0; i < len; i++) { + write(cbuf[off + i]); + } + } + + @Override + public void write(int c) throws IOException { + if (lastChar == '\r' && c == '\n') { + // Second character of CR+LF sequence. + // Do nothing. We already started a new line on last character. + } else { + if (atBeginningOfLine) { + super.write(prefix, 0, prefix.length()); + } + super.write(c); + atBeginningOfLine = c == '\r' || c == '\n'; + } + lastChar = (char) c; + } +} diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java Fri Sep 11 13:01:23 2015 -0700 @@ -24,15 +24,21 @@ */ package com.sun.tools.sjavac.server; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import static com.sun.tools.sjavac.server.SjavacServer.LINE_TYPE_RC; +import static com.sun.tools.sjavac.server.SjavacServer.LINE_TYPE_STDERR; +import static com.sun.tools.sjavac.server.SjavacServer.LINE_TYPE_STDOUT; + +import java.io.BufferedReader; +import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; +import java.io.Writer; import java.net.Socket; +import com.sun.tools.sjavac.AutoFlushWriter; import com.sun.tools.sjavac.Log; + /** * A RequestHandler handles requests performed over a socket. Specifically it * - Reads the command string specifying which method is to be invoked @@ -61,15 +67,26 @@ @Override public void run() { - try (ObjectOutputStream oout = new ObjectOutputStream(socket.getOutputStream()); - ObjectInputStream oin = new ObjectInputStream(socket.getInputStream())) { - String id = (String) oin.readObject(); - String cmd = (String) oin.readObject(); - Log.info("Handling request, id: " + id + " cmd: " + cmd); - switch (cmd) { - case SjavacServer.CMD_COMPILE: handleCompileRequest(oin, oout); break; - default: Log.error("Unknown command: " + cmd); + try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { + + // Read argument array + int n = Integer.parseInt(in.readLine()); + String[] args = new String[n]; + for (int i = 0; i < n; i++) { + args[i] = in.readLine(); } + + // Perform compilation + Writer stdout = new LinePrefixFilterWriter(new AutoFlushWriter(out), LINE_TYPE_STDOUT + ":"); + Writer stderr = new LinePrefixFilterWriter(new AutoFlushWriter(out), LINE_TYPE_STDERR + ":"); + int rc = sjavac.compile(args, stdout, stderr); + stdout.flush(); + stderr.flush(); + + // Send return code back to client + out.println(LINE_TYPE_RC + ":" + rc); + } catch (Exception ex) { // Not much to be done at this point. The client side request // code will most likely throw an IOException and the @@ -79,21 +96,4 @@ Log.error(sw.toString()); } } - - private void handleCompileRequest(ObjectInputStream oin, - ObjectOutputStream oout) throws IOException { - try { - // Read request arguments - String[] args = (String[]) oin.readObject(); - - // Perform compilation - CompilationResult cr = sjavac.compile(args); - - // Write request response - oout.writeObject(cr); - oout.flush(); - } catch (ClassNotFoundException cnfe) { - throw new IOException(cnfe); - } - } } diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java Fri Sep 11 13:01:23 2015 -0700 @@ -26,6 +26,7 @@ package com.sun.tools.sjavac.server; import java.io.IOException; +import java.io.OutputStreamWriter; import com.sun.tools.sjavac.Log; @@ -38,7 +39,8 @@ public class ServerMain { public static int run(String[] args) { - Log.initializeLog(System.out, System.err); + Log.initializeLog(new OutputStreamWriter(System.out), + new OutputStreamWriter(System.err)); // Any options other than --startserver? if (args.length > 1) { diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java Fri Sep 11 13:01:23 2015 -0700 @@ -24,6 +24,8 @@ */ package com.sun.tools.sjavac.server; +import java.io.Writer; + /** * Interface of the SjavacImpl, the sjavac client and all wrappers such as @@ -35,6 +37,10 @@ * deletion without notice. */ public interface Sjavac { - CompilationResult compile(String[] args); + + final static int RC_FATAL = -1; + final static int RC_OK = 0; + + int compile(String[] args, Writer stdout, Writer stderr); void shutdown(); } diff -r e20c281d7818 -r 618ea3c86a0d langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Fri Sep 11 13:01:23 2015 -0700 @@ -53,8 +53,10 @@ */ public class SjavacServer implements Terminable { - // Used in protocol to indicate which method to invoke - public final static String CMD_COMPILE = "compile"; + // Used in protocol to tell the content of each line + public final static String LINE_TYPE_RC = "RC"; + public final static String LINE_TYPE_STDOUT = "STDOUT"; + public final static String LINE_TYPE_STDERR = "STDERR"; final private String portfilename; final private String logfile; diff -r e20c281d7818 -r 618ea3c86a0d langtools/test/tools/javac/lib/combo/ReusableContext.java --- a/langtools/test/tools/javac/lib/combo/ReusableContext.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/test/tools/javac/lib/combo/ReusableContext.java Fri Sep 11 13:01:23 2015 -0700 @@ -31,8 +31,12 @@ import com.sun.source.util.TaskListener; import com.sun.source.util.TreeScanner; import com.sun.tools.javac.api.MultiTaskListener; +import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Type.ClassType; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.CompileStates; @@ -93,23 +97,46 @@ //find if any of the roots have redefined java.* classes Symtab syms = Symtab.instance(this); - new TreeScanner() { - @Override - public Void visitClass(ClassTree node, Void aVoid) { - Symbol sym = ((JCClassDecl)node).sym; - if (sym != null) { - syms.classes.remove(sym.flatName()); - if (sym.flatName().toString().startsWith("java.")) { - polluted = true; - } - } - return super.visitClass(node, aVoid); - } - }.scan(roots, null); + pollutionScanner.scan(roots, syms); roots.clear(); } } + /** + * This scanner detects as to whether the shared context has been polluted. This happens + * whenever a compiled program redefines a core class (in 'java.*' package) or when + * (typically because of cyclic inheritance) the symbol kind of a core class has been touched. + */ + TreeScanner pollutionScanner = new TreeScanner() { + @Override + public Void visitClass(ClassTree node, Symtab syms) { + Symbol sym = ((JCClassDecl)node).sym; + if (sym != null) { + syms.classes.remove(sym.flatName()); + Type sup = supertype(sym); + if (isCoreClass(sym) || + (sup != null && isCoreClass(sup.tsym) && sup.tsym.kind != Kinds.Kind.TYP)) { + polluted = true; + } + } + return super.visitClass(node, syms); + } + + private boolean isCoreClass(Symbol s) { + return s.flatName().toString().startsWith("java."); + } + + private Type supertype(Symbol s) { + if (s.type == null || + !s.type.hasTag(TypeTag.CLASS)) { + return null; + } else { + ClassType ct = (ClassType)s.type; + return ct.supertype_field; + } + } + }; + @Override public void finished(TaskEvent e) { if (e.getKind() == Kind.PARSE) { diff -r e20c281d7818 -r 618ea3c86a0d langtools/test/tools/javac/sym/ElementStructureTest.java --- a/langtools/test/tools/javac/sym/ElementStructureTest.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/test/tools/javac/sym/ElementStructureTest.java Fri Sep 11 13:01:23 2015 -0700 @@ -56,6 +56,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.ServiceLoader; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -76,6 +77,7 @@ import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import javax.tools.FileObject; +import javax.tools.JavaCompiler; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; @@ -88,7 +90,6 @@ import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.platform.PlatformProvider; -import com.sun.tools.javac.util.ServiceLoader; /**To generate the hash values for version N, invoke this class like: * @@ -243,7 +244,11 @@ } void run(Writer output, String version) throws Exception { - JavacTaskImpl task = (JavacTaskImpl) ToolProvider.getSystemJavaCompiler().getTask(null, null, null, Arrays.asList("-release", version), null, Arrays.asList(new ToolBox.JavaSource("Test", ""))); + List options = Arrays.asList("-release", version, "-classpath", ""); + List files = Arrays.asList(new ToolBox.JavaSource("Test", "")); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, options, null, files); + task.parse(); JavaFileManager fm = task.getContext().get(JavaFileManager.class); diff -r e20c281d7818 -r 618ea3c86a0d langtools/test/tools/sjavac/IdleShutdown.java --- a/langtools/test/tools/sjavac/IdleShutdown.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/test/tools/sjavac/IdleShutdown.java Fri Sep 11 13:01:23 2015 -0700 @@ -29,9 +29,9 @@ * @build Wrapper * @run main Wrapper IdleShutdown */ +import java.io.Writer; import java.util.concurrent.atomic.AtomicLong; -import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.IdleResetSjavac; import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Terminable; @@ -65,11 +65,11 @@ // Use Sjavac object and wait less than TIMEOUT_MS in between calls Thread.sleep(TIMEOUT_MS - 1000); log("Compiling"); - service.compile(new String[0]); + service.compile(new String[0], null, null); Thread.sleep(TIMEOUT_MS - 1000); log("Compiling"); - service.compile(new String[0]); + service.compile(new String[0], null, null); if (timeoutTimestamp.get() != -1) throw new AssertionError("Premature timeout detected."); @@ -103,13 +103,13 @@ public void shutdown() { } @Override - public CompilationResult compile(String[] args) { + public int compile(String[] args, Writer out, Writer err) { // Attempt to trigger idle timeout during a call by sleeping try { Thread.sleep(TIMEOUT_MS + 1000); } catch (InterruptedException e) { } - return null; + return 0; } } } diff -r e20c281d7818 -r 618ea3c86a0d langtools/test/tools/sjavac/PooledExecution.java --- a/langtools/test/tools/sjavac/PooledExecution.java Fri Sep 11 10:26:41 2015 -0700 +++ b/langtools/test/tools/sjavac/PooledExecution.java Fri Sep 11 13:01:23 2015 -0700 @@ -30,11 +30,11 @@ * @build Wrapper * @run main Wrapper PooledExecution */ +import java.io.Writer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import com.sun.tools.sjavac.comp.PooledSjavac; -import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.Sjavac; @@ -67,7 +67,7 @@ for (int i = 0; i < NUM_REQUESTS; i++) { tasks[i] = new Thread() { public void run() { - service.compile(new String[0]); + service.compile(new String[0], null, null); tasksFinished.incrementAndGet(); } }; @@ -109,7 +109,7 @@ AtomicInteger activeRequests = new AtomicInteger(0); @Override - public CompilationResult compile(String[] args) { + public int compile(String[] args, Writer out, Writer err) { leftToStart.countDown(); int numActiveRequests = activeRequests.incrementAndGet(); System.out.printf("Left to start: %2d / Currently active: %2d%n", @@ -123,7 +123,7 @@ } activeRequests.decrementAndGet(); System.out.println("Task completed"); - return null; + return 0; } @Override