8054474: Add --state-dir=bar to sjavac

Add --state-dir=bar to sjavac to control where sjavac stores the javac_state file.

Reviewed-by: jjg, alundblad
This commit is contained in:
Fredrik Öhrström 2014-08-08 21:26:23 +02:00
parent ce6154a2fa
commit c8256e4d27
10 changed files with 107 additions and 26 deletions

View file

@ -86,15 +86,9 @@ public class CompileJavaPackages implements Transformer {
boolean concurrentCompiles = true; boolean concurrentCompiles = true;
// Fetch the id. // Fetch the id.
String idOpt = Util.extractStringOption("id", args.getServerConf()); final String id = Util.extractStringOption("id", javacService.serverSettings());
if (idOpt == null || idOpt.equals("")) {
// No explicit id set. Create a random id so that the requests can be
// grouped properly in the server.
idOpt = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
}
final String id = idOpt;
// Only keep portfile and sjavac settings.. // Only keep portfile and sjavac settings..
String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf()); String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), javacService.serverSettings());
// Get maximum heap size from the server! // Get maximum heap size from the server!
SysInfo sysinfo = javacService.getSysInfo(); SysInfo sysinfo = javacService.getSysInfo();

View file

@ -60,7 +60,6 @@ public class JavacState
int numCores; int numCores;
// The bin_dir/javac_state // The bin_dir/javac_state
private String javacStateFilename;
private File javacState; private File javacState;
// The previous build state is loaded from javac_state // The previous build state is loaded from javac_state
@ -99,7 +98,7 @@ public class JavacState
private Set<String> recompiledPackages; private Set<String> recompiledPackages;
// The output directories filled with tasty artifacts. // The output directories filled with tasty artifacts.
private File binDir, gensrcDir, headerDir; private File binDir, gensrcDir, headerDir, stateDir;
// The current status of the file system. // The current status of the file system.
private Set<File> binArtifacts; private Set<File> binArtifacts;
@ -136,8 +135,8 @@ public class JavacState
binDir = Util.pathToFile(options.getDestDir()); binDir = Util.pathToFile(options.getDestDir());
gensrcDir = Util.pathToFile(options.getGenSrcDir()); gensrcDir = Util.pathToFile(options.getGenSrcDir());
headerDir = Util.pathToFile(options.getHeaderDir()); headerDir = Util.pathToFile(options.getHeaderDir());
javacStateFilename = binDir.getPath()+File.separator+"javac_state"; stateDir = Util.pathToFile(options.getStateDir());
javacState = new File(javacStateFilename); javacState = new File(stateDir, "javac_state");
if (removeJavacState && javacState.exists()) { if (removeJavacState && javacState.exists()) {
javacState.delete(); javacState.delete();
} }
@ -268,7 +267,7 @@ public class JavacState
*/ */
public void save() throws IOException { public void save() throws IOException {
if (!needsSaving) return; if (!needsSaving) return;
try (FileWriter out = new FileWriter(javacStateFilename)) { try (FileWriter out = new FileWriter(javacState)) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
long millisNow = System.currentTimeMillis(); long millisNow = System.currentTimeMillis();
Date d = new Date(millisNow); Date d = new Date(millisNow);
@ -311,7 +310,7 @@ public class JavacState
boolean newCommandLine = false; boolean newCommandLine = false;
boolean syntaxError = false; boolean syntaxError = false;
try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) { try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
for (;;) { for (;;) {
String l = in.readLine(); String l = in.readLine();
if (l==null) break; if (l==null) break;

View file

@ -205,6 +205,9 @@ public class Main {
if (!createIfMissing(options.getDestDir())) if (!createIfMissing(options.getDestDir()))
return -1; return -1;
if (!createIfMissing(options.getStateDir()))
return -1;
Path gensrc = options.getGenSrcDir(); Path gensrc = options.getGenSrcDir();
if (gensrc != null && !createIfMissing(gensrc)) if (gensrc != null && !createIfMissing(gensrc))
return -1; return -1;
@ -345,7 +348,7 @@ public class Main {
// Currently sjavac always connects to a server through a socket // Currently sjavac always connects to a server through a socket
// regardless if sjavac runs as a background service or not. // regardless if sjavac runs as a background service or not.
// This will most likely change in the future. // This will most likely change in the future.
JavacService javacService = new JavacServiceClient(options.getServerConf()); JavacService javacService = new JavacServiceClient(options);
again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc); again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc);
if (!rc[0]) break; if (!rc[0]) break;
} while (again); } while (again);

View file

@ -143,4 +143,10 @@ public class JavacServiceImpl implements JavacService {
return compilationResult; return compilationResult;
} }
@Override
public String serverSettings() {
return "";
}
} }

