changeset 3034:c8206f440046

8135131: Enable thin server mode in Sjavac Summary: State tracknig and incremental compilation disabled unless --state-dir is provided. Reviewed-by: jlahoda
author alundblad
date Mon, 21 Sep 2015 11:19:10 +0200
parents 6b3b94a2ebca
children 8e76163b3f3a
files src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java test/tools/sjavac/ApiExtraction.java test/tools/sjavac/ClasspathDependencies.java test/tools/sjavac/CompileCircularSources.java test/tools/sjavac/CompileExcludingDependency.java test/tools/sjavac/CompileWithAtFile.java test/tools/sjavac/CompileWithInvisibleSources.java test/tools/sjavac/CompileWithOverrideSources.java test/tools/sjavac/ExclPattern.java test/tools/sjavac/IgnoreSymbolFile.java test/tools/sjavac/IncCompInheritance.java test/tools/sjavac/IncCompileChangeNative.java test/tools/sjavac/IncCompileDropClasses.java test/tools/sjavac/IncCompileFullyQualifiedRef.java test/tools/sjavac/IncCompileNoChanges.java test/tools/sjavac/IncCompileUpdateNative.java test/tools/sjavac/IncCompileWithChanges.java test/tools/sjavac/NoState.java test/tools/sjavac/OptionDecoding.java test/tools/sjavac/ParallelCompilations.java test/tools/sjavac/PermittedArtifact.java test/tools/sjavac/SJavacTester.java
diffstat 25 files changed, 304 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Mon Sep 21 11:19:10 2015 +0200
@@ -322,6 +322,13 @@
         return instance;
     }
 
+    /**
+     * Register a Context.Factory to create a Log.
+     */
+    public static void preRegister(Context context, PrintWriter w) {
+        context.put(Log.class, (Context.Factory<Log>) (c -> new Log(c, w)));
+    }
+
     /** The number of errors encountered so far.
      */
     public int nerrors = 0;
--- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Mon Sep 21 11:19:10 2015 +0200
@@ -91,7 +91,7 @@
         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 defaultPortfile = options.getStateDir()
+        String defaultPortfile = options.getDestDir()
                                         .resolve("javac_server")
                                         .toAbsolutePath()
                                         .toString();
--- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Mon Sep 21 11:19:10 2015 +0200
@@ -36,7 +36,11 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Stream;
 
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.util.Context;
 import com.sun.tools.sjavac.JavacState;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Module;
@@ -44,10 +48,13 @@
 import com.sun.tools.sjavac.Source;
 import com.sun.tools.sjavac.Transformer;
 import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.options.Option;
 import com.sun.tools.sjavac.options.Options;
 import com.sun.tools.sjavac.options.SourceLocation;
 import com.sun.tools.sjavac.server.Sjavac;
 
