8048318: Refactor sjavac as a thin client

Moved compilation logic from client to server.

Reviewed-by: jlahoda
This commit is contained in:
Andreas Lundblad 2015-08-25 15:14:41 +02:00
parent 062a960fd6
commit 3672dbcddf
22 changed files with 637 additions and 677 deletions

View file

@ -42,9 +42,9 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi; import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/** /**
* The clean properties transform should not be necessary. * The clean properties transform should not be necessary.
@ -64,7 +64,7 @@ public class CleanProperties implements Transformer {
// Any extra information is ignored for clean properties. // Any extra information is ignored for clean properties.
} }
public boolean transform(Sjavac sjavac, public boolean transform(CompilationService sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs, Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View file

@ -32,12 +32,13 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.Set; import java.util.Set;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi; import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.CompilationSubResult;
import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo; import com.sun.tools.sjavac.server.SysInfo;
/** /**
@ -68,7 +69,7 @@ public class CompileJavaPackages implements Transformer {
args = a; args = a;
} }
public boolean transform(final Sjavac sjavac, public boolean transform(final CompilationService sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
final Set<URI> visibleSources, final Set<URI> visibleSources,
final Map<URI,Set<String>> visibleClasses, final Map<URI,Set<String>> visibleClasses,
@ -91,16 +92,11 @@ public class CompileJavaPackages implements Transformer {
boolean concurrentCompiles = true; boolean concurrentCompiles = true;
// Fetch the id. // Fetch the id.
final String id = Util.extractStringOption("id", sjavac.serverSettings()); final String id = String.valueOf(new Random().nextInt());
// Only keep portfile and sjavac settings.. // Only keep portfile and sjavac settings..
//String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings()); //String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
// Get maximum heap size from the server!
SysInfo sysinfo = sjavac.getSysInfo(); SysInfo sysinfo = sjavac.getSysInfo();
if (sysinfo == null) {
Log.error("Could not query server for sysinfo!");
return false;
}
int numMBytes = (int)(sysinfo.maxMemory / ((long)(1024*1024))); int numMBytes = (int)(sysinfo.maxMemory / ((long)(1024*1024)));
Log.debug("Server reports "+numMBytes+"MiB of memory and "+sysinfo.numCores+" cores"); Log.debug("Server reports "+numMBytes+"MiB of memory and "+sysinfo.numCores+" cores");
@ -205,7 +201,7 @@ public class CompileJavaPackages implements Transformer {
} }
// The return values for each chunked compile. // The return values for each chunked compile.
final CompilationResult[] rn = new CompilationResult[numCompiles]; final CompilationSubResult[] rn = new CompilationSubResult[numCompiles];
// The requets, might or might not run as a background thread. // The requets, might or might not run as a background thread.
final Thread[] requests = new Thread[numCompiles]; final Thread[] requests = new Thread[numCompiles];

View file

@ -44,9 +44,9 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi; import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/** /**
* Compile properties transform a properties file into a Java source file. * Compile properties transform a properties file into a Java source file.
@ -71,7 +71,7 @@ public class CompileProperties implements Transformer {
public void setExtra(Options a) { public void setExtra(Options a) {
} }
public boolean transform(Sjavac sjavac, public boolean transform(CompilationService compilationService,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs, Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View file

@ -37,9 +37,9 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi; import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/** /**
* The copy file transform simply copies a matching file from -src to -d . * The copy file transform simply copies a matching file from -src to -d .
@ -58,7 +58,7 @@ public class CopyFile implements Transformer {
public void setExtra(Options a) { public void setExtra(Options a) {
} }
public boolean transform(Sjavac sjavac, public boolean transform(CompilationService compilationService,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs, Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View file

@ -45,9 +45,9 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi; import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/** /**
* The javac state class maintains the previous (prev) and the current (now) * The javac state class maintains the previous (prev) and the current (now)
@ -748,7 +748,7 @@ public class JavacState {
/** /**
* Compile all the java sources. Return true, if it needs to be called again! * Compile all the java sources. Return true, if it needs to be called again!
*/ */
public boolean performJavaCompilations(Sjavac sjavac, public boolean performJavaCompilations(CompilationService sjavac,
Options args, Options args,
Set<String> recentlyCompiled, Set<String> recentlyCompiled,
boolean[] rcValue) { boolean[] rcValue) {
@ -790,7 +790,7 @@ public class JavacState {
* For all packages, find all sources belonging to the package, group the sources * For all packages, find all sources belonging to the package, group the sources
* based on their transformers and apply the transformers on each source code group. * based on their transformers and apply the transformers on each source code group.
*/ */
private boolean perform(Sjavac sjavac, private boolean perform(CompilationService sjavac,
File outputDir, File outputDir,
Map<String,Transformer> suffixRules) { Map<String,Transformer> suffixRules) {
boolean rc = true; boolean rc = true;

View file

@ -30,9 +30,9 @@ import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi; import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/** /**
* The transform interface is used to transform content inside a package, from one form to another. * The transform interface is used to transform content inside a package, from one form to another.
@ -83,7 +83,7 @@ public interface Transformer {
* If num_cores is set to a non-zero value. The transform should attempt to use no more than these * If num_cores is set to a non-zero value. The transform should attempt to use no more than these
* number of threads for heavy work. * number of threads for heavy work.
*/ */
boolean transform(Sjavac sjavac, boolean transform(CompilationService sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSources, Set<URI> visibleSources,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View file

@ -25,29 +25,13 @@
package com.sun.tools.sjavac.client; package com.sun.tools.sjavac.client;
import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.JavacState;
import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Module;
import com.sun.tools.sjavac.ProblemException;
import com.sun.tools.sjavac.Source;
import com.sun.tools.sjavac.Transformer;
import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.comp.PooledSjavac;
import com.sun.tools.sjavac.comp.SjavacImpl; import com.sun.tools.sjavac.comp.SjavacImpl;
import com.sun.tools.sjavac.options.Options; 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; import com.sun.tools.sjavac.server.Sjavac;
/** /**
@ -74,282 +58,34 @@ public class ClientMain {
return -1; return -1;
} }
Log.setLogLevel(options.getLogLevel());
if (!validateOptions(options))
return -1;
if (!createIfMissing(options.getDestDir()))
return -1;
if (!createIfMissing(options.getStateDir()))
return -1;
Path gensrc = options.getGenSrcDir();
if (gensrc != null && !createIfMissing(gensrc))
return -1;
Path hdrdir = options.getHeaderDir();
if (hdrdir != null && !createIfMissing(hdrdir))
return -1;
Log.debug("=========================================================="); Log.debug("==========================================================");
Log.debug("Launching sjavac client with the following parameters:"); Log.debug("Launching sjavac client with the following parameters:");
Log.debug(" " + options.getStateArgsString()); Log.debug(" " + options.getStateArgsString());
Log.debug("=========================================================="); Log.debug("==========================================================");
// Load the prev build state database. // Prepare sjavac object
JavacState javac_state = JavacState.load(options, out, err); boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
Sjavac sjavac;
// Setup the suffix rules from the command line. // Create an sjavac implementation to be used for compilation
Map<String, Transformer> suffixRules = new HashMap<>(); if (background) {
try {
// Handling of .java-compilation
suffixRules.putAll(javac_state.getJavaSuffixRule());
// Handling of -copy and -tr
suffixRules.putAll(options.getTranslationRules());
// All found modules are put here.
Map<String,Module> modules = new HashMap<>();
// We start out in the legacy empty no-name module.
// As soon as we stumble on a module-info.java file we change to that module.
Module current_module = new Module("", "");
modules.put("", current_module);
// Find all sources, use the suffix rules to know which files are sources.
Map<String,Source> sources = new HashMap<>();
// Find the files, this will automatically populate the found modules
// with found packages where the sources are found!
findSourceFiles(options.getSources(),
suffixRules.keySet(),
sources,
modules,
current_module,
options.isDefaultPackagePermitted(),
false);
if (sources.isEmpty()) {
Log.error("Found nothing to compile!");
return -1;
}
// Create a map of all source files that are available for linking. Both -src and
// -sourcepath point to such files. It is possible to specify multiple
// -sourcepath options to enable different filtering rules. If the
// filters are the same for multiple sourcepaths, they may be concatenated
// using :(;). Before sending the list of sourcepaths to javac, they are
// all concatenated. The list created here is used by the SmartFileWrapper to
// make sure only the correct sources are actually available.
// We might find more modules here as well.
Map<String,Source> sources_to_link_to = new HashMap<>();
List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
sourceResolutionLocations.addAll(options.getSources());
sourceResolutionLocations.addAll(options.getSourceSearchPaths());
findSourceFiles(sourceResolutionLocations,
Collections.singleton(".java"),
sources_to_link_to,
modules,
current_module,
options.isDefaultPackagePermitted(),
true);
// Find all class files allowable for linking.
// And pickup knowledge of all modules found here.
// This cannot currently filter classes inside jar files.
// Map<String,Source> classes_to_link_to = new HashMap<String,Source>();
// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true);
// Find all module sources allowable for linking.
// Map<String,Source> modules_to_link_to = new HashMap<String,Source>();
// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true);
// Add the set of sources to the build database.
javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
javac_state.now().checkInternalState("checking sources", false, sources);
javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
javac_state.setVisibleSources(sources_to_link_to);
int round = 0;
printRound(round);
// If there is any change in the source files, taint packages
// and mark the database in need of saving.
javac_state.checkSourceStatus(false);
// Find all existing artifacts. Their timestamp will match the last modified timestamps stored
// in javac_state, simply because loading of the JavacState will clean out all artifacts
// that do not match the javac_state database.
javac_state.findAllArtifacts();
// Remove unidentified artifacts from the bin, gensrc and header dirs.
// (Unless we allow them to be there.)
// I.e. artifacts that are not known according to the build database (javac_state).
// For examples, files that have been manually copied into these dirs.
// Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
// in javac_state) have already been removed when the javac_state was loaded.
if (!options.areUnidentifiedArtifactsPermitted()) {
javac_state.removeUnidentifiedArtifacts();
}
// Go through all sources and taint all packages that miss artifacts.
javac_state.taintPackagesThatMissArtifacts();
// Check recorded classpath public apis. Taint packages that depend on
// classpath classes whose public apis have changed.
javac_state.taintPackagesDependingOnChangedClasspathPackages();
// Now clean out all known artifacts belonging to tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
// Copy files, for example property files, images files, xml files etc etc.
javac_state.performCopying(Util.pathToFile(options.getDestDir()), suffixRules);
// Translate files, for example compile properties or compile idls.
javac_state.performTranslation(Util.pathToFile(gensrc), suffixRules);
// Add any potentially generated java sources to the tobe compiled list.
// (Generated sources must always have a package.)
Map<String,Source> generated_sources = new HashMap<>();
try {
Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null,
generated_sources, modules, current_module, false, true, false);
javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
// Recheck the the source files and their timestamps again.
javac_state.checkSourceStatus(true);
// Now do a safety check that the list of source files is identical
// to the list Make believes we are compiling. If we do not get this
// right, then incremental builds will fail with subtility.
// If any difference is detected, then we will fail hard here.
// This is an important safety net.
javac_state.compareWithMakefileList(Util.pathToFile(options.getSourceReferenceList()));
// Do the compilations, repeatedly until no tainted packages exist.
boolean again;
// Collect the name of all compiled packages.
Set<String> recently_compiled = new HashSet<>();
boolean[] rc = new boolean[1];
boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
Sjavac sjavac;
// Create an sjavac implementation to be used for compilation
if (background) {
sjavac = new SjavacClient(options); sjavac = new SjavacClient(options);
} else { } catch (PortFileInaccessibleException e) {
int poolsize = Util.extractIntOption("poolsize", options.getServerConf()); Log.error("Port file inaccessible.");
if (poolsize <= 0) return -1;
poolsize = Runtime.getRuntime().availableProcessors();
sjavac = new PooledSjavac(new SjavacImpl(), poolsize);
} }
} else {
do { sjavac = new SjavacImpl();
if (round > 0)
printRound(round);
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc);
if (!rc[0]) {
Log.debug("Compilation failed.");
break;
}
if (!again) {
Log.debug("Nothing left to do.");
}
round++;
} while (again);
Log.debug("No need to do another round.");
// Only update the state if the compile went well.
if (rc[0]) {
javac_state.save();
// Reflatten only the artifacts.
javac_state.now().flattenArtifacts(modules);
// Remove artifacts that were generated during the last compile, but not this one.
javac_state.removeSuperfluousArtifacts(recently_compiled);
}
if (!background)
sjavac.shutdown();
return rc[0] ? 0 : -1;
} catch (ProblemException e) {
Log.error(e.getMessage());
return -1;
} catch (Exception e) {
e.printStackTrace(err);
return -1;
}
}
private static boolean validateOptions(Options options) {
String err = null;
if (options.getDestDir() == null) {
err = "Please specify output directory.";
} else if (options.isJavaFilesAmongJavacArgs()) {
err = "Sjavac does not handle explicit compilation of single .java files.";
} else if (options.getServerConf() == null) {
err = "No server configuration provided.";
} else if (!options.getImplicitPolicy().equals("none")) {
err = "The only allowed setting for sjavac is -implicit:none";
} else if (options.getSources().isEmpty()) {
err = "You have to specify -src.";
} else if (options.getTranslationRules().size() > 1
&& options.getGenSrcDir() == null) {
err = "You have translators but no gensrc dir (-s) specified!";
} }
if (err != null) CompilationResult cr = sjavac.compile(args);
Log.error(err);
return err == null; out.print(cr.stdout);
err.print(cr.stderr);
if (!background)
sjavac.shutdown();
return cr.returnCode;
} }
private static boolean createIfMissing(Path dir) {
if (Files.isDirectory(dir))
return true;
if (Files.exists(dir)) {
Log.error(dir + " is not a directory.");
return false;
}
try {
Files.createDirectories(dir);
} catch (IOException e) {
Log.error("Could not create directory: " + e.getMessage());
return false;
}
return true;
}
/** Find source files in the given source locations. */
public static void findSourceFiles(List<SourceLocation> sourceLocations,
Set<String> sourceTypes,
Map<String,Source> foundFiles,
Map<String, Module> foundModules,
Module currentModule,
boolean permitSourcesInDefaultPackage,
boolean inLinksrc) {
for (SourceLocation source : sourceLocations) {
source.findSourceFiles(sourceTypes,
foundFiles,
foundModules,
currentModule,
permitSourcesInDefaultPackage,
inLinksrc);
}
}
private static void printRound(int round) {
Log.debug("****************************************");
Log.debug("* Round " + round + " *");
Log.debug("****************************************");
}
} }

View file

@ -0,0 +1,36 @@
/*
* 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.client;
import java.io.IOException;
public class PortFileInaccessibleException extends IOException {
private static final long serialVersionUID = -4755261881545398973L;
public PortFileInaccessibleException(Throwable cause) {
super(cause);
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,32 +26,27 @@
package com.sun.tools.sjavac.client; package com.sun.tools.sjavac.client;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
import java.util.Set;
import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.options.OptionHelper; import com.sun.tools.sjavac.options.OptionHelper;
import com.sun.tools.sjavac.options.Options; 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.CompilationResult;
import com.sun.tools.sjavac.server.PortFile; import com.sun.tools.sjavac.server.PortFile;
import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SjavacServer; import com.sun.tools.sjavac.server.SjavacServer;
import com.sun.tools.sjavac.server.SysInfo;
/** /**
* Sjavac implementation that delegates requests to a SjavacServer. * Sjavac implementation that delegates requests to a SjavacServer.
@ -89,9 +84,7 @@ public class SjavacClient implements Sjavac {
// Store the server conf settings here. // Store the server conf settings here.
private final String settings; private final String settings;
// This constructor should not throw FileNotFoundException (to be resolved public SjavacClient(Options options) throws PortFileInaccessibleException {
// in JDK-8060030)
public SjavacClient(Options options) throws FileNotFoundException {
String tmpServerConf = options.getServerConf(); String tmpServerConf = options.getServerConf();
String serverConf = (tmpServerConf!=null)? tmpServerConf : ""; String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
String tmpId = Util.extractStringOption("id", serverConf); String tmpId = Util.extractStringOption("id", serverConf);
@ -103,8 +96,7 @@ public class SjavacClient implements Sjavac {
String portfileName = Util.extractStringOption("portfile", serverConf, defaultPortfile); String portfileName = Util.extractStringOption("portfile", serverConf, defaultPortfile);
try { try {
portFile = SjavacServer.getPortFile(portfileName); portFile = SjavacServer.getPortFile(portfileName);
} catch (FileNotFoundException e) { } catch (PortFileInaccessibleException e) {
// Reached for instance if directory of port file does not exist
Log.error("Port file inaccessable: " + e); Log.error("Port file inaccessable: " + e);
throw e; throw e;
} }
@ -126,40 +118,8 @@ public class SjavacClient implements Sjavac {
return settings; return settings;
} }
/**
* Make a request to the server only to get the maximum possible heap size to use for compilations.
*/
@Override @Override
public SysInfo getSysInfo() { public CompilationResult compile(String[] args) {
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_SYS_INFO);
oos.flush();
return (SysInfo) ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
Log.error("[CLIENT] Exception caught: " + ex);
Log.debug(Util.getStackTrace(ex));
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // Restore interrupt
Log.error("[CLIENT] getSysInfo interrupted.");
Log.debug(Util.getStackTrace(ie));
}
return null;
}
@Override
public CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
CompilationResult result; CompilationResult result;
try (Socket socket = tryConnect()) { try (Socket socket = tryConnect()) {
// The ObjectInputStream constructor will block until the // The ObjectInputStream constructor will block until the
@ -170,22 +130,17 @@ public class SjavacClient implements Sjavac {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
oos.writeObject(id); oos.writeObject(id);
oos.writeObject(SjavacServer.CMD_COMPILE); oos.writeObject(SjavacServer.CMD_COMPILE);
oos.writeObject(protocolId);
oos.writeObject(invocationId);
oos.writeObject(args); oos.writeObject(args);
oos.writeObject(explicitSources);
oos.writeObject(sourcesToCompile);
oos.writeObject(visibleSources);
oos.flush(); oos.flush();
result = (CompilationResult) ois.readObject(); result = (CompilationResult) ois.readObject();
} catch (IOException | ClassNotFoundException ex) { } catch (IOException | ClassNotFoundException ex) {
Log.error("[CLIENT] Exception caught: " + ex); Log.error("[CLIENT] Exception caught: " + ex);
result = new CompilationResult(CompilationResult.ERROR_FATAL); result = new CompilationResult(CompilationSubResult.ERROR_FATAL);
result.stderr = Util.getStackTrace(ex); result.stderr = Util.getStackTrace(ex);
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // Restore interrupt Thread.currentThread().interrupt(); // Restore interrupt
Log.error("[CLIENT] compile interrupted."); Log.error("[CLIENT] compile interrupted.");
result = new CompilationResult(CompilationResult.ERROR_FATAL); result = new CompilationResult(CompilationSubResult.ERROR_FATAL);
result.stderr = Util.getStackTrace(ie); result.stderr = Util.getStackTrace(ie);
} }
return result; return result;

View file

@ -0,0 +1,171 @@
/*
* 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.comp;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Dependencies;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.comp.dependencies.NewDependencyCollector;
import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector;
import com.sun.tools.sjavac.server.CompilationSubResult;
import com.sun.tools.sjavac.server.SysInfo;
/**
* <p><b>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.</b>
*/
public class CompilationService {
public SysInfo getSysInfo() {
return new SysInfo(Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().maxMemory());
}
public CompilationSubResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
SmartFileManager sfm = new SmartFileManager(fm);
Context context = new Context();
Dependencies.GraphDependencies.preRegister(context);
// Now setup the actual compilation
CompilationSubResult compilationResult = new CompilationSubResult(0);
// First deal with explicit source files on cmdline and in at file
ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>();
for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(explicitSources)) {
explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
}
// Now deal with sources supplied as source_to_compile
ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
for (URI u : sourcesToCompile)
sourcesToCompileFiles.append(new File(u));
for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles))
explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
// Create a new logger
StringWriter stdoutLog = new StringWriter();
StringWriter stderrLog = new StringWriter();
PrintWriter stdout = new PrintWriter(stdoutLog);
PrintWriter stderr = new PrintWriter(stderrLog);
com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs);
PathAndPackageVerifier papVerifier = new PathAndPackageVerifier();
NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs);
try {
if (explicitJFOs.size() > 0) {
sfm.setVisibleSources(visibleSources);
sfm.cleanArtifacts();
sfm.setLog(stdout);
// Do the compilation!
JavacTaskImpl task =
(JavacTaskImpl) compiler.getTask(stderr,
sfm,
null,
Arrays.asList(args),
null,
explicitJFOs,
context);
sfm.setSymbolFileEnabled(!com.sun.tools.javac.util.Options.instance(context).isSet("ignore.symbol.file"));
task.addTaskListener(depsCollector);
task.addTaskListener(pubApiCollector);
task.addTaskListener(papVerifier);
logJavacInvocation(args);
rc = task.doCall();
Log.debug("javac returned with code " + rc);
sfm.flush();
}
} catch (Exception e) {
Log.error(Util.getStackTrace(e));
stderrLog.append(Util.getStackTrace(e));
rc = com.sun.tools.javac.main.Main.Result.ERROR;
}
compilationResult.packageArtifacts = sfm.getPackageArtifacts();
if (papVerifier.errorsDiscovered())
rc = com.sun.tools.javac.main.Main.Result.ERROR;
compilationResult.packageDependencies = depsCollector.getDependencies(false);
compilationResult.packageCpDependencies = depsCollector.getDependencies(true);
compilationResult.packagePubapis = pubApiCollector.getPubApis(true);
compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false);
compilationResult.stdout = stdoutLog.toString();
compilationResult.stderr = stderrLog.toString();
compilationResult.returnCode = rc.exitCode;
return compilationResult;
} catch (IOException e) {
throw new Error(e);
}
}
private void logJavacInvocation(String[] args) {
Log.debug("Invoking javac with args");
Iterator<String> argIter = Arrays.asList(args).iterator();
while (argIter.hasNext()) {
String arg = argIter.next();
String line = " " + arg;
if (arg.matches("\\-(d|cp|classpath|sourcepath|source|target)")
&& argIter.hasNext()) {
line += " " + argIter.next();
}
Log.debug(line);
}
}
}