View file

@ -274,8 +274,16 @@ public enum Option {
if (dir != null) if (dir != null)
helper.headerDir(dir); helper.headerDir(dir);
} }
},
STATE_DIR("--state-dir=", "Directory used to store sjavac state and log files.") {
@Override
protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
String p = iter.current().substring(arg.length());
helper.stateDir(Paths.get(p));
}
}; };
public final String arg; public final String arg;
final String description; final String description;

View file

@ -104,6 +104,9 @@ public abstract class OptionHelper {
/** Sets the directory for generated headers */ /** Sets the directory for generated headers */
public abstract void headerDir(Path dir); public abstract void headerDir(Path dir);
/** Sets the directory for state and log files generated by sjavac */
public abstract void stateDir(Path dir);
/** Sets the implicit policy */ /** Sets the implicit policy */
public abstract void implicit(String policy); public abstract void implicit(String policy);

View file

@ -41,7 +41,7 @@ import com.sun.tools.sjavac.Transformer;
public class Options { public class Options {
// Output directories // Output directories
private Path destDir, genSrcDir, headerDir; private Path destDir, genSrcDir, headerDir, stateDir;
// Input directories // Input directories
private List<SourceLocation> sources = new ArrayList<>(); private List<SourceLocation> sources = new ArrayList<>();
@ -86,6 +86,11 @@ public class Options {
return headerDir; return headerDir;
} }
/** Get the path for the state directory, defaults to destDir. */
public Path getStateDir() {
return stateDir != null ? stateDir : destDir;
}
/** Get all source locations for files to be compiled */ /** Get all source locations for files to be compiled */
public List<SourceLocation> getSources() { public List<SourceLocation> getSources() {
return sources; return sources;
@ -231,6 +236,9 @@ public class Options {
if (destDir != null) if (destDir != null)
args.addArg(Option.D, destDir.normalize()); args.addArg(Option.D, destDir.normalize());
if (stateDir != null)
args.addArg(Option.STATE_DIR, stateDir.normalize());
// Source roots // Source roots
args.addSourceLocations(Option.SRC, sources); args.addSourceLocations(Option.SRC, sources);
args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths); args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths);
@ -319,6 +327,7 @@ public class Options {
boolean headerProvided = false; boolean headerProvided = false;
boolean genSrcProvided = false; boolean genSrcProvided = false;
boolean stateProvided = false;
@Override @Override
public void reportError(String msg) { public void reportError(String msg) {
@ -457,6 +466,16 @@ public class Options {
headerDir = dir.toAbsolutePath(); headerDir = dir.toAbsolutePath();
} }
@Override
public void stateDir(Path dir) {
if (stateProvided) {
reportError("State directory already specified.");
return;
}
stateProvided = true;
stateDir = dir.toAbsolutePath();
}
private List<SourceLocation> createSourceLocations(List<Path> paths) { private List<SourceLocation> createSourceLocations(List<Path> paths) {
List<SourceLocation> result = new ArrayList<>(); List<SourceLocation> result = new ArrayList<>();
for (Path path : paths) { for (Path path : paths) {

View file

@ -40,4 +40,5 @@ public interface JavacService {
List<File> explicitSources, List<File> explicitSources,
Set<URI> sourcesToCompile, Set<URI> sourcesToCompile,
Set<URI> visibleSources); Set<URI> visibleSources);
String serverSettings();
} }

View file

@ -46,6 +46,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import com.sun.tools.sjavac.Util; import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.options.Options;
import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN; import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL; import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
@ -72,19 +73,34 @@ public class JavacServiceClient implements JavacService {
// for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
private final String sjavac; private final String sjavac;
public JavacServiceClient(String settings) { // Store the server conf settings here.
id = Util.extractStringOption("id", settings); private final String settings;
portfile = Util.extractStringOption("portfile", settings);
logfile = Util.extractStringOption("logfile", settings, portfile + ".javaclog"); public JavacServiceClient(Options options) {
stdouterrfile = Util.extractStringOption("stdouterrfile", settings, portfile + ".stdouterr"); String tmpServerConf = options.getServerConf();
background = Util.extractBooleanOption("background", settings, true); String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
sjavac = Util.extractStringOption("sjavac", settings, "sjavac"); String tmpId = Util.extractStringOption("id", serverConf);
int poolsize = Util.extractIntOption("poolsize", settings); id = (tmpId!=null) ? tmpId : "id"+(((new java.util.Random()).nextLong())&Long.MAX_VALUE);
keepalive = Util.extractIntOption("keepalive", settings, 120); String p = Util.extractStringOption("portfile", serverConf);
portfile = (p!=null) ? p : options.getStateDir().toFile().getAbsolutePath()+File.separatorChar+"javac_server";
logfile = Util.extractStringOption("logfile", serverConf, portfile + ".javaclog");
stdouterrfile = Util.extractStringOption("stdouterrfile", serverConf, portfile + ".stdouterr");
background = Util.extractBooleanOption("background", serverConf, true);
sjavac = Util.extractStringOption("sjavac", serverConf, "sjavac");
int poolsize = Util.extractIntOption("poolsize", serverConf);
keepalive = Util.extractIntOption("keepalive", serverConf, 120);
this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors(); this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
settings = (serverConf.equals("")) ? "id="+id+",portfile="+portfile : serverConf;
} }
/**
* Hand out the server settings.
* @return The server settings, possibly a default value.
*/
public String serverSettings() {
return settings;
}
/** /**
* Make a request to the server only to get the maximum possible heap size to use for compilations. * Make a request to the server only to get the maximum possible heap size to use for compilations.

View file

@ -25,7 +25,7 @@
/* /*
* @test * @test
* @summary Test all aspects of sjavac. * @summary Test all aspects of sjavac.
* @bug 8004658 8042441 8042699 8054461 * @bug 8004658 8042441 8042699 8054461 8054474
* *
* @build Wrapper * @build Wrapper
* @run main Wrapper SJavac * @run main Wrapper SJavac
@ -100,6 +100,7 @@ public class SJavac {
compileExcludingDependency(); compileExcludingDependency();
incrementalCompileTestFullyQualifiedRef(); incrementalCompileTestFullyQualifiedRef();
compileWithAtFile(); compileWithAtFile();
testStateDir();
delete(gensrc); delete(gensrc);
delete(gensrc2); delete(gensrc2);
@ -495,6 +496,37 @@ public class SJavac {
"bin/beta/B.class"); "bin/beta/B.class");
} }
/**
* Tests storing javac_state into another directory.
* @throws Exception If test fails
*/
void testStateDir() throws Exception {
System.out.println("\nVerify that --state-dir=bar works.");
System.out.println("----------------------------------");
Path bar = defaultfs.getPath("bar");
Files.createDirectory(bar);
delete(gensrc);
delete(bin);
delete(bar);
previous_bin_state = collectState(bin);
Map<String,Long> previous_bar_state = collectState(bar);
populate(gensrc,
"alfa/omega/A.java",
"package alfa.omega; public class A { }");
compile("--state-dir=bar", "-src", "gensrc", "-d", "bin", serverArg);
Map<String,Long> new_bin_state = collectState(bin);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class");
Map<String,Long> new_bar_state = collectState(bar);
verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state,
"bar/javac_state");
}
void removeFrom(Path dir, String... args) throws IOException { void removeFrom(Path dir, String... args) throws IOException {
for (String filename : args) { for (String filename : args) {
Path p = dir.resolve(filename); Path p = dir.resolve(filename);