+import javax.tools.JavaFileManager;
+
 /**
  * The sjavac implementation that interacts with javac and performs the actual
  * compilation.
@@ -77,7 +84,8 @@
         if (!createIfMissing(options.getDestDir()))
             return RC_FATAL;
 
-        if (!createIfMissing(options.getStateDir()))
+        Path stateDir = options.getStateDir();
+        if (stateDir != null && !createIfMissing(options.getStateDir()))
             return RC_FATAL;
 
         Path gensrc = options.getGenSrcDir();
@@ -88,164 +96,189 @@
         if (hdrdir != null && !createIfMissing(hdrdir))
             return RC_FATAL;
 
-        // Load the prev build state database.
-        JavacState javac_state = JavacState.load(options, out, err);
+        if (stateDir == null) {
+            // Prepare context. Direct logging to our byte array stream.
+            Context context = new Context();
+            PrintWriter writer = new PrintWriter(err);
+            com.sun.tools.javac.util.Log.preRegister(context, writer);
+            JavacFileManager.preRegister(context);
 
-        // Setup the suffix rules from the command line.
-        Map<String, Transformer> suffixRules = new HashMap<>();
+            // Prepare arguments
+            String[] passThroughArgs = Stream.of(args)
+                                             .filter(arg -> !arg.startsWith(Option.SERVER.arg))
+                                             .toArray(String[]::new);
 
-        // Handling of .java-compilation
-        suffixRules.putAll(javac_state.getJavaSuffixRule());
+            // Compile
+            com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac", writer);
+            Main.Result result = compiler.compile(passThroughArgs, context);
 
-        // Handling of -copy and -tr
-        suffixRules.putAll(options.getTranslationRules());
+            // Clean up
+            JavaFileManager fileManager = context.get(JavaFileManager.class);
+            if (fileManager instanceof JavacFileManager) {
+                ((JavacFileManager) fileManager).close();
+            }
+            return result.exitCode;
 
-        // 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);
+        } else {
+            // Load the prev build state database.
+            JavacState javac_state = JavacState.load(options, out, err);
 
-        // Find all sources, use the suffix rules to know which files are sources.
-        Map<String,Source> sources = new HashMap<>();
+            // Setup the suffix rules from the command line.
+            Map<String, Transformer> suffixRules = 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);
+            // Handling of .java-compilation
+            suffixRules.putAll(javac_state.getJavaSuffixRule());
 
-        if (sources.isEmpty()) {
-            Log.error("Found nothing to compile!");
-            return RC_FATAL;
-        }
+            // 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);
 
-        // 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<>();
+            // Find all sources, use the suffix rules to know which files are sources.
+            Map<String,Source> sources = 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 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);
 
-        // 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;
-                }
-                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 (sources.isEmpty()) {
+                Log.error("Found nothing to compile!");
+                return RC_FATAL;
             }
 
-            return rc[0] ? RC_OK : RC_FATAL;
-        } catch (ProblemException e) {
-            Log.error(e.getMessage());
-            return RC_FATAL;
-        } catch (Exception e) {
-            e.printStackTrace(new PrintWriter(err));
-            return RC_FATAL;
+
+            // 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;
+                    }
+                    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);
+                }
+
+                return rc[0] ? RC_OK : RC_FATAL;
+            } catch (ProblemException e) {
+                Log.error(e.getMessage());
+                return RC_FATAL;
+            } catch (Exception e) {
+                e.printStackTrace(new PrintWriter(err));
+                return RC_FATAL;
+            }
         }
     }
 
@@ -266,8 +299,8 @@
             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.getSources().isEmpty() && options.getStateDir() != null) {
+            err = "You have to specify -src when using --state-dir.";
         } else if (options.getTranslationRules().size() > 1
                 && options.getGenSrcDir() == null) {
             err = "You have translators but no gensrc dir (-s) specified!";
--- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Mon Sep 21 11:19:10 2015 +0200
@@ -97,7 +97,7 @@
 
     /** Get the path for the state directory, defaults to destDir. */
     public Path getStateDir() {
-        return stateDir != null ? stateDir : destDir;
+        return stateDir;
     }
 
     /** Get all source locations for files to be compiled */
--- a/test/tools/sjavac/ApiExtraction.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/ApiExtraction.java	Mon Sep 21 11:19:10 2015 +0200
@@ -89,7 +89,7 @@
         new ToolBox().new JavacTask().sources(testSrc).run();
 
         // Extract PubApi
-        Options options = Options.parseArgs("-d", "bin", "-cp", ".");
+        Options options = Options.parseArgs("-d", "bin", "--state-dir=bin", "-cp", ".");
         PubApiExtractor pubApiExtr = new PubApiExtractor(options);
         PubApi actualApi = pubApiExtr.getPubApi("TestClass");
 
--- a/test/tools/sjavac/ClasspathDependencies.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/ClasspathDependencies.java	Mon Sep 21 11:19:10 2015 +0200
@@ -64,7 +64,7 @@
         headline("Create a test dependency, Dep.class, and put it in the classpath dir");
         String depCode = "package dep; public class Dep { public void m1() {} }";
         toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
-        int rc = compile(server, "-d", classesDep, srcDep);
+        int rc = compile(server, "-d", classesDep, "--state-dir=" + classesDep, srcDep);
         check(rc == 0, "Compilation failed unexpectedly");
 
         ////////////////////////////////////////////////////////////////////////
@@ -73,7 +73,7 @@
                           "package pkg;" +
                           "import dep.Dep;" +
                           "public class C { Dep dep; public void m() { new Dep().m1(); } }");
-        rc = compile(server, "-d", classes, src, "-cp", classesDep);
+        rc = compile(server, "-d", classes, "--state-dir=" + classes, src, "-cp", classesDep);
         check(rc == 0, "Compilation failed unexpectedly");
         FileTime modTime1 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
 
@@ -82,12 +82,12 @@
         Thread.sleep(2000);
         depCode = depCode.replaceAll("}$", "private void m2() {} }");
         toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
-        rc = compile(server, "-d", classesDep, srcDep);
+        rc = compile(server, "-d", classesDep, "--state-dir=" + classesDep, srcDep);
         check(rc == 0, "Compilation failed unexpectedly");
 
         ////////////////////////////////////////////////////////////////////////
         headline("Make sure that this does not trigger recompilation of C.java");