View file

@ -24,11 +24,7 @@
*/ */
package com.sun.tools.sjavac.comp; package com.sun.tools.sjavac.comp;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -36,7 +32,6 @@ import java.util.concurrent.TimeUnit;
import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
/** /**
* An sjavac implementation that limits the number of concurrent calls by * An sjavac implementation that limits the number of concurrent calls by
@ -59,30 +54,10 @@ public class PooledSjavac implements Sjavac {
} }
@Override @Override
public SysInfo getSysInfo() { public CompilationResult compile(String[] args) {
try {
return pool.submit(() -> delegate.getSysInfo()).get();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error during getSysInfo", e);
}
}
@Override
public CompilationResult compile(final String protocolId,
final String invocationId,
final String[] args,
final List<File> explicitSources,
final Set<URI> sourcesToCompile,
final Set<URI> visibleSources) {
try { try {
return pool.submit(() -> { return pool.submit(() -> {
return delegate.compile(protocolId, return delegate.compile(args);
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
}).get(); }).get();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -112,8 +87,4 @@ public class PooledSjavac implements Sjavac {
delegate.shutdown(); delegate.shutdown();
} }
@Override
public String serverSettings() {
return delegate.serverSettings();
}
} }

View file

@ -24,34 +24,33 @@
*/ */
package com.sun.tools.sjavac.comp; package com.sun.tools.sjavac.comp;
import java.io.File; 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.IOException;
import java.io.PrintWriter; import java.io.PrintStream;
import java.io.StringWriter; import java.nio.file.Files;
import java.net.URI; import java.nio.file.Path;
import java.util.Arrays; import java.util.ArrayList;
import java.util.Iterator; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.tools.JavaFileObject; import com.sun.tools.sjavac.JavacState;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Dependencies;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Options;
import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Module;
import com.sun.tools.sjavac.ProblemException;
import com.sun.tools.sjavac.Source;
import com.sun.tools.sjavac.Transformer;
import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.comp.dependencies.NewDependencyCollector; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector; import com.sun.tools.sjavac.options.SourceLocation;
import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
/** /**
* The sjavac implementation that interacts with javac and performs the actual * The sjavac implementation that interacts with javac and performs the actual
@ -65,123 +64,282 @@ import com.sun.tools.sjavac.server.SysInfo;
public class SjavacImpl implements Sjavac { public class SjavacImpl implements Sjavac {
@Override @Override
public SysInfo getSysInfo() { public CompilationResult compile(String[] args) {
return new SysInfo(Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().maxMemory());
}
@Override ByteArrayOutputStream outBaos = new ByteArrayOutputStream();
public CompilationResult compile(String protocolId, ByteArrayOutputStream errBaos = new ByteArrayOutputStream();
String invocationId, PrintStream out = new PrintStream(outBaos);
String[] args, PrintStream err = new PrintStream(errBaos);
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler(); Options options;
try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { try {
SmartFileManager sfm = new SmartFileManager(fm); options = Options.parseArgs(args);
Context context = new Context(); } catch (IllegalArgumentException e) {
Log.error(e.getMessage());
return new CompilationResult(ERROR_FATAL);
}
Dependencies.GraphDependencies.preRegister(context); Log.setLogLevel(options.getLogLevel());
// Now setup the actual compilation if (!validateOptions(options))
CompilationResult compilationResult = new CompilationResult(0); return new CompilationResult(ERROR_FATAL);
// First deal with explicit source files on cmdline and in at file if (!createIfMissing(options.getDestDir()))
ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>(); return new CompilationResult(ERROR_FATAL);
for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(explicitSources)) {
explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
}
// Now deal with sources supplied as source_to_compile
ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
for (URI u : sourcesToCompile)
sourcesToCompileFiles.append(new File(u));
for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) if (!createIfMissing(options.getStateDir()))
explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH)); return new CompilationResult(ERROR_FATAL);
// Create a new logger Path gensrc = options.getGenSrcDir();
StringWriter stdoutLog = new StringWriter(); if (gensrc != null && !createIfMissing(gensrc))
StringWriter stderrLog = new StringWriter(); return new CompilationResult(ERROR_FATAL);
PrintWriter stdout = new PrintWriter(stdoutLog);
PrintWriter stderr = new PrintWriter(stderrLog);
com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs);
PathAndPackageVerifier papVerifier = new PathAndPackageVerifier();
NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs);
try {
if (explicitJFOs.size() > 0) {
sfm.setVisibleSources(visibleSources);
sfm.cleanArtifacts();
sfm.setLog(stdout);
// Do the compilation! Path hdrdir = options.getHeaderDir();
JavacTaskImpl task = if (hdrdir != null && !createIfMissing(hdrdir))
(JavacTaskImpl) compiler.getTask(stderr, return new CompilationResult(ERROR_FATAL);
sfm,
null, // Load the prev build state database.
Arrays.asList(args), JavacState javac_state = JavacState.load(options, out, err);
null,
explicitJFOs, // Setup the suffix rules from the command line.
context); Map<String, Transformer> suffixRules = new HashMap<>();
sfm.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
task.addTaskListener(depsCollector); // Handling of .java-compilation
task.addTaskListener(pubApiCollector); suffixRules.putAll(javac_state.getJavaSuffixRule());
task.addTaskListener(papVerifier);
logJavacInvocation(args); // Handling of -copy and -tr
rc = task.doCall(); suffixRules.putAll(options.getTranslationRules());
Log.debug("javac returned with code " + rc);
sfm.flush(); // All found modules are put here.
Map<String,Module> modules = new HashMap<>();
// We start out in the legacy empty no-name module.
// As soon as we stumble on a module-info.java file we change to that module.
Module current_module = new Module("", "");
modules.put("", current_module);
// Find all sources, use the suffix rules to know which files are sources.
Map<String,Source> sources = new HashMap<>();
// Find the files, this will automatically populate the found modules
// with found packages where the sources are found!
findSourceFiles(options.getSources(),
suffixRules.keySet(),
sources,
modules,
current_module,
options.isDefaultPackagePermitted(),
false);
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));
}
// Create a map of all source files that are available for linking. Both -src and
// -sourcepath point to such files. It is possible to specify multiple
// -sourcepath options to enable different filtering rules. If the
// filters are the same for multiple sourcepaths, they may be concatenated
// using :(;). Before sending the list of sourcepaths to javac, they are
// all concatenated. The list created here is used by the SmartFileWrapper to
// make sure only the correct sources are actually available.
// We might find more modules here as well.
Map<String,Source> sources_to_link_to = new HashMap<>();
List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
sourceResolutionLocations.addAll(options.getSources());
sourceResolutionLocations.addAll(options.getSourceSearchPaths());
findSourceFiles(sourceResolutionLocations,
Collections.singleton(".java"),
sources_to_link_to,
modules,
current_module,
options.isDefaultPackagePermitted(),
true);
// Add the set of sources to the build database.
javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
javac_state.now().checkInternalState("checking sources", false, sources);
javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
javac_state.setVisibleSources(sources_to_link_to);
int round = 0;
printRound(round);
// If there is any change in the source files, taint packages
// and mark the database in need of saving.
javac_state.checkSourceStatus(false);
// Find all existing artifacts. Their timestamp will match the last modified timestamps stored
// in javac_state, simply because loading of the JavacState will clean out all artifacts
// that do not match the javac_state database.
javac_state.findAllArtifacts();
// Remove unidentified artifacts from the bin, gensrc and header dirs.
// (Unless we allow them to be there.)
// I.e. artifacts that are not known according to the build database (javac_state).
// For examples, files that have been manually copied into these dirs.
// Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
// in javac_state) have already been removed when the javac_state was loaded.
if (!options.areUnidentifiedArtifactsPermitted()) {
javac_state.removeUnidentifiedArtifacts();
}
// Go through all sources and taint all packages that miss artifacts.
javac_state.taintPackagesThatMissArtifacts();
// Check recorded classpath public apis. Taint packages that depend on
// classpath classes whose public apis have changed.
javac_state.taintPackagesDependingOnChangedClasspathPackages();
// Now clean out all known artifacts belonging to tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
// Copy files, for example property files, images files, xml files etc etc.
javac_state.performCopying(Util.pathToFile(options.getDestDir()), suffixRules);
// Translate files, for example compile properties or compile idls.
javac_state.performTranslation(Util.pathToFile(gensrc), suffixRules);
// Add any potentially generated java sources to the tobe compiled list.
// (Generated sources must always have a package.)
Map<String,Source> generated_sources = new HashMap<>();
try {
Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null,
generated_sources, modules, current_module, false, true, false);
javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
// Recheck the the source files and their timestamps again.
javac_state.checkSourceStatus(true);
// Now do a safety check that the list of source files is identical
// to the list Make believes we are compiling. If we do not get this
// right, then incremental builds will fail with subtility.
// If any difference is detected, then we will fail hard here.
// This is an important safety net.
javac_state.compareWithMakefileList(Util.pathToFile(options.getSourceReferenceList()));
// Do the compilations, repeatedly until no tainted packages exist.
boolean again;
// Collect the name of all compiled packages.
Set<String> recently_compiled = new HashSet<>();
boolean[] rc = new boolean[1];
CompilationService compilationService = new CompilationService();
do {
if (round > 0)
printRound(round);
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
again = javac_state.performJavaCompilations(compilationService, options, recently_compiled, rc);
if (!rc[0]) {
Log.debug("Compilation failed.");
break;
} }
} catch (Exception e) { if (!again) {
Log.error(Util.getStackTrace(e)); Log.debug("Nothing left to do.");
stderrLog.append(Util.getStackTrace(e)); }
rc = com.sun.tools.javac.main.Main.Result.ERROR; round++;
} while (again);
Log.debug("No need to do another round.");
// Only update the state if the compile went well.
if (rc[0]) {
javac_state.save();
// Reflatten only the artifacts.
javac_state.now().flattenArtifacts(modules);
// Remove artifacts that were generated during the last compile, but not this one.
javac_state.removeSuperfluousArtifacts(recently_compiled);
} }
compilationResult.packageArtifacts = sfm.getPackageArtifacts(); return new CompilationResult(rc[0] ? 0 : ERROR_FATAL,
new String(outBaos.toByteArray(), UTF_8),
if (papVerifier.errorsDiscovered()) new String(errBaos.toByteArray(), UTF_8));
rc = com.sun.tools.javac.main.Main.Result.ERROR; } catch (ProblemException e) {
Log.error(e.getMessage());
compilationResult.packageDependencies = depsCollector.getDependencies(false); return new CompilationResult(ERROR_FATAL,
compilationResult.packageCpDependencies = depsCollector.getDependencies(true); new String(outBaos.toByteArray(), UTF_8),
new String(errBaos.toByteArray(), UTF_8));
compilationResult.packagePubapis = pubApiCollector.getPubApis(true); // pubApis.getPubapis(explicitJFOs, true); } catch (Exception e) {
compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false); // pubApis.getPubapis(explicitJFOs, false); e.printStackTrace(err);
compilationResult.stdout = stdoutLog.toString(); return new CompilationResult(ERROR_FATAL,
compilationResult.stderr = stderrLog.toString(); new String(outBaos.toByteArray(), UTF_8),
compilationResult.returnCode = rc.exitCode; new String(errBaos.toByteArray(), UTF_8));
return compilationResult;
} catch (IOException e) {
throw new Error(e);
} }
} }
@Override @Override
public void shutdown() { public void shutdown() {
// Nothing to clean up // Nothing to clean up
// ... maybe we should wait for any current request to finish?
} }
@Override private static boolean validateOptions(Options options) {
public String serverSettings() {
return ""; String err = null;
if (options.getDestDir() == null) {
err = "Please specify output directory.";
} else if (options.isJavaFilesAmongJavacArgs()) {
err = "Sjavac does not handle explicit compilation of single .java files.";
} else if (options.getServerConf() == null) {
err = "No server configuration provided.";
} else if (!options.getImplicitPolicy().equals("none")) {
err = "The only allowed setting for sjavac is -implicit:none";
} else if (options.getSources().isEmpty()) {
err = "You have to specify -src.";
} else if (options.getTranslationRules().size() > 1
&& options.getGenSrcDir() == null) {
err = "You have translators but no gensrc dir (-s) specified!";
}
if (err != null)
Log.error(err);
return err == null;
} }
private void logJavacInvocation(String[] args) { private static boolean createIfMissing(Path dir) {
Log.debug("Invoking javac with args");
Iterator<String> argIter = Arrays.asList(args).iterator(); if (Files.isDirectory(dir))
while (argIter.hasNext()) { return true;
String arg = argIter.next();
String line = " " + arg; if (Files.exists(dir)) {
if (arg.matches("\\-(d|cp|classpath|sourcepath|source|target)") Log.error(dir + " is not a directory.");
&& argIter.hasNext()) { return false;
line += " " + argIter.next(); }
}
Log.debug(line); try {
Files.createDirectories(dir);
} catch (IOException e) {
Log.error("Could not create directory: " + e.getMessage());
return false;
}
return true;
}
/** Find source files in the given source locations. */
public static void findSourceFiles(List<SourceLocation> sourceLocations,
Set<String> sourceTypes,
Map<String,Source> foundFiles,
Map<String, Module> foundModules,
Module currentModule,
boolean permitSourcesInDefaultPackage,
boolean inLinksrc) {
for (SourceLocation source : sourceLocations) {
source.findSourceFiles(sourceTypes,
foundFiles,
foundModules,
currentModule,
permitSourcesInDefaultPackage,
inLinksrc);
} }
} }
private static void printRound(int round) {
Log.debug("****************************************");
Log.debug("* Round " + round + " *");
Log.debug("****************************************");
}
} }

