8054474: Add --state-dir=bar to sjavac
authorohrstrom
Fri, 08 Aug 2014 21:26:23 +0200
changeset 26088 f479ca655ba1
parent 26087 93e7681752f6
child 26089 196b7a50a266
8054474: Add --state-dir=bar to sjavac Summary: Add --state-dir=bar to sjavac to control where sjavac stores the javac_state file. Reviewed-by: jjg, alundblad
langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java
langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java
langtools/src/share/classes/com/sun/tools/sjavac/Main.java
langtools/src/share/classes/com/sun/tools/sjavac/comp/JavacServiceImpl.java
langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java
langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java
langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java
langtools/src/share/classes/com/sun/tools/sjavac/server/JavacService.java
langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java
langtools/test/tools/sjavac/SJavac.java
--- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Fri Aug 08 21:26:23 2014 +0200
@@ -86,15 +86,9 @@
         boolean concurrentCompiles = true;
 
         // Fetch the id.
-        String idOpt = Util.extractStringOption("id", args.getServerConf());
-        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;
+        final String id = Util.extractStringOption("id", javacService.serverSettings());
         // 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!
         SysInfo sysinfo = javacService.getSysInfo();
--- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java	Fri Aug 08 21:26:23 2014 +0200
@@ -60,7 +60,6 @@
     int numCores;
 
     // The bin_dir/javac_state
-    private String javacStateFilename;
     private File javacState;
 
     // The previous build state is loaded from javac_state
@@ -99,7 +98,7 @@
     private Set<String> recompiledPackages;
 
     // 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.
     private Set<File> binArtifacts;
@@ -136,8 +135,8 @@
         binDir = Util.pathToFile(options.getDestDir());
         gensrcDir = Util.pathToFile(options.getGenSrcDir());
         headerDir = Util.pathToFile(options.getHeaderDir());
-        javacStateFilename = binDir.getPath()+File.separator+"javac_state";
-        javacState = new File(javacStateFilename);
+        stateDir = Util.pathToFile(options.getStateDir());
+        javacState = new File(stateDir, "javac_state");
         if (removeJavacState && javacState.exists()) {
             javacState.delete();
         }
@@ -268,7 +267,7 @@
      */
     public void save() throws IOException {
         if (!needsSaving) return;
-        try (FileWriter out = new FileWriter(javacStateFilename)) {
+        try (FileWriter out = new FileWriter(javacState)) {
             StringBuilder b = new StringBuilder();
             long millisNow = System.currentTimeMillis();
             Date d = new Date(millisNow);
@@ -311,7 +310,7 @@
         boolean newCommandLine = false;
         boolean syntaxError = false;
 
-        try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
+        try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
             for (;;) {
                 String l = in.readLine();
                 if (l==null) break;
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java	Fri Aug 08 21:26:23 2014 +0200
@@ -205,6 +205,9 @@
         if (!createIfMissing(options.getDestDir()))
             return -1;
 
+        if (!createIfMissing(options.getStateDir()))
+            return -1;
+
         Path gensrc = options.getGenSrcDir();
         if (gensrc != null && !createIfMissing(gensrc))
             return -1;
@@ -345,7 +348,7 @@
                 // Currently sjavac always connects to a server through a socket
                 // regardless if sjavac runs as a background service or not.
                 // 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);
                 if (!rc[0]) break;
             } while (again);
--- a/langtools/src/share/classes/com/sun/tools/sjavac/comp/JavacServiceImpl.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/JavacServiceImpl.java	Fri Aug 08 21:26:23 2014 +0200
@@ -143,4 +143,10 @@
 
         return compilationResult;
     }
+
+    @Override
+    public String serverSettings() {
+        return "";
+    }
+
 }
--- a/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java	Fri Aug 08 21:26:23 2014 +0200
@@ -274,8 +274,16 @@
             if (dir != null)
                 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;
 
     final String description;
--- a/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Fri Aug 08 21:26:23 2014 +0200
@@ -104,6 +104,9 @@
     /** Sets the directory for generated headers */
     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 */
     public abstract void implicit(String policy);
 
--- a/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java	Fri Aug 08 21:26:23 2014 +0200
@@ -41,7 +41,7 @@
 public class Options {
 
     // Output directories
-    private Path destDir, genSrcDir, headerDir;
+    private Path destDir, genSrcDir, headerDir, stateDir;
 
     // Input directories
     private List<SourceLocation> sources = new ArrayList<>();
@@ -86,6 +86,11 @@
         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 */
     public List<SourceLocation> getSources() {
         return sources;
@@ -231,6 +236,9 @@
         if (destDir != null)
             args.addArg(Option.D, destDir.normalize());
 
+        if (stateDir != null)
+            args.addArg(Option.STATE_DIR, stateDir.normalize());
+
         // Source roots
         args.addSourceLocations(Option.SRC, sources);
         args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths);
@@ -319,6 +327,7 @@
 
         boolean headerProvided = false;
         boolean genSrcProvided = false;
+        boolean stateProvided = false;
 
         @Override
         public void reportError(String msg) {
@@ -457,6 +466,16 @@
             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) {
             List<SourceLocation> result = new ArrayList<>();
             for (Path path : paths) {
--- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacService.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacService.java	Fri Aug 08 21:26:23 2014 +0200
@@ -40,4 +40,5 @@
                               List<File> explicitSources,
                               Set<URI> sourcesToCompile,
                               Set<URI> visibleSources);
+    String serverSettings();
 }
--- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java	Fri Aug 08 21:26:23 2014 +0200
@@ -46,6 +46,7 @@
 import java.util.Set;
 
 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_FATAL;
@@ -72,19 +73,34 @@
     // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
     private final String sjavac;
 
-    public JavacServiceClient(String settings) {
-        id = Util.extractStringOption("id", settings);
-        portfile = Util.extractStringOption("portfile", settings);
-        logfile = Util.extractStringOption("logfile", settings, portfile + ".javaclog");
-        stdouterrfile = Util.extractStringOption("stdouterrfile", settings, portfile + ".stdouterr");
-        background = Util.extractBooleanOption("background", settings, true);
-        sjavac = Util.extractStringOption("sjavac", settings, "sjavac");
-        int poolsize = Util.extractIntOption("poolsize", settings);
-        keepalive = Util.extractIntOption("keepalive", settings, 120);
+    // Store the server conf settings here.
+    private final String settings;
+
+    public JavacServiceClient(Options options) {
+        String tmpServerConf = options.getServerConf();
+        String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
+        String tmpId = Util.extractStringOption("id", serverConf);
+        id = (tmpId!=null) ? tmpId : "id"+(((new java.util.Random()).nextLong())&Long.MAX_VALUE);
+        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();
+        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.
--- a/langtools/test/tools/sjavac/SJavac.java	Fri Aug 08 20:47:24 2014 +0200
+++ b/langtools/test/tools/sjavac/SJavac.java	Fri Aug 08 21:26:23 2014 +0200
@@ -25,7 +25,7 @@
 /*
  * @test
  * @summary Test all aspects of sjavac.
- * @bug 8004658 8042441 8042699 8054461
+ * @bug 8004658 8042441 8042699 8054461 8054474
  *
  * @build Wrapper
  * @run main Wrapper SJavac
@@ -100,6 +100,7 @@
         compileExcludingDependency();
         incrementalCompileTestFullyQualifiedRef();
         compileWithAtFile();
+        testStateDir();
 
         delete(gensrc);
         delete(gensrc2);
@@ -495,6 +496,37 @@
                          "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 {
         for (String filename : args) {
             Path p = dir.resolve(filename);