-        rc = compile(server, "-d", classes, src, "-cp", classesDep);
+        rc = compile(server, "-d", classes, "--state-dir=" + classes, src, "-cp", classesDep);
         check(rc == 0, "Compilation failed unexpectedly");
         FileTime modTime2 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
         check(modTime1.equals(modTime2), "Recompilation erroneously triggered");
@@ -97,12 +97,12 @@
         Thread.sleep(2000);
         depCode = depCode.replace("m1()", "m1(String... arg)");
         toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
-        rc = compile(server, "-d", classesDep, srcDep);
+        rc = compile(server, "-d", classesDep, "--state-dir=" + classesDep, srcDep);
         check(rc == 0, "Compilation failed unexpectedly");
 
         ////////////////////////////////////////////////////////////////////////
         headline("Make sure that recompilation of C.java is triggered");
-        rc = compile(server, "-d", classes, src, "-cp", classesDep);
+        rc = compile(server, "-d", classes, "--state-dir=" + classes, src, "-cp", classesDep);
         check(rc == 0, "Compilation failed unexpectedly");
         FileTime modTime3 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
         check(modTime2.compareTo(modTime3) < 0, "Recompilation not triggered");
--- a/test/tools/sjavac/CompileCircularSources.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/CompileCircularSources.java	Mon Sep 21 11:19:10 2015 +0200
@@ -63,6 +63,7 @@
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
                 "-h", HEADERS.toString(),
+                "--state-dir=" + BIN,
                 "-j", "3",
                 SERVER_ARG,
                 "--log=debug");
--- a/test/tools/sjavac/CompileExcludingDependency.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/CompileExcludingDependency.java	Mon Sep 21 11:19:10 2015 +0200
@@ -62,6 +62,7 @@
                 "-x", "alfa/omega",
                 "-sourcepath", GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 SERVER_ARG);
 
         Map<String,Long> new_bin_state = collectState(BIN);
--- a/test/tools/sjavac/CompileWithAtFile.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/CompileWithAtFile.java	Mon Sep 21 11:19:10 2015 +0200
@@ -52,7 +52,8 @@
                      "-if */alfa/omega/A.java\n" +
                      "-if */beta/B.java\n" +
                      GENSRC + "\n" +
-                     "-d " + BIN + "\n");
+                     "-d " + BIN + "\n" +
+                     "--state-dir=" + BIN + "\n");
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
                  "package alfa.omega; import beta.B; public class A { B b; }");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
--- a/test/tools/sjavac/CompileWithInvisibleSources.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/CompileWithInvisibleSources.java	Mon Sep 21 11:19:10 2015 +0200
@@ -70,6 +70,7 @@
                 "-sourcepath", GENSRC2.toString(),
                 "-sourcepath", GENSRC3.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG);
@@ -86,6 +87,7 @@
                              "-sourcepath", GENSRC2.toString(),
                              "-sourcepath", GENSRC3.toString(),
                              "-d", BIN.toString(),
+                             "--state-dir=" + BIN,
                              "-h", HEADERS.toString(),
                              "-j", "1",
                              SERVER_ARG);
--- a/test/tools/sjavac/CompileWithOverrideSources.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/CompileWithOverrideSources.java	Mon Sep 21 11:19:10 2015 +0200
@@ -68,6 +68,7 @@
                 GENSRC.toString(),
                 GENSRC2.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG);
@@ -83,6 +84,7 @@
         compileExpectFailure(GENSRC.toString(),
                              GENSRC2.toString(),
                              "-d", BIN.toString(),
+                             "--state-dir=" + BIN,
                              "-h", HEADERS.toString(),
                              "-j", "1",
                              SERVER_ARG);
--- a/test/tools/sjavac/ExclPattern.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/ExclPattern.java	Mon Sep 21 11:19:10 2015 +0200
@@ -61,6 +61,7 @@
                 "-x", "pkg/excl-dir/*",
                 "-src", "srcdir",
                 "-d", "dest",
+                "--state-dir=dest",
                 "-j", "1",
                 "-copy", ".txt",
                 "--server:portfile=testserver,background=false",
--- a/test/tools/sjavac/IgnoreSymbolFile.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IgnoreSymbolFile.java	Mon Sep 21 11:19:10 2015 +0200
@@ -56,11 +56,20 @@
         new File("classes").mkdirs();
 
         String server = "--server:portfile=testserver,background=false";
-        int rc1 = compile(server, "-d", "classes", "-Werror", "src");
+        int rc1 = compile(server,
+                          "-d", "classes",
+                          "--state-dir=classes",
+                          "-Werror",
+                          "src");
         if (rc1 == 0)
             error("compilation succeeded unexpectedly");
 