View file

@ -26,15 +26,8 @@
package com.sun.tools.sjavac.server; package com.sun.tools.sjavac.server;
import java.io.Serializable; import java.io.Serializable;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.pubapi.PubApi;
/** /**
*
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk. * 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 * This code and its internal interfaces are subject to change or
@ -47,17 +40,18 @@ public class CompilationResult implements Serializable {
// Return code constants // Return code constants
public final static int ERROR_FATAL = -1; public final static int ERROR_FATAL = -1;
public String stdout;
public String stderr;
public int returnCode; public int returnCode;
public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageDependencies = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageCpDependencies = new HashMap<>();
public Map<String, PubApi> packagePubapis = new HashMap<>();
public Map<String, PubApi> dependencyPubapis = new HashMap<>();
public String stdout = "";
public String stderr = "";
public CompilationResult(int returnCode) { public CompilationResult(int returnCode) {
this(returnCode, "", "");
}
public CompilationResult(int returnCode, String stdout, String stderr) {
this.returnCode = returnCode; this.returnCode = returnCode;
this.stdout = stdout;
this.stderr = stderr;
} }
public void setReturnCode(int returnCode) { public void setReturnCode(int returnCode) {

View file

@ -0,0 +1,66 @@
/*
* 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;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
*
* <p><b>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.</b>
*/
public class CompilationSubResult implements Serializable {
static final long serialVersionUID = 46739181113L;
// Return code constants
public final static int ERROR_FATAL = -1;
public int returnCode;
public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageDependencies = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageCpDependencies = new HashMap<>();
public Map<String, PubApi> packagePubapis = new HashMap<>();
public Map<String, PubApi> dependencyPubapis = new HashMap<>();
public String stdout = "";
public String stderr = "";
public CompilationSubResult(int returnCode) {
this.returnCode = returnCode;
}
public void setReturnCode(int returnCode) {
this.returnCode = returnCode;
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,10 +24,6 @@
*/ */
package com.sun.tools.sjavac.server; package com.sun.tools.sjavac.server;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -64,30 +60,10 @@ public class IdleResetSjavac implements Sjavac {
} }
@Override @Override
public SysInfo getSysInfo() { public CompilationResult compile(String[] args) {
startCall(); startCall();
try { try {
return delegate.getSysInfo(); return delegate.compile(args);
} finally {
endCall();
}
}
@Override
public CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
startCall();
try {
return delegate.compile(protocolId,
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
} finally { } finally {
endCall(); endCall();
} }
@ -129,8 +105,4 @@ public class IdleResetSjavac implements Sjavac {
delegate.shutdown(); delegate.shutdown();
} }
@Override
public String serverSettings() {
return delegate.serverSettings();
}
} }

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,7 @@ import java.util.concurrent.Semaphore;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.client.PortFileInaccessibleException;
/** /**
* The PortFile class mediates access to a short binary file containing the tcp/ip port (for the localhost) * The PortFile class mediates access to a short binary file containing the tcp/ip port (for the localhost)
@ -80,11 +81,16 @@ public class PortFile {
* Create a new portfile. * Create a new portfile.
* @param fn is the path to the file. * @param fn is the path to the file.
*/ */
public PortFile(String fn) throws FileNotFoundException { public PortFile(String fn) throws PortFileInaccessibleException {
filename = fn; filename = fn;
file = new File(filename); file = new File(filename);
stopFile = new File(filename+".stop"); stopFile = new File(filename+".stop");
rwfile = new RandomAccessFile(file, "rw"); try {
rwfile = new RandomAccessFile(file, "rw");
} catch (FileNotFoundException e) {
// Reached if file for instance already exists and is a directory
throw new PortFileInaccessibleException(e);
}
// The rwfile should only be readable by the owner of the process // The rwfile should only be readable by the owner of the process
// and no other! How do we do that on a RandomAccessFile? // and no other! How do we do that on a RandomAccessFile?
channel = rwfile.getChannel(); channel = rwfile.getChannel();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,16 +24,12 @@
*/ */
package com.sun.tools.sjavac.server; package com.sun.tools.sjavac.server;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.Socket; import java.net.Socket;
import java.net.URI;
import java.util.List;
import java.util.Set;
import com.sun.tools.sjavac.Log; import com.sun.tools.sjavac.Log;
@ -71,8 +67,7 @@ public class RequestHandler implements Runnable {
String cmd = (String) oin.readObject(); String cmd = (String) oin.readObject();
Log.info("Handling request, id: " + id + " cmd: " + cmd); Log.info("Handling request, id: " + id + " cmd: " + cmd);
switch (cmd) { switch (cmd) {
case SjavacServer.CMD_SYS_INFO: handleSysInfoRequest(oin, oout); break; case SjavacServer.CMD_COMPILE: handleCompileRequest(oin, oout); break;
case SjavacServer.CMD_COMPILE: handleCompileRequest(oin, oout); break;
default: Log.error("Unknown command: " + cmd); default: Log.error("Unknown command: " + cmd);
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -85,31 +80,15 @@ public class RequestHandler implements Runnable {
} }
} }
private void handleSysInfoRequest(ObjectInputStream oin,
ObjectOutputStream oout) throws IOException {
oout.writeObject(sjavac.getSysInfo());
oout.flush();
}
@SuppressWarnings("unchecked")
private void handleCompileRequest(ObjectInputStream oin, private void handleCompileRequest(ObjectInputStream oin,
ObjectOutputStream oout) throws IOException { ObjectOutputStream oout) throws IOException {
try { try {
// Read request arguments // Read request arguments
String protocolId = (String) oin.readObject();
String invocationId = (String) oin.readObject();
String[] args = (String[]) oin.readObject(); String[] args = (String[]) oin.readObject();
List<File> explicitSources = (List<File>) oin.readObject();
Set<URI> sourcesToCompile = (Set<URI>) oin.readObject();
Set<URI> visibleSources = (Set<URI>) oin.readObject();
// Perform compilation // Perform compilation
CompilationResult cr = sjavac.compile(protocolId, CompilationResult cr = sjavac.compile(args);
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
// Write request response // Write request response
oout.writeObject(cr); oout.writeObject(cr);
oout.flush(); oout.flush();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,10 +24,6 @@
*/ */
package com.sun.tools.sjavac.server; package com.sun.tools.sjavac.server;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.Set;
/** /**
* Interface of the SjavacImpl, the sjavac client and all wrappers such as * Interface of the SjavacImpl, the sjavac client and all wrappers such as
@ -39,16 +35,6 @@ import java.util.Set;
* deletion without notice.</b> * deletion without notice.</b>
*/ */
public interface Sjavac { public interface Sjavac {
CompilationResult compile(String[] args);
SysInfo getSysInfo();
CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources);
void shutdown(); void shutdown();
String serverSettings();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,7 @@ import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.client.PortFileInaccessibleException;
import com.sun.tools.sjavac.comp.PooledSjavac; import com.sun.tools.sjavac.comp.PooledSjavac;
import com.sun.tools.sjavac.comp.SjavacImpl; import com.sun.tools.sjavac.comp.SjavacImpl;
@ -54,7 +55,6 @@ public class SjavacServer implements Terminable {
// Used in protocol to indicate which method to invoke // Used in protocol to indicate which method to invoke
public final static String CMD_COMPILE = "compile"; public final static String CMD_COMPILE = "compile";
public final static String CMD_SYS_INFO = "sys-info";
final private String portfilename; final private String portfilename;
final private String logfile; final private String logfile;
@ -122,7 +122,7 @@ public class SjavacServer implements Terminable {
/** /**
* Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time. * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
*/ */
public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException { public static synchronized PortFile getPortFile(String filename) throws PortFileInaccessibleException {
if (allPortFiles == null) { if (allPortFiles == null) {
allPortFiles = new HashMap<>(); allPortFiles = new HashMap<>();
} }

View file

@ -31,17 +31,11 @@
* @build Wrapper * @build Wrapper
* @run main Wrapper IdleShutdown * @run main Wrapper IdleShutdown
*/ */
import java.io.File;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.IdleResetSjavac; import com.sun.tools.sjavac.server.IdleResetSjavac;
import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
import com.sun.tools.sjavac.server.Terminable; import com.sun.tools.sjavac.server.Terminable;
@ -70,35 +64,14 @@ public class IdleShutdown {
if (timeoutTimestamp.get() != -1) if (timeoutTimestamp.get() != -1)
throw new AssertionError("Premature timeout detected."); throw new AssertionError("Premature timeout detected.");
// Call various methods and wait less than TIMEOUT_MS in between // Use Sjavac object and wait less than TIMEOUT_MS in between calls
Thread.sleep(TIMEOUT_MS - 1000); Thread.sleep(TIMEOUT_MS - 1000);
log("Getting sys info"); log("Compiling");
service.getSysInfo(); service.compile(new String[0]);
Thread.sleep(TIMEOUT_MS - 1000);
log("Getting sys info");
service.getSysInfo();
if (timeoutTimestamp.get() != -1)
throw new AssertionError("Premature timeout detected.");
Thread.sleep(TIMEOUT_MS - 1000); Thread.sleep(TIMEOUT_MS - 1000);
log("Compiling"); log("Compiling");
service.compile("", service.compile(new String[0]);
"",
new String[0],
Collections.<File>emptyList(),
Collections.<URI>emptySet(),
Collections.<URI>emptySet());
Thread.sleep(TIMEOUT_MS - 1000);
log("Compiling");
service.compile("",
"",
new String[0],
Collections.<File>emptyList(),
Collections.<URI>emptySet(),
Collections.<URI>emptySet());
if (timeoutTimestamp.get() != -1) if (timeoutTimestamp.get() != -1)
throw new AssertionError("Premature timeout detected."); throw new AssertionError("Premature timeout detected.");
@ -129,7 +102,10 @@ public class IdleShutdown {
private static class NoopJavacService implements Sjavac { private static class NoopJavacService implements Sjavac {
@Override @Override
public SysInfo getSysInfo() { public void shutdown() {
}
@Override
public CompilationResult compile(String[] args) {
// Attempt to trigger idle timeout during a call by sleeping // Attempt to trigger idle timeout during a call by sleeping
try { try {
Thread.sleep(TIMEOUT_MS + 1000); Thread.sleep(TIMEOUT_MS + 1000);
@ -137,21 +113,5 @@ public class IdleShutdown {
} }
return null; return null;
} }
@Override
public void shutdown() {
}
@Override
public CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
return null;
}
@Override
public String serverSettings() {
return "";
}
} }
} }

View file

@ -51,10 +51,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import com.sun.tools.sjavac.CopyFile; import com.sun.tools.sjavac.CopyFile;
import com.sun.tools.sjavac.Main;
import com.sun.tools.sjavac.Module; import com.sun.tools.sjavac.Module;
import com.sun.tools.sjavac.Source; import com.sun.tools.sjavac.Source;
import com.sun.tools.sjavac.client.ClientMain; import com.sun.tools.sjavac.client.ClientMain;
import com.sun.tools.sjavac.comp.SjavacImpl;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.options.SourceLocation; import com.sun.tools.sjavac.options.SourceLocation;
@ -136,7 +136,7 @@ public class OptionDecoding {
Options options = Options.parseArgs("-if", "root/pkg1/ClassA1.java", "root"); Options options = Options.parseArgs("-if", "root/pkg1/ClassA1.java", "root");
Map<String, Source> foundFiles = new HashMap<>(); Map<String, Source> foundFiles = new HashMap<>();
ClientMain.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
new HashMap<String, Module>(), new Module("", ""), false, true); new HashMap<String, Module>(), new Module("", ""), false, true);
checkFilesFound(foundFiles.keySet(), a1); checkFilesFound(foundFiles.keySet(), a1);
@ -148,7 +148,7 @@ public class OptionDecoding {
Options options = Options.parseArgs("-i", "pkg1/*", "root"); Options options = Options.parseArgs("-i", "pkg1/*", "root");
Map<String, Source> foundFiles = new HashMap<>(); Map<String, Source> foundFiles = new HashMap<>();
ClientMain.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
new HashMap<String, Module>(), new Module("", ""), false, true); new HashMap<String, Module>(), new Module("", ""), false, true);
checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2); checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
@ -160,7 +160,7 @@ public class OptionDecoding {
Options options = Options.parseArgs("-xf", "root/pkg1/ClassA1.java", "root"); Options options = Options.parseArgs("-xf", "root/pkg1/ClassA1.java", "root");
Map<String, Source> foundFiles = new HashMap<>(); Map<String, Source> foundFiles = new HashMap<>();
ClientMain.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
new HashMap<String, Module>(), new Module("", ""), false, true); new HashMap<String, Module>(), new Module("", ""), false, true);
checkFilesFound(foundFiles.keySet(), a2, b1, b2, c1, c2); checkFilesFound(foundFiles.keySet(), a2, b1, b2, c1, c2);
@ -171,7 +171,7 @@ public class OptionDecoding {
Options options = Options.parseArgs("-i", "pkg1/*", "root"); Options options = Options.parseArgs("-i", "pkg1/*", "root");
Map<String, Source> foundFiles = new HashMap<>(); Map<String, Source> foundFiles = new HashMap<>();
ClientMain.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
new HashMap<String, Module>(), new Module("", ""), false, true); new HashMap<String, Module>(), new Module("", ""), false, true);
checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2); checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
@ -182,7 +182,7 @@ public class OptionDecoding {
Options options = Options.parseArgs("-i", "pkg1/*", "-x", "pkg1/pkg2/*", "root"); Options options = Options.parseArgs("-i", "pkg1/*", "-x", "pkg1/pkg2/*", "root");
Map<String, Source> foundFiles = new HashMap<>(); Map<String, Source> foundFiles = new HashMap<>();
ClientMain.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
new HashMap<String, Module>(), new Module("", ""), false, true); new HashMap<String, Module>(), new Module("", ""), false, true);
checkFilesFound(foundFiles.keySet(), a1, a2); checkFilesFound(foundFiles.keySet(), a1, a2);

View file

@ -32,18 +32,12 @@
* @build Wrapper * @build Wrapper
* @run main Wrapper PooledExecution * @run main Wrapper PooledExecution
*/ */
import java.io.File;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import com.sun.tools.sjavac.comp.PooledSjavac; import com.sun.tools.sjavac.comp.PooledSjavac;
import com.sun.tools.sjavac.server.CompilationResult; import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
public class PooledExecution { public class PooledExecution {
@ -75,12 +69,7 @@ public class PooledExecution {
for (int i = 0; i < NUM_REQUESTS; i++) { for (int i = 0; i < NUM_REQUESTS; i++) {
tasks[i] = new Thread() { tasks[i] = new Thread() {
public void run() { public void run() {
service.compile("", service.compile(new String[0]);
"",
new String[0],
Collections.<File>emptyList(),
Collections.<URI>emptySet(),
Collections.<URI>emptySet());
tasksFinished.incrementAndGet(); tasksFinished.incrementAndGet();
} }
}; };
@ -122,12 +111,7 @@ public class PooledExecution {
AtomicInteger activeRequests = new AtomicInteger(0); AtomicInteger activeRequests = new AtomicInteger(0);
@Override @Override
public CompilationResult compile(String protocolId, public CompilationResult compile(String[] args) {
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
leftToStart.countDown(); leftToStart.countDown();
int numActiveRequests = activeRequests.incrementAndGet(); int numActiveRequests = activeRequests.incrementAndGet();
System.out.printf("Left to start: %2d / Currently active: %2d%n", System.out.printf("Left to start: %2d / Currently active: %2d%n",
@ -144,19 +128,9 @@ public class PooledExecution {
return null; return null;
} }
@Override
public SysInfo getSysInfo() {
return null;
}
@Override @Override
public void shutdown() { public void shutdown() {
} }
@Override
public String serverSettings() {
return "";
}
} }
} }
} }