-        int rc2 = compile(server, "-d", "classes", "-Werror", "-XDignore.symbol.file=true", "src");
+        int rc2 = compile(server,
+                          "-d", "classes",
+                          "--state-dir=classes",
+                          "-Werror",
+                          "-XDignore.symbol.file=true",
+                          "src");
         if (rc2 != 0)
             error("compilation failed unexpectedly: rc=" + rc2);
 
--- a/test/tools/sjavac/IncCompInheritance.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompInheritance.java	Mon Sep 21 11:19:10 2015 +0200
@@ -53,7 +53,7 @@
 
         // Initial compile (should succeed)
         String server = "--server:portfile=testserver,background=false";
-        int rc1 = compile(server, "-d", classes, src);
+        int rc1 = compile(server, "-d", classes, "--state-dir=" + classes, src);
         if (rc1 != 0)
             throw new AssertionError("Compilation failed unexpectedly");
 
@@ -65,7 +65,7 @@
         // Incremental compile (C should now be recompiled even though it
         // depends on A only through inheritance via B).
         // Since A.m is removed, this should fail.
-        int rc2 = compile(server, "-d", classes, src);
+        int rc2 = compile(server, "-d", classes, "--state-dir=" + classes, src);
         if (rc2 == 0)
             throw new AssertionError("Compilation succeeded unexpectedly");
     }
--- a/test/tools/sjavac/IncCompileChangeNative.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompileChangeNative.java	Mon Sep 21 11:19:10 2015 +0200
@@ -76,6 +76,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,
@@ -105,6 +106,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,
--- a/test/tools/sjavac/IncCompileDropClasses.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompileDropClasses.java	Mon Sep 21 11:19:10 2015 +0200
@@ -71,6 +71,7 @@
         removeFrom(GENSRC, "alfa/omega/AA.java");
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,
--- a/test/tools/sjavac/IncCompileFullyQualifiedRef.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompileFullyQualifiedRef.java	Mon Sep 21 11:19:10 2015 +0200
@@ -60,6 +60,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-j", "1",
                 SERVER_ARG,
                 "--log=debug");
@@ -74,6 +75,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-j", "1",
                 SERVER_ARG,
                 "--log=debug");
--- a/test/tools/sjavac/IncCompileNoChanges.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompileNoChanges.java	Mon Sep 21 11:19:10 2015 +0200
@@ -69,6 +69,7 @@
         System.out.println("Testing that no change in sources implies no change in binaries");
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,
--- a/test/tools/sjavac/IncCompileUpdateNative.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompileUpdateNative.java	Mon Sep 21 11:19:10 2015 +0200
@@ -76,6 +76,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,
--- a/test/tools/sjavac/IncCompileWithChanges.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/IncCompileWithChanges.java	Mon Sep 21 11:19:10 2015 +0200
@@ -78,6 +78,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/sjavac/NoState.java	Mon Sep 21 11:19:10 2015 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Test --no-state option
+ * @bug 8135131
+  * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.file
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.sjavac
+ * @build Wrapper ToolBox
+ * @run main Wrapper NoState
+ */
+
+import com.sun.tools.javac.util.Assert;
+
+import java.util.*;
+import java.nio.file.*;
+
+public class NoState extends SJavacTester {
+    public static void main(String... args) throws Exception {
+        new NoState().run();
+    }
+
+    public void run() throws Exception {
+        clean(TEST_ROOT);
+        ToolBox tb = new ToolBox();
+        tb.writeFile(GENSRC.resolve("pkg/A.java"), "package pkg; class A {}");
+        Files.createDirectory(BIN);
+        compile("-d", BIN.toString(),
+                "--server:portfile=testserver,background=false",
+                GENSRC + "/pkg/A.java");
+
+        // Make sure file was compiled
+        Assert.check(Files.exists(BIN.resolve("pkg/A.class")));
+
+        // Make sure we have no other files (such as a javac_state file) in the bin directory
+        Assert.check(Files.list(BIN).count() == 1);
+        Assert.check(Files.list(BIN.resolve("pkg")).count() == 1);
+    }
+}
--- a/test/tools/sjavac/OptionDecoding.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/OptionDecoding.java	Mon Sep 21 11:19:10 2015 +0200
@@ -59,7 +59,6 @@
 public class OptionDecoding {
 
     public static void main(String[] args) throws IOException {
-
         testPaths();
         testDupPaths();
         testSourceLocations();
@@ -67,30 +66,28 @@
         testServerConf();
         testSearchPaths();
         testTranslationRules();
-
     }
 
     // Test decoding of output paths
     static void testPaths() throws IOException {
-
         final String H = "headers";
         final String G = "gensrc";
         final String D = "dest";
+        final String stateDir = "stateDir";
         final String CMP = "srcRefList.txt";
 
-        Options options = Options.parseArgs("-h", H, "-s", G, "-d", D,
+        Options options = Options.parseArgs("-h", H, "-s", G, "-d", D, "--state-dir=" + stateDir,
                                             "--compare-found-sources", CMP);
 
         assertEquals(Paths.get(H).toAbsolutePath(), options.getHeaderDir());
         assertEquals(Paths.get(G).toAbsolutePath(), options.getGenSrcDir());
         assertEquals(Paths.get(D).toAbsolutePath(), options.getDestDir());
+        assertEquals(Paths.get(stateDir).toAbsolutePath(), options.getStateDir());
         assertEquals(Paths.get(CMP), options.getSourceReferenceList());
-
     }
 
     // Providing duplicate header / dest / gensrc paths should produce an error.
     static void testDupPaths() throws IOException {
-
         try {
             Options.parseArgs("-h", "dir1", "-h", "dir2");
             throw new RuntimeException("Duplicate header directories should fail.");
@@ -111,12 +108,10 @@
         } catch (IllegalArgumentException iae) {
             // Expected
         }
-
     }
 
     // Test source locations and -x, -i, -xf, -if filters
     static void testSourceLocations() throws IOException {
-
         Path a1 = Paths.get("root/pkg1/ClassA1.java");
         Path a2 = Paths.get("root/pkg1/ClassA2.java");
         Path b1 = Paths.get("root/pkg1/pkg2/ClassB1.java");
@@ -185,12 +180,10 @@
 
             checkFilesFound(foundFiles.keySet(), a1, a2);
         }
-
     }
 
     // Test basic options
     static void testSimpleOptions() {
-
         Options options = Options.parseArgs("-j", "17", "--log=debug");
         assertEquals(17, options.getNumCores());
         assertEquals("debug", options.getLogLevel());
@@ -239,7 +232,6 @@
 
     // Test -tr option
     static void testTranslationRules() {
-
         Class<?> cls = com.sun.tools.sjavac.CompileJavaPackages.class;
 
         Options options = Options.parseArgs(
@@ -250,6 +242,5 @@
         assertEquals(cls, options.getTranslationRules().get(".exa").getClass());
         assertEquals(cls, options.getTranslationRules().get(".exb").getClass());
         assertEquals(CopyFile.class, options.getTranslationRules().get(".html").getClass());
-
     }
 }
--- a/test/tools/sjavac/ParallelCompilations.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/ParallelCompilations.java	Mon Sep 21 11:19:10 2015 +0200
@@ -46,21 +46,22 @@
 
   public void run() throws Exception {
     ToolBox tb = new ToolBox();
-    final String SERVER_ARG = "--server:"
-            + "portfile=testportfile,"
-            + "background=false";
 
     // Generate 10 files
     for (int i = 0; i < 10; i++) {
-      String fileName = "Test" + i;
       String content = "package foo"+ i + ";\n" +
-                       "public class "+ fileName + "{\n" +
+                       "public class Test" + i + "{\n" +
                        "  public static void main(String[] args) {}\n" +
                        "\n}";
       Path srcDir = Paths.get("src");
-      tb.writeJavaFiles(srcDir,content);
+      tb.writeJavaFiles(srcDir, content);
     }
-    //Method will throw an exception if compilation fails
-    compile("src", "-d", "classes", "-j", "10", SERVER_ARG, "--log=debug");
+    // Method will throw an exception if compilation fails
+    compile("src",
+            "-d", BIN.toString(),
+            "--state-dir=" + BIN,
+            "-j", "10",
+            SERVER_ARG,
+            "--log=debug");
   }
 }
--- a/test/tools/sjavac/PermittedArtifact.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/PermittedArtifact.java	Mon Sep 21 11:19:10 2015 +0200
@@ -65,6 +65,7 @@
                 "--permit-artifact=" + BIN + "/alfa/omega/AA.class",
                 "-src", GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 SERVER_ARG);
 
         Map<String,Long> new_bin_state = collectState(BIN);
--- a/test/tools/sjavac/SJavacTester.java	Fri Sep 18 14:21:17 2015 -0700
+++ b/test/tools/sjavac/SJavacTester.java	Mon Sep 21 11:19:10 2015 +0200
@@ -87,6 +87,7 @@
 
         compile(GENSRC.toString(),
                 "-d", BIN.toString(),
+                "--state-dir=" + BIN,
                 "-h", HEADERS.toString(),
                 "-j", "1",
                 SERVER_ARG,