8173777: Merge javac -Xmodule into javac--patch-module
authorjlahoda
Mon, 13 Feb 2017 09:37:26 +0100
changeset 43772 4e5350b7be75
parent 43771 25ddac537bb5
child 43773 8d8593871575
8173777: Merge javac -Xmodule into javac--patch-module Summary: Merging -Xmodule: functionality into --patch-module. Reviewed-by: jjg, mchung, rfield
langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java
langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties
langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java
langtools/test/tools/javac/6627362/T6627362.java
langtools/test/tools/javac/6627362/x/Object.java
langtools/test/tools/javac/6627362/x/java/lang/Object.java
langtools/test/tools/javac/diags/Example.java
langtools/test/tools/javac/diags/examples.not-yet.txt
langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/ModuleInfoWithPatchedModuleClassoutput.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/additional/module-info.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/patchmodule/java.compiler/javax/lang/model/element/Extra.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/ModuleInfoWithPatchedModule.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/patchmodule/java.compiler/javax/lang/model/element/Extra.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/patchmodule/java.compiler/module-info.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithXModuleSourcePath/Extra.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithXModuleSourcePath/module-info.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithXmoduleClasspath/ModuleInfoWithXmoduleClasspath.java
langtools/test/tools/javac/diags/examples/ModuleInfoWithXmoduleClasspath/additional/module-info.java
langtools/test/tools/javac/diags/examples/NoSuperclass.java
langtools/test/tools/javac/diags/examples/NoSuperclass/NoSuperclass.java
langtools/test/tools/javac/diags/examples/NoSuperclass/patchmodule/java.base/java/lang/Object.java
langtools/test/tools/javac/diags/examples/TooManyPatchedModules/TooManyPatchedModules.java
langtools/test/tools/javac/diags/examples/TooManyPatchedModules/patchmodule/java.compiler/p/C.java
langtools/test/tools/javac/diags/examples/TooManyPatchedModules/patchmodule/jdk.compiler/p/C.java
langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java
langtools/test/tools/javac/meth/BadPolySig.java
langtools/test/tools/javac/meth/BadPolySig/BadPolySig.java
langtools/test/tools/javac/meth/BadPolySig/java.base/java/lang/invoke/MethodHandle.java
langtools/test/tools/javac/modules/AddLimitMods.java
langtools/test/tools/javac/modules/AddReadsTest.java
langtools/test/tools/javac/modules/CompileModulePatchTest.java
langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java
langtools/test/tools/javac/modules/PatchModulesTest.java
langtools/test/tools/javac/modules/XModuleTest.java
langtools/test/tools/javac/synthesize/Main.java
langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java
--- a/langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java	Mon Feb 13 09:37:26 2017 +0100
@@ -107,7 +107,14 @@
      * @spec JPMS
      * @since 9
      */
-    MODULE_PATH;
+    MODULE_PATH,
+
+    /**
+     * Location to search for module patches.
+     * @since 9
+     * @spec JPMS
+     */
+    PATCH_MODULE_PATH;
 
     /**
      * Returns a location object with the given name.  The following
@@ -166,6 +173,7 @@
             case UPGRADE_MODULE_PATH:
             case SYSTEM_MODULES:
             case MODULE_PATH:
+            case PATCH_MODULE_PATH:
                 return true;
             default:
                 return false;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Mon Feb 13 09:37:26 2017 +0100
@@ -361,7 +361,7 @@
         @Override @DefinedBy(Api.COMPILER)
         public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
             try {
-                return clientJavaFileManager.getLocationForModule(location, fo, pkgName);
+                return clientJavaFileManager.getLocationForModule(location, unwrap(fo), pkgName);
             } catch (ClientCodeException e) {
                 throw e;
             } catch (RuntimeException | Error e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Mon Feb 13 09:37:26 2017 +0100
@@ -553,20 +553,47 @@
 
         Location classLocn = msym.classLocation;
         Location sourceLocn = msym.sourceLocation;
+        Location patchLocn = msym.patchLocation;
+        Location patchOutLocn = msym.patchOutputLocation;
 
-        if (wantClassFiles && (classLocn != null)) {
-            fillIn(p, classLocn,
-                   list(classLocn,
-                        p,
-                        packageName,
-                        classKinds));
-        }
-        if (wantSourceFiles && (sourceLocn != null)) {
-            fillIn(p, sourceLocn,
-                   list(sourceLocn,
-                        p,
-                        packageName,
-                        sourceKinds));
+        boolean prevPreferCurrent = preferCurrent;
+
+        try {
+            preferCurrent = false;
+            if (wantClassFiles && (patchOutLocn != null)) {
+                fillIn(p, patchOutLocn,
+                       list(patchOutLocn,
+                            p,
+                            packageName,
+                            classKinds));
+            }
+            if ((wantClassFiles || wantSourceFiles) && (patchLocn != null)) {
+                Set<JavaFileObject.Kind> combined = EnumSet.noneOf(JavaFileObject.Kind.class);
+                combined.addAll(classKinds);
+                combined.addAll(sourceKinds);
+                fillIn(p, patchLocn,
+                       list(patchLocn,
+                            p,
+                            packageName,
+                            combined));
+            }
+            preferCurrent = true;
+            if (wantClassFiles && (classLocn != null)) {
+                fillIn(p, classLocn,
+                       list(classLocn,
+                            p,
+                            packageName,
+                            classKinds));
+            }
+            if (wantSourceFiles && (sourceLocn != null)) {
+                fillIn(p, sourceLocn,
+                       list(sourceLocn,
+                            p,
+                            packageName,
+                            sourceKinds));
+            }
+        } finally {
+            preferCurrent = prevPreferCurrent;
         }
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Mon Feb 13 09:37:26 2017 +0100
@@ -267,6 +267,7 @@
     private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) {
         ListBuffer<ModuleSymbol> results = new ListBuffer<>();
         Map<Name, Location> namesInSet = new HashMap<>();
+        boolean multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
         while (moduleLocationIterator.hasNext()) {
             Set<Location> locns = (moduleLocationIterator.next());
             namesInSet.clear();
@@ -279,10 +280,29 @@
                             // module has already been found, so ignore this instance
                             continue;
                         }
+                        if (fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) &&
+                            msym.patchLocation == null) {
+                            msym.patchLocation =
+                                    fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
+                                                                     msym.name.toString());
+                            checkModuleInfoOnLocation(msym.patchLocation, Kind.CLASS, Kind.SOURCE);
+                            if (msym.patchLocation != null &&
+                                multiModuleMode &&
+                                fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
+                                msym.patchOutputLocation =
+                                        fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
+                                                                         msym.name.toString());
+                                checkModuleInfoOnLocation(msym.patchOutputLocation, Kind.CLASS);
+                            }
+                        }
                         if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
-                            msym.sourceLocation = l;
-                            if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
-                                msym.classLocation = fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, msym.name.toString());
+                            if (msym.patchLocation == null) {
+                                msym.sourceLocation = l;
+                                if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
+                                    msym.classLocation =
+                                            fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
+                                                                             msym.name.toString());
+                                }
                             }
                         } else {
                             msym.classLocation = l;
@@ -291,7 +311,8 @@
                             moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) {
                             msym.flags_field |= Flags.SYSTEM_MODULE;
                         }
-                        if (toFind == msym || toFind == null) {
+                        if (toFind == null ||
+                            (toFind == msym && (msym.sourceLocation != null || msym.classLocation != null))) {
                             // Note: cannot return msym directly, because we must finish
                             // processing this set first
                             results.add(msym);
@@ -311,6 +332,21 @@
         return results.toList();
     }
 
+    private void checkModuleInfoOnLocation(Location location, Kind... kinds) throws IOException {
+        if (location == null)
+            return ;
+
+        for (Kind kind : kinds) {
+            JavaFileObject file = fileManager.getJavaFileForInput(location,
+                                                                  names.module_info.toString(),
+                                                                  kind);
+            if (file != null) {
+                log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(file));
+                return;
+            }
+        }
+    }
+
     private void findModuleInfo(ModuleSymbol msym) {
         try {
             JavaFileObject src_fo = (msym.sourceLocation == null) ? null
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Feb 13 09:37:26 2017 +0100
@@ -908,6 +908,8 @@
         public Name version;
         public JavaFileManager.Location sourceLocation;
         public JavaFileManager.Location classLocation;
+        public JavaFileManager.Location patchLocation;
+        public JavaFileManager.Location patchOutputLocation;
 
         /** All directives, in natural order. */
         public List<com.sun.tools.javac.code.Directive> directives;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Feb 13 09:37:26 2017 +0100
@@ -145,7 +145,7 @@
 
     public final boolean multiModuleMode;
 
-    private final String moduleOverride;
+    private final String legacyModuleOverride;
 
     private final Name java_se;
     private final Name java_;
@@ -192,7 +192,7 @@
 
         lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
 
-        moduleOverride = options.get(Option.XMODULE);
+        legacyModuleOverride = options.get(Option.XMODULE);
 
         multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
         ClassWriter classWriter = ClassWriter.instance(context);
@@ -366,9 +366,26 @@
 
                 JavaFileObject prev = log.useSource(tree.sourcefile);
                 try {
-                    Location locn = getModuleLocation(tree);
-                    if (locn != null) {
-                        Name name = names.fromString(fileManager.inferModuleName(locn));
+                    Location msplocn = getModuleLocation(tree);
+                    Location plocn = fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) ?
+                            fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
+                                                             tree.sourcefile, getPackageName(tree)) :
+                            null;
+
+                    if (plocn != null) {
+                        Name name = names.fromString(fileManager.inferModuleName(plocn));
+                        ModuleSymbol msym = moduleFinder.findModule(name);
+                        tree.modle = msym;
+                        rootModules.add(msym);
+
+                        if (msplocn != null) {
+                            Name mspname = names.fromString(fileManager.inferModuleName(msplocn));
+                            if (name != mspname) {
+                                log.error(tree.pos(), Errors.FilePatchedAndMsp(name, mspname));
+                            }
+                        }
+                    } else if (msplocn != null) {
+                        Name name = names.fromString(fileManager.inferModuleName(msplocn));
                         ModuleSymbol msym;
                         JCModuleDecl decl = tree.getModuleDecl();
                         if (decl != null) {
@@ -383,7 +400,7 @@
                             msym = syms.enterModule(name);
                         }
                         if (msym.sourceLocation == null) {
-                            msym.sourceLocation = locn;
+                            msym.sourceLocation = msplocn;
                             if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
                                 msym.classLocation = fileManager.getLocationForModule(
                                         StandardLocation.CLASS_OUTPUT, msym.name.toString());
@@ -414,7 +431,9 @@
             }
             defaultModule = syms.unnamedModule;
         } else {
+            ModuleSymbol module = null;
             if (defaultModule == null) {
+                String moduleOverride = singleModuleOverride(trees);
                 switch (rootModules.size()) {
                     case 0:
                         defaultModule = moduleFinder.findSingleModule();
@@ -422,38 +441,49 @@
                             if (moduleOverride != null) {
                                 checkNoAllModulePath();
                                 defaultModule = moduleFinder.findModule(names.fromString(moduleOverride));
-                                defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
+                                if (legacyModuleOverride != null) {
+                                    defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
+                                }
+                                defaultModule.patchOutputLocation = StandardLocation.CLASS_OUTPUT;
                             } else {
                                 // Question: why not do findAllModules and initVisiblePackages here?
                                 // i.e. body of unnamedModuleCompleter
                                 defaultModule.completer = getUnnamedModuleCompleter();
+                                defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
                                 defaultModule.classLocation = StandardLocation.CLASS_PATH;
                             }
                         } else {
-                            checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleClasspath);
+                            checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleClassoutput);
                             checkNoAllModulePath();
                             defaultModule.complete();
                             // Question: why not do completeModule here?
                             defaultModule.completer = sym -> completeModule((ModuleSymbol) sym);
+                            defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
                         }
                         rootModules.add(defaultModule);
                         break;
                     case 1:
-                        checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleSourcepath);
+                        checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleSourcepath);
                         checkNoAllModulePath();
                         defaultModule = rootModules.iterator().next();
+                        defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
                         defaultModule.classLocation = StandardLocation.CLASS_OUTPUT;
                         break;
                     default:
                         Assert.error("too many modules");
                 }
-                defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
             } else if (rootModules.size() == 1 && defaultModule == rootModules.iterator().next()) {
                 defaultModule.complete();
                 defaultModule.completer = sym -> completeModule((ModuleSymbol) sym);
             } else {
                 Assert.check(rootModules.isEmpty());
-                rootModules.add(defaultModule);
+                String moduleOverride = singleModuleOverride(trees);
+                if (moduleOverride != null) {
+                    module = moduleFinder.findModule(names.fromString(moduleOverride));
+                } else {
+                    module = defaultModule;
+                }
+                rootModules.add(module);
             }
 
             if (defaultModule != syms.unnamedModule) {
@@ -461,12 +491,56 @@
                 syms.unnamedModule.classLocation = StandardLocation.CLASS_PATH;
             }
 
+            if (module == null) {
+                module = defaultModule;
+            }
+
             for (JCCompilationUnit tree: trees) {
-                tree.modle = defaultModule;
+                tree.modle = module;
             }
         }
     }
 
+    private String singleModuleOverride(List<JCCompilationUnit> trees) {
+        if (!fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) {
+            return legacyModuleOverride;
+        }
+
+        Set<String> override = new LinkedHashSet<>();
+        for (JCCompilationUnit tree : trees) {
+            JavaFileObject fo = tree.sourcefile;
+
+            try {
+                Location loc =
+                        fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
+                                                         fo, getPackageName(tree));
+
+                if (loc != null) {
+                    override.add(fileManager.inferModuleName(loc));
+                }
+            } catch (IOException ex) {
+                throw new Error(ex);
+            }
+        }
+
+        switch (override.size()) {
+            case 0: return legacyModuleOverride;
+            case 1: return override.iterator().next();
+            default:
+                log.error(Errors.TooManyPatchedModules(override));
+                return null;
+        }
+    }
+
+    private String getPackageName(JCCompilationUnit tree) {
+        if (tree.getModuleDecl() != null) {
+            return null;
+        } else {
+            JCPackageDecl pkg = tree.getPackage();
+            return (pkg == null) ? "" : TreeInfo.fullName(pkg.pid).toString();
+        }
+    }
+
     /**
      * Determine the location for the module on the module source path
      * or source output directory which contains a given CompilationUnit.
@@ -478,32 +552,23 @@
      * @throws IOException if there is a problem while searching for the module.
      */
     private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
-        Name pkgName;
-        if (tree.getModuleDecl() != null) {
-            pkgName = null;
-        } else {
-            JCPackageDecl pkg = tree.getPackage();
-            pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid);
-        }
-
+        String pkgName = getPackageName(tree);
         JavaFileObject fo = tree.sourcefile;
 
-        // For now, just check module source path.
-        // We may want to check source path as well.
         Location loc =
                 fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH,
-                                                 fo, (pkgName == null) ? null : pkgName.toString());
+                                                 fo, (pkgName == null) ? null : pkgName);
         if (loc == null) {
             Location sourceOutput = fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT) ?
                     StandardLocation.SOURCE_OUTPUT : StandardLocation.CLASS_OUTPUT;
             loc =
                 fileManager.getLocationForModule(sourceOutput,
-                                                 fo, (pkgName == null) ? null : pkgName.toString());
+                                                 fo, (pkgName == null) ? null : pkgName);
         }
         return loc;
     }
 
-    private void checkSpecifiedModule(List<JCCompilationUnit> trees, JCDiagnostic.Error error) {
+    private void checkSpecifiedModule(List<JCCompilationUnit> trees, String moduleOverride, JCDiagnostic.Error error) {
         if (moduleOverride != null) {
             JavaFileObject prev = log.useSource(trees.head.sourcefile);
             try {
@@ -1594,8 +1659,8 @@
     }
 
     public void newRound() {
+        allModules = null;
         rootModules = null;
-        allModules = null;
         warnedMissing.clear();
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Mon Feb 13 09:37:26 2017 +0100
@@ -980,7 +980,7 @@
     public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
         checkModuleOrientedOrOutputLocation(location);
         if (!(fo instanceof PathFileObject))
-            throw new IllegalArgumentException(fo.getName());
+            return null;
         int depth = 1; // allow 1 for filename
         if (pkgName != null && !pkgName.isEmpty()) {
             depth += 1;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Feb 13 09:37:26 2017 +0100
@@ -432,7 +432,7 @@
         /**
          * @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String)
          */
-        Location getLocationForModule(Path dir) {
+        Location getLocationForModule(Path dir) throws IOException  {
             return null;
         }
 
@@ -545,7 +545,7 @@
                 l = new ModuleLocationHandler(location.getName() + "[" + name + "]",
                         name,
                         Collections.singleton(out),
-                        true, false);
+                        true);
                 moduleLocations.put(name, l);
                 pathLocations.put(out.toAbsolutePath(), l);
            }
@@ -864,29 +864,14 @@
         protected final String name;
         protected final String moduleName;
         protected final Collection<Path> searchPath;
-        protected final Collection<Path> searchPathWithOverrides;
         protected final boolean output;
 
         ModuleLocationHandler(String name, String moduleName, Collection<Path> searchPath,
-                boolean output, boolean allowOverrides) {
+                boolean output) {
             this.name = name;
             this.moduleName = moduleName;
             this.searchPath = searchPath;
             this.output = output;
-
-            if (allowOverrides && patchMap != null) {
-                SearchPath mPatch = patchMap.get(moduleName);
-                if (mPatch != null) {
-                    SearchPath sp = new SearchPath();
-                    sp.addAll(mPatch);
-                    sp.addAll(searchPath);
-                    searchPathWithOverrides = sp;
-                } else {
-                    searchPathWithOverrides = searchPath;
-                }
-            } else {
-                searchPathWithOverrides = searchPath;
-            }
         }
 
         @Override @DefinedBy(Api.COMPILER)
@@ -909,7 +894,7 @@
             // For now, we always return searchPathWithOverrides. This may differ from the
             // JVM behavior if there is a module-info.class to be found in the overriding
             // classes.
-            return searchPathWithOverrides;
+            return searchPath;
         }
 
         @Override // defined by LocationHandler
@@ -1068,7 +1053,7 @@
                         String name = location.getName()
                                 + "[" + pathIndex + ":" + moduleName + "]";
                         ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
-                                Collections.singleton(path), false, true);
+                                Collections.singleton(path), false);
                         return Collections.singleton(l);
                     } catch (ModuleNameReader.BadClassFile e) {
                         log.error(Errors.LocnBadModuleInfo(path));
@@ -1093,7 +1078,7 @@
                     String name = location.getName()
                             + "[" + pathIndex + "." + (index++) + ":" + moduleName + "]";
                     ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
-                            Collections.singleton(modulePath), false, true);
+                            Collections.singleton(modulePath), false);
                     result.add(l);
                 }
                 return result;
@@ -1110,7 +1095,7 @@
                 String name = location.getName()
                         + "[" + pathIndex + ":" + moduleName + "]";
                 ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
-                        Collections.singleton(modulePath), false, true);
+                        Collections.singleton(modulePath), false);
                 return Collections.singleton(l);
             }
 
@@ -1277,7 +1262,7 @@
             pathLocations = new LinkedHashMap<>();
             map.forEach((k, v) -> {
                 String name = location.getName() + "[" + k + "]";
-                ModuleLocationHandler h = new ModuleLocationHandler(name, k, v, false, false);
+                ModuleLocationHandler h = new ModuleLocationHandler(name, k, v, false);
                 moduleLocations.put(k, h);
                 v.forEach(p -> pathLocations.put(normalize(p), h));
             });
@@ -1417,6 +1402,7 @@
         private Path systemJavaHome;
         private Path modules;
         private Map<String, ModuleLocationHandler> systemModules;
+        private Map<Path, Location> pathLocations;
 
         SystemModulesLocationHandler() {
             super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM);
@@ -1491,6 +1477,12 @@
         }
 
         @Override
+        Location getLocationForModule(Path dir) throws IOException {
+            initSystemModules();
+            return (pathLocations == null) ? null : pathLocations.get(dir);
+        }
+
+        @Override
         Iterable<Set<Location>> listLocationsForModules() throws IOException {
             initSystemModules();
             Set<Location> locns = new LinkedHashSet<>();
@@ -1544,18 +1536,96 @@
             }
 
             systemModules = new LinkedHashMap<>();
+            pathLocations = new LinkedHashMap<>();
             try (DirectoryStream<Path> stream = Files.newDirectoryStream(modules, Files::isDirectory)) {
                 for (Path entry : stream) {
                     String moduleName = entry.getFileName().toString();
                     String name = location.getName() + "[" + moduleName + "]";
                     ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName,
-                            Collections.singleton(entry), false, true);
+                            Collections.singleton(entry), false);
                     systemModules.put(moduleName, h);
+                    pathLocations.put(normalize(entry), h);
                 }
             }
         }
     }
 
+    private class PatchModulesLocationHandler extends BasicLocationHandler {
+        private final Map<String, ModuleLocationHandler> moduleLocations = new HashMap<>();
+        private final Map<Path, Location> pathLocations = new HashMap<>();
+
+        PatchModulesLocationHandler() {
+            super(StandardLocation.PATCH_MODULE_PATH, Option.PATCH_MODULE);
+        }
+
+        @Override
+        boolean handleOption(Option option, String value) {
+            if (!options.contains(option)) {
+                return false;
+            }
+
+            // Allow an extended syntax for --patch-module consisting of a series
+            // of values separated by NULL characters. This is to facilitate
+            // supporting deferred file manager options on the command line.
+            // See Option.PATCH_MODULE for the code that composes these multiple
+            // values.
+            for (String v : value.split("\0")) {
+                int eq = v.indexOf('=');
+                if (eq > 0) {
+                    String moduleName = v.substring(0, eq);
+                    SearchPath mPatchPath = new SearchPath()
+                            .addFiles(v.substring(eq + 1));
+                    String name = location.getName() + "[" + moduleName + "]";
+                    ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName, mPatchPath, false);
+                    moduleLocations.put(moduleName, h);
+                    for (Path r : mPatchPath) {
+                        pathLocations.put(normalize(r), h);
+                    }
+                } else {
+                    // Should not be able to get here;
+                    // this should be caught and handled in Option.PATCH_MODULE
+                    log.error(Errors.LocnInvalidArgForXpatch(value));
+                }
+            }
+
+            return true;
+        }
+
+        @Override
+        boolean isSet() {
+            return !moduleLocations.isEmpty();
+        }
+
+        @Override
+        Collection<Path> getPaths() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        void setPaths(Iterable<? extends Path> files) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        Location getLocationForModule(String name) throws IOException {
+            return moduleLocations.get(name);
+        }
+
+        @Override
+        Location getLocationForModule(Path dir) throws IOException {
+            return (pathLocations == null) ? null : pathLocations.get(dir);
+        }
+
+        @Override
+        Iterable<Set<Location>> listLocationsForModules() throws IOException {
+            Set<Location> locns = new LinkedHashSet<>();
+            for (Location l: moduleLocations.values())
+                locns.add(l);
+            return Collections.singleton(locns);
+        }
+
+    }
+
     Map<Location, LocationHandler> handlersForLocation;
     Map<Option, LocationHandler> handlersForOption;
 
@@ -1573,6 +1643,7 @@
             new OutputLocationHandler(StandardLocation.SOURCE_OUTPUT, Option.S),
             new OutputLocationHandler(StandardLocation.NATIVE_HEADER_OUTPUT, Option.H),
             new ModuleSourcePathLocationHandler(),
+            new PatchModulesLocationHandler(),
             // TODO: should UPGRADE_MODULE_PATH be merged with SYSTEM_MODULES?
             new ModulePathLocationHandler(StandardLocation.UPGRADE_MODULE_PATH, Option.UPGRADE_MODULE_PATH),
             new ModulePathLocationHandler(StandardLocation.MODULE_PATH, Option.MODULE_PATH),
@@ -1587,51 +1658,9 @@
         }
     }
 
-    private Map<String, SearchPath> patchMap;
-
     boolean handleOption(Option option, String value) {
-        switch (option) {
-            case PATCH_MODULE:
-                if (value == null) {
-                    patchMap = null;
-                } else {
-                    // Allow an extended syntax for --patch-module consisting of a series
-                    // of values separated by NULL characters. This is to facilitate
-                    // supporting deferred file manager options on the command line.
-                    // See Option.PATCH_MODULE for the code that composes these multiple
-                    // values.
-                    for (String v : value.split("\0")) {
-                        int eq = v.indexOf('=');
-                        if (eq > 0) {
-                            String mName = v.substring(0, eq);
-                            SearchPath mPatchPath = new SearchPath()
-                                    .addFiles(v.substring(eq + 1));
-                            boolean ok = true;
-                            for (Path p : mPatchPath) {
-                                Path mi = p.resolve("module-info.class");
-                                if (Files.exists(mi)) {
-                                    log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(mi));
-                                    ok = false;
-                                }
-                            }
-                            if (ok) {
-                                if (patchMap == null) {
-                                    patchMap = new LinkedHashMap<>();
-                                }
-                                patchMap.put(mName, mPatchPath);
-                            }
-                        } else {
-                            // Should not be able to get here;
-                            // this should be caught and handled in Option.PATCH_MODULE
-                            log.error(Errors.LocnInvalidArgForXpatch(value));
-                        }
-                    }
-                }
-                return true;
-            default:
-                LocationHandler h = handlersForOption.get(option);
-                return (h == null ? false : h.handleOption(option, value));
-        }
+        LocationHandler h = handlersForOption.get(option);
+        return (h == null ? false : h.handleOption(option, value));
     }
 
     boolean hasLocation(Location location) {
@@ -1670,7 +1699,7 @@
         return (h == null ? null : h.getLocationForModule(name));
     }
 
-    Location getLocationForModule(Location location, Path dir) {
+    Location getLocationForModule(Location location, Path dir) throws IOException {
         LocationHandler h = getHandler(location);
         return (h == null ? null : h.getLocationForModule(dir));
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Mon Feb 13 09:37:26 2017 +0100
@@ -598,9 +598,6 @@
                     && !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) {
                 log.error(Errors.NoOutputDir);
             }
-            if (options.isSet(Option.XMODULE)) {
-                log.error(Errors.XmoduleNoModuleSourcepath);
-            }
         }
 
         if (fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH) &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Feb 13 09:37:26 2017 +0100
@@ -1450,6 +1450,11 @@
             return;
         }
 
+        if (!modules.multiModuleMode && env.toplevel.modle != modules.getDefaultModule()) {
+            //can only generate classfiles for a single module:
+            return;
+        }
+
         if (compileStates.isDone(env, CompileState.LOWER)) {
             results.addAll(desugaredEnvs.get(env));
             return;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Mon Feb 13 09:37:26 2017 +0100
@@ -579,7 +579,7 @@
         }
     },
 
-    XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
+    XMODULE("-Xmodule:", "opt.arg.module", "opt.module", HIDDEN, BASIC) {
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             String prev = helper.get(XMODULE);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Feb 13 09:37:26 2017 +0100
@@ -1292,7 +1292,7 @@
 compiler.warn.outdir.is.in.exploded.module=\
     the output directory is within an exploded module: {0}
 
-# 0: path
+# 0: file object
 compiler.err.locn.module-info.not.allowed.on.patch.path=\
     module-info.class not allowed on patch path: {0}
 
@@ -2957,14 +2957,20 @@
 compiler.err.module.decl.sb.in.module-info.java=\
     module declarations should be in a file named module-info.java
 
-compiler.err.module-info.with.xmodule.sourcepath=\
-    illegal combination of -Xmodule and module-info on sourcepath
-
-compiler.err.module-info.with.xmodule.classpath=\
-    illegal combination of -Xmodule and module-info on classpath
-
-compiler.err.xmodule.no.module.sourcepath=\
-    illegal combination of -Xmodule and --module-source-path
+compiler.err.module-info.with.patched.module.sourcepath=\
+    compiling a module patch with module-info on sourcepath
+
+compiler.err.module-info.with.patched.module.classoutput=\
+    compiling a module patch with module-info on class output
+
+# 0: set of string
+compiler.err.too.many.patched.modules=\
+    too many patched modules ({0}), use --module-source-path
+
+# 0: name, 1: name
+compiler.err.file.patched.and.msp=\
+    file accessible from both --patch-module and --module-source-path, \
+    but belongs to a different module on each path: {0}, {1}
 
 compiler.err.processorpath.no.processormodulepath=\
     illegal combination of -processorpath and --processor-module-path
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java	Mon Feb 13 09:37:26 2017 +0100
@@ -204,13 +204,6 @@
         }
     },
 
-    XMODULE("-Xmodule:", false) {
-        @Override
-        public void process(Helper helper, String arg) throws InvalidValueException {
-            Option.XMODULE.process(helper.getOptionHelper(), arg);
-        }
-    },
-
     PATCH_MODULE("--patch-module", true) {
         @Override
         public void process(Helper helper, String arg) throws InvalidValueException {
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Mon Feb 13 09:37:26 2017 +0100
@@ -82,7 +82,6 @@
 \                                   Specify additional modules to be considered as required by a\n\
 \                                   given module. <other-module> may be ALL-UNNAMED to require\n\
 \                                   the unnamed module.\n\
-\  -Xmodule:<module-name>           Specify a module to which the classes being compiled belong.\n\
 \  --patch-module <module>=<file>(:<file>)*\n\
 \                                   Override or augment a module with classes and resources\n\
 \                                   in JAR files or directories\n
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Mon Feb 13 09:37:26 2017 +0100
@@ -181,13 +181,6 @@
         }
     },
 
-    XMODULE("-Xmodule:", EXTENDED, false) {
-        @Override
-        public void process(Helper helper, String arg) throws InvalidValueException {
-            Option.XMODULE.process(helper.getOptionHelper(), arg);
-        }
-    },
-
     PATCH_MODULE("--patch-module", EXTENDED, true) {
         @Override
         public void process(Helper helper, String arg) throws InvalidValueException {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Mon Feb 13 09:37:26 2017 +0100
@@ -238,11 +238,6 @@
     given module. <other-module> may be ALL-UNNAMED to require\n\
     the unnamed module.
 
-main.opt.Xmodule.arg=\
-    <module-name>
-main.opt.Xmodule.desc=\
-    Specify a module to which the classes being compiled belong
-
 main.opt.patch.module.arg=\
     <module>=<file>(:<file>)*
 main.opt.patch.module.desc=\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Mon Feb 13 09:37:26 2017 +0100
@@ -30,8 +30,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.net.URI;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
@@ -71,10 +69,6 @@
 
     private final JShell proc;
 
-    // Upcoming Jigsaw
-    private Method inferModuleNameMethod = null;
-    private Method listLocationsForModulesMethod = null;
-
     Iterable<? extends Path> getLocationAsPaths(Location loc) {
         return this.stdFileManager.getLocationAsPaths(loc);
     }
@@ -186,45 +180,6 @@
         return new SourceMemoryJavaFileObject(origin, name, code);
     }
 
-    // Make compatible with Jigsaw
-    @Override
-    public String inferModuleName(Location location) {
-        try {
-            if (inferModuleNameMethod == null) {
-                inferModuleNameMethod = JavaFileManager.class.getDeclaredMethod("inferModuleName", Location.class);
-            }
-            @SuppressWarnings("unchecked")
-            String result = (String) inferModuleNameMethod.invoke(stdFileManager, location);
-            return result;
-        } catch (NoSuchMethodException | SecurityException ex) {
-            throw new InternalError("Cannot lookup JavaFileManager method", ex);
-        } catch (IllegalAccessException |
-                IllegalArgumentException |
-                InvocationTargetException ex) {
-            throw new InternalError("Cannot invoke JavaFileManager method", ex);
-        }
-    }
-
-    // Make compatible with Jigsaw
-    @Override
-    public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
-        try {
-            if (listLocationsForModulesMethod == null) {
-                listLocationsForModulesMethod = JavaFileManager.class.getDeclaredMethod("listLocationsForModules", Location.class);
-            }
-            @SuppressWarnings("unchecked")
-            Iterable<Set<Location>> result = (Iterable<Set<Location>>) listLocationsForModulesMethod.invoke(stdFileManager, location);
-            return result;
-        } catch (NoSuchMethodException | SecurityException ex) {
-            throw new InternalError("Cannot lookup JavaFileManager method", ex);
-        } catch (IllegalAccessException |
-                IllegalArgumentException |
-                InvocationTargetException ex) {
-            throw new InternalError("Cannot invoke JavaFileManager method", ex);
-        }
-    }
-
-
     /**
      * Returns a class loader for loading plug-ins from the given location. For
      * example, to load annotation processors, a compiler will request a class
@@ -584,6 +539,26 @@
                 ", sibling: " + sibling);
     }
 
+    @Override
+    public Location getLocationForModule(Location location, String moduleName) throws IOException {
+        return stdFileManager.getLocationForModule(location, moduleName);
+    }
+
+    @Override
+    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        return stdFileManager.getLocationForModule(location, fo, pkgName);
+    }
+
+    @Override
+    public String inferModuleName(Location location) throws IOException {
+        return stdFileManager.inferModuleName(location);
+    }
+
+    @Override
+    public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
+        return stdFileManager.listLocationsForModules(location);
+    }
+
     /**
      * Flushes any resources opened for output by this file manager
      * directly or indirectly.  Flushing a closed file manager has no
--- a/langtools/test/tools/javac/6627362/T6627362.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/6627362/T6627362.java	Mon Feb 13 09:37:26 2017 +0100
@@ -68,9 +68,9 @@
         // compile and disassemble E.java, using modified Object.java,
         // check for reference to System.arraycopy
         File x = new File(testSrc, "x");
-        String[] jcArgs = { "-d", ".", "-Xmodule:java.base",
+        String[] jcArgs = { "-d", ".", "--patch-module", "java.base=" + x.getAbsolutePath(),
                             new File(x, "E.java").getPath(),
-                            new File(x, "Object.java").getPath()};
+                            new File(new File(new File(x, "java"), "lang"), "Object.java").getPath()};
         compile(jcArgs);
 
         String[] jpArgs = { "-classpath", ".", "-c", "E" };
--- a/langtools/test/tools/javac/6627362/x/Object.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, 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.
- */
-
-package java.lang;
-
-/*
- * Object, without clone()
- */
-public class Object {
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6627362/x/java/lang/Object.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007, 2008, 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.
+ */
+
+package java.lang;
+
+/*
+ * Object, without clone()
+ */
+public class Object {
+}
--- a/langtools/test/tools/javac/diags/Example.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/diags/Example.java	Mon Feb 13 09:37:26 2017 +0100
@@ -63,6 +63,7 @@
         procFiles = new ArrayList<File>();
         srcPathFiles = new ArrayList<File>();
         moduleSourcePathFiles = new ArrayList<File>();
+        patchModulePathFiles = new ArrayList<File>();
         modulePathFiles = new ArrayList<File>();
         classPathFiles = new ArrayList<File>();
         additionalFiles = new ArrayList<File>();
@@ -88,6 +89,9 @@
                 } else if (files == srcFiles && c.getName().equals("modulesourcepath")) {
                     moduleSourcePathDir = c;
                     findFiles(c, moduleSourcePathFiles);
+                } else if (files == srcFiles && c.getName().equals("patchmodule")) {
+                    patchModulePathDir = c;
+                    findFiles(c, patchModulePathFiles);
                 } else if (files == srcFiles && c.getName().equals("additional")) {
                     additionalFilesDir = c;
                     findFiles(c, additionalFiles);
@@ -272,6 +276,16 @@
             files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
         }
 
+        if (patchModulePathDir != null) {
+            for (File mod : patchModulePathDir.listFiles()) {
+                opts.add("--patch-module");
+                opts.add(mod.getName() + "=" + mod.getPath());
+            }
+            files = new ArrayList<>();
+            files.addAll(patchModulePathFiles);
+            files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
+        }
+
         if (additionalFiles.size() > 0) {
             List<String> sOpts = Arrays.asList("-d", classesDir.getPath());
             new Jsr199Compiler(verbose).run(null, null, false, sOpts, additionalFiles);
@@ -343,9 +357,11 @@
     List<File> procFiles;
     File srcPathDir;
     File moduleSourcePathDir;
+    File patchModulePathDir;
     File additionalFilesDir;
     List<File> srcPathFiles;
     List<File> moduleSourcePathFiles;
+    List<File> patchModulePathFiles;
     List<File> modulePathFiles;
     List<File> classPathFiles;
     List<File> additionalFiles;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Mon Feb 13 09:37:26 2017 +0100
@@ -5,6 +5,7 @@
 compiler.err.cant.read.file                             # (apt.JavaCompiler?)
 compiler.err.cant.select.static.class.from.param.type
 compiler.err.dc.unterminated.string                     # cannot happen
+compiler.err.file.patched.and.msp                       # needs the same dir on --module-source-path and --patch-module
 compiler.err.illegal.char.for.encoding
 compiler.err.invalid.repeatable.annotation              # should not happen
 compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/ModuleInfoWithPatchedModuleClassoutput.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+// key: compiler.err.module-info.with.patched.module.classoutput
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/additional/module-info.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+module mod {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/patchmodule/java.compiler/javax/lang/model/element/Extra.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+package javax.lang.model.element;
+
+public interface Extra {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/ModuleInfoWithPatchedModule.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+// key: compiler.err.module-info.with.patched.module.sourcepath
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/patchmodule/java.compiler/javax/lang/model/element/Extra.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+package javax.lang.model.element;
+
+public interface Extra {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/patchmodule/java.compiler/module-info.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+module java.compiler {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXModuleSourcePath/Extra.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-// key: compiler.err.module-info.with.xmodule.sourcepath
-// options: -Xmodule:java.compiler
-
-package javax.lang.model.element;
-
-public interface Extra {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXModuleSourcePath/module-info.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-module java.compiler {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXmoduleClasspath/ModuleInfoWithXmoduleClasspath.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-// key: compiler.err.module-info.with.xmodule.classpath
-// options: -Xmodule:java.compiler
-
-package javax.lang.model.element;
-
-public interface ModuleInfoWithXModuleClasspath {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXmoduleClasspath/additional/module-info.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-module mod {}
--- a/langtools/test/tools/javac/diags/examples/NoSuperclass.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2010, 2016, 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.
- */
-
-// key: compiler.err.no.superclass
-// options: -Xmodule:java.base
-
-package java.lang;
-
-class Object {
-    public Object() {
-        super();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoSuperclass/NoSuperclass.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010, 2017, 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.
+ */
+
+// key: compiler.err.no.superclass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoSuperclass/patchmodule/java.base/java/lang/Object.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, 2017, 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.
+ */
+
+package java.lang;
+
+class Object {
+    public Object() {
+        super();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TooManyPatchedModules/TooManyPatchedModules.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// key: compiler.err.too.many.patched.modules
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TooManyPatchedModules/patchmodule/java.compiler/p/C.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package p;
+
+class C {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TooManyPatchedModules/patchmodule/jdk.compiler/p/C.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package p;
+
+class C {}
--- a/langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-// key: compiler.err.xmodule.no.module.sourcepath
-// options: -Xmodule:java.compiler --module-source-path src
-
-class XModuleWithModulePath {}
--- a/langtools/test/tools/javac/meth/BadPolySig.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-/*
- * @test
- * @bug 8168774
- * @summary Polymorhic signature method check crashes javac
- * @compile -Xmodule:java.base BadPolySig.java
- */
-
-package java.lang.invoke;
-
-class MethodHandle {
-    native Object m();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/BadPolySig/BadPolySig.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 2017, 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
+ * @bug 8168774
+ * @summary Polymorhic signature method check crashes javac
+ * @modules jdk.compiler
+ * @compile/module=java.base java/lang/invoke/MethodHandle.java
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/BadPolySig/java.base/java/lang/invoke/MethodHandle.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+package java.lang.invoke;
+
+class MethodHandle {
+    native Object m();
+}
--- a/langtools/test/tools/javac/modules/AddLimitMods.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/modules/AddLimitMods.java	Mon Feb 13 09:37:26 2017 +0100
@@ -293,7 +293,7 @@
         }
 
         actual = new JavacTask(tb)
-                   .options("-Xmodule:java.base",
+                   .options("--patch-module", "java.base=" + cpSrc.toString(),
                             "-XDrawDiagnostics",
                             "--add-modules", "ALL-MODULE-PATH")
                    .outdir(cpOut)
--- a/langtools/test/tools/javac/modules/AddReadsTest.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/modules/AddReadsTest.java	Mon Feb 13 09:37:26 2017 +0100
@@ -217,7 +217,7 @@
         new JavacTask(tb)
           .options("--class-path", jar.toString(),
                    "--add-reads", "java.base=ALL-UNNAMED",
-                   "-Xmodule:java.base")
+                   "--patch-module", "java.base=" + src)
           .outdir(classes)
           .files(src.resolve("impl").resolve("Impl.java"))
           .run()
@@ -237,7 +237,7 @@
         new JavacTask(tb)
           .options("--add-modules", "java.desktop",
                    "--add-reads", "java.base=java.desktop",
-                   "-Xmodule:java.base")
+                   "--patch-module", "java.base=" + src)
           .outdir(classes)
           .files(findJavaFiles(src))
           .run()
@@ -304,7 +304,7 @@
 
         new JavacTask(tb)
           .options("--add-reads", "m1x=ALL-UNNAMED",
-                   "-Xmodule:m1x",
+                   "--patch-module", "m1x=" + unnamedSrc,
                    "--module-path", classes.toString())
           .outdir(unnamedClasses)
           .files(findJavaFiles(unnamedSrc))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/CompileModulePatchTest.java	Mon Feb 13 09:37:26 2017 +0100
@@ -0,0 +1,694 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ * @bug 8173777
+ * @summary tests for multi-module mode compilation
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.code
+ *      jdk.compiler/com.sun.tools.javac.main
+ *      jdk.compiler/com.sun.tools.javac.processing
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
+ * @run main CompileModulePatchTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.Task.Expect;
+
+public class CompileModulePatchTest extends ModuleTestBase {
+
+    public static void main(String... args) throws Exception {
+        new CompileModulePatchTest().runTests();
+    }
+
+    @Test
+    public void testCorrectModulePatch(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("--patch-module", "java.compiler=" + src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.isEmpty())
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testCorrectModulePatchMultiModule(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        Path m1 = src.resolve("m1");
+        tb.writeJavaFiles(m1, "package javax.lang.model.element; public interface Extra extends Element { }");
+        Path m2 = src.resolve("m2");
+        tb.writeJavaFiles(m2, "package com.sun.source.tree; public interface Extra extends Tree { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("--patch-module", "java.compiler=" + m1.toString(),
+                         "--patch-module", "jdk.compiler=" + m2.toString(),
+                         "--module-source-path", "dummy")
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.isEmpty())
+            throw new Exception("expected output not found: " + log);
+
+        checkFileExists(classes, "java.compiler/javax/lang/model/element/Extra.class");
+        checkFileExists(classes, "jdk.compiler/com/sun/source/tree/Extra.class");
+    }
+
+    @Test
+    public void testCorrectModulePatchMultiModule2(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        Path m1 = src.resolve("m1");
+        tb.writeJavaFiles(m1,
+                          "package javax.lang.model.element; public interface Extra extends Element { }");
+        Path m2 = src.resolve("m2");
+        tb.writeJavaFiles(m2,
+                          "package com.sun.source.tree; public interface Extra extends Tree { }");
+        Path msp = base.resolve("msp");
+        Path m3 = msp.resolve("m3x");
+        tb.writeJavaFiles(m3,
+                          "module m3x { }",
+                          "package m3; public class Test { }");
+        Path m4 = msp.resolve("m4x");
+        tb.writeJavaFiles(m4,
+                          "module m4x { }",
+                          "package m4; public class Test { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("--patch-module", "java.compiler=" + m1.toString(),
+                         "--patch-module", "jdk.compiler=" + m2.toString(),
+                         "--module-source-path", msp.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src, msp))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.isEmpty())
+            throw new Exception("expected output not found: " + log);
+
+        checkFileExists(classes, "java.compiler/javax/lang/model/element/Extra.class");
+        checkFileExists(classes, "jdk.compiler/com/sun/source/tree/Extra.class");
+        checkFileExists(classes, "m3x/m3/Test.class");
+        checkFileExists(classes, "m4x/m4/Test.class");
+    }
+
+    @Test
+    public void testPatchModuleModuleSourcePathConflict(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        Path m1 = src.resolve("m1x");
+        tb.writeJavaFiles(m1,
+                          "module m1x { }",
+                          "package m1; public class Test { }");
+        Path m2 = src.resolve("m2x");
+        tb.writeJavaFiles(m2,
+                          "module m2x { }",
+                          "package m2; public class Test { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("--patch-module", "m1x=" + m2.toString(),
+                         "--module-source-path", src.toString(),
+                         "-XDrawDiagnostics")
+                .outdir(classes)
+                .files(findJavaFiles(src.resolve("m1x").resolve("m1"),
+                                     src.resolve("m2x").resolve("m2")))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expectedOut = Arrays.asList(
+                "Test.java:1:1: compiler.err.file.patched.and.msp: m1x, m2x",
+                "1 error"
+        );
+
+        if (!expectedOut.equals(log))
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testSourcePath(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }");
+        Path srcPath = base.resolve("src-path");
+        tb.writeJavaFiles(srcPath, "package javax.lang.model.element; interface Other { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("--patch-module", "java.compiler=" + src.toString(),
+                         "-sourcepath", srcPath.toString(),
+                         "-XDrawDiagnostics")
+                .outdir(classes)
+                .files(src.resolve("javax/lang/model/element/Extra.java"))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expectedOut = Arrays.asList(
+                "Extra.java:1:75: compiler.err.cant.resolve: kindname.class, Other, , ",
+                "1 error"
+        );
+
+        if (!expectedOut.equals(log))
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testClassPath(Path base) throws Exception {
+        Path cpSrc = base.resolve("cpSrc");
+        tb.writeJavaFiles(cpSrc, "package p; public interface Other { }");
+        Path cpClasses = base.resolve("cpClasses");
+        tb.createDirectories(cpClasses);
+
+        String cpLog = new JavacTask(tb)
+                .outdir(cpClasses)
+                .files(findJavaFiles(cpSrc))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!cpLog.isEmpty())
+            throw new Exception("expected output not found: " + cpLog);
+
+        Path src = base.resolve("src");
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, p.Other { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("--patch-module", "java.compiler=" + src.toString(),
+                         "--class-path", cpClasses.toString(),
+                         "-XDrawDiagnostics")
+                .outdir(classes)
+                .files(src.resolve("javax/lang/model/element/Extra.java"))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expectedOut = Arrays.asList(
+                "Extra.java:1:76: compiler.err.doesnt.exist: p",
+                "1 error"
+        );
+
+        if (!expectedOut.equals(log))
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "module java.compiler {}",
+                          "package javax.lang.model.element; public interface Extra { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log;
+        List<String> expected;
+
+        log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--patch-module", "java.compiler=" + src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.sourcepath",
+                                 "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found: " + log);
+
+        //multi-module mode:
+        log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--patch-module", "java.compiler=" + src.toString(),
+                         "--module-source-path", "dummy")
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.java",
+                                 "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testNoModuleInfoInClassOutput(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path srcMod = base.resolve("src-mod");
+        tb.writeJavaFiles(srcMod,
+                          "module mod {}");
+        Path classes = base.resolve("classes").resolve("java.compiler");
+        tb.createDirectories(classes);
+
+        String logMod = new JavacTask(tb)
+                .options()
+                .outdir(classes)
+                .files(findJavaFiles(srcMod))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!logMod.isEmpty())
+            throw new Exception("unexpected output found: " + logMod);
+
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "package javax.lang.model.element; public interface Extra { }");
+        tb.createDirectories(classes);
+
+        List<String> log;
+        List<String> expected;
+
+        log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--patch-module", "java.compiler=" + src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.classoutput",
+                                 "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found: " + log);
+
+        log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--patch-module", "java.compiler=" + src.toString(),
+                         "--module-source-path", "dummy")
+                .outdir(classes.getParent())
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.class",
+                                 "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testWithModulePath(Path base) throws Exception {
+        Path modSrc = base.resolve("modSrc");
+        Path modules = base.resolve("modules");
+        new ModuleBuilder(tb, "m1")
+                .classes("package pkg1; public interface E { }")
+                .build(modSrc, modules);
+
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }");
+
+        new JavacTask(tb, Task.Mode.CMDLINE)
+                .options("--module-path", modules.toString(),
+                        "--patch-module", "m1=" + src.toString())
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll();
+
+        //checks module bounds still exist
+        new ModuleBuilder(tb, "m2")
+                .classes("package pkg2; public interface D { }")
+                .build(modSrc, modules);
+
+        Path src2 = base.resolve("src2");
+        tb.writeJavaFiles(src2, "package p; interface A extends pkg2.D { }");
+
+        List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
+                .options("-XDrawDiagnostics",
+                        "--module-path", modules.toString(),
+                        "--patch-module", "m1=" + src2.toString())
+                .files(findJavaFiles(src2))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList("A.java:1:32: compiler.err.package.not.visible: pkg2, (compiler.misc.not.def.access.does.not.read: m1, pkg2, m2)",
+                "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @Test
+    public void testWithUpgradeModulePath(Path base) throws Exception {
+        Path modSrc = base.resolve("modSrc");
+        Path modules = base.resolve("modules");
+        new ModuleBuilder(tb, "m1")
+                .classes("package pkg1; public interface E { }")
+                .build(modSrc, modules);
+
+        Path upgrSrc = base.resolve("upgradeSrc");
+        Path upgrade = base.resolve("upgrade");
+        new ModuleBuilder(tb, "m1")
+                .classes("package pkg1; public interface D { }")
+                .build(upgrSrc, upgrade);
+
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "package p; interface A extends pkg1.D { }");
+
+        new JavacTask(tb, Task.Mode.CMDLINE)
+                .options("--module-path", modules.toString(),
+                        "--upgrade-module-path", upgrade.toString(),
+                        "--patch-module", "m1=" + src.toString())
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testUnnamedIsolation(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path sourcePath = base.resolve("source-path");
+        tb.writeJavaFiles(sourcePath, "package src; public class Src {}");
+
+        Path classPathSrc = base.resolve("class-path-src");
+        tb.writeJavaFiles(classPathSrc, "package cp; public class CP { }");
+        Path classPath = base.resolve("classPath");
+        tb.createDirectories(classPath);
+
+        String cpLog = new JavacTask(tb)
+                .outdir(classPath)
+                .files(findJavaFiles(classPathSrc))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!cpLog.isEmpty())
+            throw new Exception("expected output not found: " + cpLog);
+
+        Path modulePathSrc = base.resolve("module-path-src");
+        tb.writeJavaFiles(modulePathSrc,
+                          "module m {}",
+                          "package m; public class M {}");
+        Path modulePath = base.resolve("modulePath");
+        tb.createDirectories(modulePath.resolve("m"));
+
+        String modLog = new JavacTask(tb)
+                .outdir(modulePath.resolve("m"))
+                .files(findJavaFiles(modulePathSrc))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!modLog.isEmpty())
+            throw new Exception("expected output not found: " + modLog);
+
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "package m; public class Extra { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("--patch-module", "m=" + sourcePath.toString(),
+                         "--class-path", classPath.toString(),
+                         "--source-path", sourcePath.toString(),
+                         "--module-path", modulePath.toString(),
+                         "--processor-path", System.getProperty("test.classes"),
+                         "-XDaccessInternalAPI=true",
+                         "-processor", CheckModuleContentProcessing.class.getName())
+                .outdir(classes)
+                .files(findJavaFiles(sourcePath))
+                .run()
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.isEmpty())
+            throw new Exception("expected output not found: " + log);
+    }
+
+    @SupportedAnnotationTypes("*")
+    public static final class CheckModuleContentProcessing extends AbstractProcessor {
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            Symtab syms = Symtab.instance(((JavacProcessingEnvironment) processingEnv).getContext());
+            Elements elements = processingEnv.getElementUtils();
+            ModuleElement unnamedModule = syms.unnamedModule;
+            ModuleElement mModule = elements.getModuleElement("m");
+
+            assertNonNull("mModule found", mModule);
+            assertNonNull("src.Src from m", elements.getTypeElement(mModule, "src.Src"));
+            assertNull("cp.CP not from m", elements.getTypeElement(mModule, "cp.CP"));
+            assertNull("src.Src not from unnamed", elements.getTypeElement(unnamedModule, "src.Src"));
+            assertNonNull("cp.CP from unnamed", elements.getTypeElement(unnamedModule, "cp.CP"));
+
+            return false;
+        }
+
+        @Override
+        public SourceVersion getSupportedSourceVersion() {
+            return SourceVersion.latest();
+        }
+
+        private static void assertNonNull(String msg, Object val) {
+            if (val == null) {
+                throw new AssertionError(msg);
+            }
+        }
+
+        private static void assertNull(String msg, Object val) {
+            if (val != null) {
+                throw new AssertionError(msg);
+            }
+        }
+    }
+
+    @Test
+    public void testSingleModeIncremental(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "package javax.lang.model.element; public interface Extra extends Element { }",
+                          "package javax.lang.model.element; public interface Extra2 extends Extra { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        Thread.sleep(2000); //ensure newer timestamps on classfiles:
+
+        new JavacTask(tb)
+            .options("--patch-module", "java.compiler=" + src.toString())
+            .outdir(classes)
+            .files(findJavaFiles(src))
+            .run()
+            .writeAll()
+            .getOutput(Task.OutputKind.DIRECT);
+
+        List<String> log = new JavacTask(tb)
+            .options("--patch-module", "java.compiler=" + src.toString(),
+                     "-verbose")
+            .outdir(classes)
+            .files(findJavaFiles(src.resolve("javax/lang/model/element/Extra2.java"
+                                    .replace("/", src.getFileSystem().getSeparator()))))
+            .run()
+            .writeAll()
+            .getOutputLines(Task.OutputKind.DIRECT)
+            .stream()
+            .filter(l -> l.contains("parsing"))
+            .collect(Collectors.toList());
+
+        boolean parsesExtra2 = log.stream()
+                                  .anyMatch(l -> l.contains("Extra2.java"));
+        boolean parsesExtra = log.stream()
+                              .anyMatch(l -> l.contains("Extra.java"));
+
+        if (!parsesExtra2 || parsesExtra) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
+    @Test
+    public void testComplexMSPAndPatch(Path base) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path src1 = base.resolve("src1");
+        Path src1ma = src1.resolve("ma");
+        tb.writeJavaFiles(src1ma,
+                          "module ma { exports ma; }",
+                          "package ma; public class C1 { public static void method() { } }",
+                          "package ma.impl; public class C2 { }");
+        Path src1mb = src1.resolve("mb");
+        tb.writeJavaFiles(src1mb,
+                          "module mb { requires ma; }",
+                          "package mb.impl; public class C2 { public static void method() { } }");
+        Path src1mc = src1.resolve("mc");
+        tb.writeJavaFiles(src1mc,
+                          "module mc { }");
+        Path classes1 = base.resolve("classes1");
+        tb.createDirectories(classes1);
+        tb.cleanDirectory(classes1);
+
+        new JavacTask(tb)
+            .options("--module-source-path", src1.toString())
+            .files(findJavaFiles(src1))
+            .outdir(classes1)
+            .run()
+            .writeAll();
+
+        //patching:
+        Path src2 = base.resolve("src2");
+        Path src2ma = src2.resolve("ma");
+        tb.writeJavaFiles(src2ma,
+                          "package ma.impl; public class C2 { public static void extra() { ma.C1.method(); } }",
+                          "package ma.impl; public class C3 { public void test() { C2.extra(); } }");
+        Path src2mb = src2.resolve("mb");
+        tb.writeJavaFiles(src2mb,
+                          "package mb.impl; public class C3 { public void test() { C2.method(); ma.C1.method(); ma.impl.C2.extra(); } }");
+        Path src2mc = src2.resolve("mc");
+        tb.writeJavaFiles(src2mc,
+                          "package mc.impl; public class C2 { public static void test() { } }",
+                          //will require --add-reads ma:
+                          "package mc.impl; public class C3 { public static void test() { ma.impl.C2.extra(); } }");
+        Path src2mt = src2.resolve("mt");
+        tb.writeJavaFiles(src2mt,
+                          "module mt { requires ma; requires mb; }",
+                          "package mt.impl; public class C2 { public static void test() { mb.impl.C2.method(); ma.impl.C2.extra(); } }",
+                          "package mt.impl; public class C3 { public static void test() { C2.test(); mc.impl.C2.test(); } }");
+        Path classes2 = base.resolve("classes2");
+        tb.createDirectories(classes2);
+        tb.cleanDirectory(classes2);
+
+        Thread.sleep(2000); //ensure newer timestamps on classfiles:
+
+        new JavacTask(tb)
+            .options("--module-path", classes1.toString(),
+                     "--patch-module", "ma=" + src2ma.toString(),
+                     "--patch-module", "mb=" + src2mb.toString(),
+                     "--add-exports", "ma/ma.impl=mb",
+                     "--patch-module", "mc=" + src2mc.toString(),
+                     "--add-reads", "mc=ma",
+                     "--add-exports", "ma/ma.impl=mc",
+                     "--add-exports", "ma/ma.impl=mt",
+                     "--add-exports", "mb/mb.impl=mt",
+                     "--add-exports", "mc/mc.impl=mt",
+                     "--add-reads", "mt=mc",
+                     "--module-source-path", src2.toString())
+            .outdir(classes2)
+            .files(findJavaFiles(src2))
+            .run()
+            .writeAll();
+
+        //incremental compilation (C2 mustn't be compiled, C3 must):
+        tb.writeJavaFiles(src2ma,
+                          "package ma.impl; public class C3 { public void test() { ma.C1.method(); C2.extra(); } }");
+        tb.writeJavaFiles(src2mt,
+                          "package mt.impl; public class C3 { public static void test() { mc.impl.C2.test(); C2.test(); } }");
+
+        List<String> log = new JavacTask(tb)
+            .options("--module-path", classes1.toString(),
+                     "--patch-module", "ma=" + src2ma.toString(),
+                     "--patch-module", "mb=" + src2mb.toString(),
+                     "--add-exports", "ma/ma.impl=mb",
+                     "--patch-module", "mc=" + src2mc.toString(),
+                     "--add-reads", "mc=ma",
+                     "--add-exports", "ma/ma.impl=mc",
+                     "--add-exports", "ma/ma.impl=mt",
+                     "--add-exports", "mb/mb.impl=mt",
+                     "--add-exports", "mc/mc.impl=mt",
+                     "--add-reads", "mt=mc",
+                     "--module-source-path", src2.toString(),
+                     "--add-modules", "mc",
+                     "-verbose")
+            .outdir(classes2)
+            .files(src2ma.resolve("ma").resolve("impl").resolve("C3.java"),
+                   src2mt.resolve("mt").resolve("impl").resolve("C3.java"))
+            .run()
+            .writeAll()
+            .getOutputLines(Task.OutputKind.DIRECT)
+            .stream()
+            .filter(l -> l.contains("parsing"))
+            .collect(Collectors.toList());
+
+        boolean parsesC3 = log.stream()
+                              .anyMatch(l -> l.contains("C3.java"));
+        boolean parsesC2 = log.stream()
+                              .anyMatch(l -> l.contains("C2.java"));
+
+        if (!parsesC3 || parsesC2) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
+    private void checkFileExists(Path dir, String path) {
+        Path toCheck = dir.resolve(path.replace("/", dir.getFileSystem().getSeparator()));
+
+        if (!Files.exists(toCheck)) {
+            throw new AssertionError(toCheck.toString() + " does not exist!");
+        }
+    }
+}
--- a/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java	Mon Feb 13 09:37:26 2017 +0100
@@ -177,7 +177,7 @@
         Files.createDirectories(patch);
 
         new JavacTask(tb)
-                .options("-Xmodule:java.base")
+                .options("--patch-module", "java.base=" + patchSrc.toString())
                 .outdir(patch)
                 .sourcepath(patchSrc)
                 .files(findJavaFiles(patchSrc))
--- a/langtools/test/tools/javac/modules/PatchModulesTest.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/modules/PatchModulesTest.java	Mon Feb 13 09:37:26 2017 +0100
@@ -28,7 +28,7 @@
  * @library /tools/lib
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
- *      jdk.compiler/com.sun.tools.javac.file:+open
+ *      jdk.compiler/com.sun.tools.javac.file
  *      jdk.compiler/com.sun.tools.javac.main
  * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
  * @run main PatchModulesTest
@@ -38,21 +38,26 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.lang.reflect.Field;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.AbstractMap.SimpleEntry;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 import javax.tools.ToolProvider;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
 
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.file.BaseFileManager;
 import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.file.Locations;
 
 import static java.util.Arrays.asList;
 
@@ -115,21 +120,29 @@
     void test(List<String> patches, boolean expectOK, String expect) throws Exception {
         JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
         StringWriter sw = new StringWriter();
-        try (PrintWriter pw = new PrintWriter(sw)) {
-            JavacFileManager fm = tool.getStandardFileManager(null, null, null);
+        try (PrintWriter pw = new PrintWriter(sw);
+            JavacFileManager fm = tool.getStandardFileManager(null, null, null)) {
             List<String> opts = patches.stream()
                 .map(p -> "--patch-module=" + p.replace(":", PS))
                 .collect(Collectors.toList());
             Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects("C.java");
             JavacTask task = tool.getTask(pw, fm, null, opts, null, files);
 
-            Field locationsField = BaseFileManager.class.getDeclaredField("locations");
-            locationsField.setAccessible(true);
-            Object locations = locationsField.get(fm);
+            Map<String, List<Location>> mod2Location =
+                    StreamSupport.stream(fm.listLocationsForModules(StandardLocation.PATCH_MODULE_PATH)
+                                           .spliterator(),
+                                        false)
+                                 .flatMap(sl -> sl.stream())
+                                 .collect(Collectors.groupingBy(l -> fm.inferModuleName(l)));
 
-            Field patchMapField = Locations.class.getDeclaredField("patchMap");
-            patchMapField.setAccessible(true);
-            Map<?,?> patchMap = (Map<?,?>) patchMapField.get(locations);
+            Map<String, List<String>> patchMap = mod2Location.entrySet()
+                    .stream()
+                    .map(e -> new SimpleEntry<>(e.getKey(), e.getValue().get(0)))
+                    .map(e -> new SimpleEntry<>(e.getKey(), locationPaths(fm, e.getValue())))
+                    .collect(Collectors.toMap(Entry :: getKey,
+                                              Entry :: getValue,
+                                              (v1, v2) -> {throw new IllegalStateException();},
+                                              TreeMap::new));
             String found = patchMap.toString();
 
             if (!found.equals(expect)) {
@@ -150,5 +163,34 @@
             }
         }
     }
+
+    static List<String> locationPaths(StandardJavaFileManager fm, Location loc) {
+        return StreamSupport.stream(fm.getLocationAsPaths(loc).spliterator(), false)
+                            .map(p -> p.toString())
+                            .collect(Collectors.toList());
+    }
+
+    @Test
+    public void testPatchWithSource(Path base) throws Exception {
+        Path patch = base.resolve("patch");
+        tb.writeJavaFiles(patch, "package javax.lang.model.element; public interface Extra { }");
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "module m { requires java.compiler; }",
+                          "package test; public interface Test extends javax.lang.model.element.Extra { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        new toolbox.JavacTask(tb)
+            .options("--patch-module", "java.compiler=" + patch.toString())
+            .outdir(classes)
+            .files(findJavaFiles(src))
+            .run()
+            .writeAll();
+
+        if (Files.exists(classes.resolve("javax"))) {
+            throw new AssertionError();
+        }
+    }
 }
 
--- a/langtools/test/tools/javac/modules/XModuleTest.java	Fri Feb 10 15:42:17 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,422 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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 tests for multi-module mode compilation
- * @library /tools/lib
- * @modules
- *      jdk.compiler/com.sun.tools.javac.api
- *      jdk.compiler/com.sun.tools.javac.code
- *      jdk.compiler/com.sun.tools.javac.main
- *      jdk.compiler/com.sun.tools.javac.processing
- * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
- * @run main XModuleTest
- */
-
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Elements;
-
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import toolbox.JavacTask;
-import toolbox.ModuleBuilder;
-import toolbox.Task;
-import toolbox.Task.Expect;
-
-public class XModuleTest extends ModuleTestBase {
-
-    public static void main(String... args) throws Exception {
-        new XModuleTest().runTests();
-    }
-
-    @Test
-    public void testCorrectXModule(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        String log = new JavacTask(tb)
-                .options("-Xmodule:java.compiler")
-                .outdir(classes)
-                .files(findJavaFiles(src))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!log.isEmpty())
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testSourcePath(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }", "package javax.lang.model.element; interface Other { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        String log = new JavacTask(tb)
-                .options("-Xmodule:java.compiler", "-sourcepath", src.toString())
-                .outdir(classes)
-                .files(src.resolve("javax/lang/model/element/Extra.java"))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!log.isEmpty())
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testClassPath(Path base) throws Exception {
-        Path cpSrc = base.resolve("cpSrc");
-        tb.writeJavaFiles(cpSrc, "package p; public interface Other { }");
-        Path cpClasses = base.resolve("cpClasses");
-        tb.createDirectories(cpClasses);
-
-        String cpLog = new JavacTask(tb)
-                .outdir(cpClasses)
-                .files(findJavaFiles(cpSrc))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!cpLog.isEmpty())
-            throw new Exception("expected output not found: " + cpLog);
-
-        Path src = base.resolve("src");
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, p.Other { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        List<String> log = new JavacTask(tb)
-                .options("-Xmodule:java.compiler",
-                         "--class-path", cpClasses.toString(),
-                         "-XDrawDiagnostics")
-                .outdir(classes)
-                .files(src.resolve("javax/lang/model/element/Extra.java"))
-                .run(Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        List<String> expectedOut = Arrays.asList(
-                "Extra.java:1:76: compiler.err.doesnt.exist: p",
-                "1 error"
-        );
-
-        if (!expectedOut.equals(log))
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src,
-                          "module java.compiler {}",
-                          "package javax.lang.model.element; public interface Extra { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        List<String> log = new JavacTask(tb)
-                .options("-XDrawDiagnostics", "-Xmodule:java.compiler")
-                .outdir(classes)
-                .files(findJavaFiles(src))
-                .run(Task.Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.sourcepath",
-                                              "1 error");
-
-        if (!expected.equals(log))
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testNoModuleInfoInClassOutput(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path srcMod = base.resolve("src-mod");
-        tb.writeJavaFiles(srcMod,
-                          "module mod {}");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        String logMod = new JavacTask(tb)
-                .options()
-                .outdir(classes)
-                .files(findJavaFiles(srcMod))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!logMod.isEmpty())
-            throw new Exception("unexpected output found: " + logMod);
-
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src,
-                          "package javax.lang.model.element; public interface Extra { }");
-        tb.createDirectories(classes);
-
-        List<String> log = new JavacTask(tb)
-                .options("-XDrawDiagnostics", "-Xmodule:java.compiler")
-                .outdir(classes)
-                .files(findJavaFiles(src))
-                .run(Task.Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.classpath",
-                                              "1 error");
-
-        if (!expected.equals(log))
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testModuleSourcePathXModule(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        List<String> log = new JavacTask(tb)
-                .options("-XDrawDiagnostics", "-Xmodule:java.compiler", "--module-source-path", src.toString())
-                .outdir(classes)
-                .files(findJavaFiles(src))
-                .run(Task.Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        List<String> expected = Arrays.asList("- compiler.err.xmodule.no.module.sourcepath");
-
-        if (!expected.equals(log))
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testXModuleTooMany(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
-                .options("-XDrawDiagnostics", "-Xmodule:java.compiler", "-Xmodule:java.compiler")
-                .outdir(classes)
-                .files(findJavaFiles(src))
-                .run(Task.Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        List<String> expected = Arrays.asList("javac: option -Xmodule: can only be specified once",
-                                              "Usage: javac <options> <source files>",
-                                              "use --help for a list of possible options");
-
-        if (!expected.equals(log))
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testWithModulePath(Path base) throws Exception {
-        Path modSrc = base.resolve("modSrc");
-        Path modules = base.resolve("modules");
-        new ModuleBuilder(tb, "m1")
-                .classes("package pkg1; public interface E { }")
-                .build(modSrc, modules);
-
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }");
-
-        new JavacTask(tb, Task.Mode.CMDLINE)
-                .options("--module-path", modules.toString(),
-                        "-Xmodule:m1")
-                .files(findJavaFiles(src))
-                .run()
-                .writeAll();
-
-        //checks module bounds still exist
-        new ModuleBuilder(tb, "m2")
-                .classes("package pkg2; public interface D { }")
-                .build(modSrc, modules);
-
-        Path src2 = base.resolve("src2");
-        tb.writeJavaFiles(src2, "package p; interface A extends pkg2.D { }");
-
-        List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
-                .options("-XDrawDiagnostics",
-                        "--module-path", modules.toString(),
-                        "-Xmodule:m1")
-                .files(findJavaFiles(src2))
-                .run(Task.Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        List<String> expected = Arrays.asList("A.java:1:32: compiler.err.package.not.visible: pkg2, (compiler.misc.not.def.access.does.not.read: m1, pkg2, m2)",
-                "1 error");
-
-        if (!expected.equals(log))
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @Test
-    public void testWithUpgradeModulePath(Path base) throws Exception {
-        Path modSrc = base.resolve("modSrc");
-        Path modules = base.resolve("modules");
-        new ModuleBuilder(tb, "m1")
-                .classes("package pkg1; public interface E { }")
-                .build(modSrc, modules);
-
-        Path upgrSrc = base.resolve("upgradeSrc");
-        Path upgrade = base.resolve("upgrade");
-        new ModuleBuilder(tb, "m1")
-                .classes("package pkg1; public interface D { }")
-                .build(upgrSrc, upgrade);
-
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package p; interface A extends pkg1.D { }");
-
-        new JavacTask(tb, Task.Mode.CMDLINE)
-                .options("--module-path", modules.toString(),
-                        "--upgrade-module-path", upgrade.toString(),
-                        "-Xmodule:m1")
-                .files(findJavaFiles(src))
-                .run()
-                .writeAll();
-    }
-
-    @Test
-    public void testUnnamedIsolation(Path base) throws Exception {
-        //note: avoiding use of java.base, as that gets special handling on some places:
-        Path sourcePath = base.resolve("source-path");
-        tb.writeJavaFiles(sourcePath, "package src; public class Src {}");
-
-        Path classPathSrc = base.resolve("class-path-src");
-        tb.writeJavaFiles(classPathSrc, "package cp; public class CP { }");
-        Path classPath = base.resolve("classPath");
-        tb.createDirectories(classPath);
-
-        String cpLog = new JavacTask(tb)
-                .outdir(classPath)
-                .files(findJavaFiles(classPathSrc))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!cpLog.isEmpty())
-            throw new Exception("expected output not found: " + cpLog);
-
-        Path modulePathSrc = base.resolve("module-path-src");
-        tb.writeJavaFiles(modulePathSrc,
-                          "module m {}",
-                          "package m; public class M {}");
-        Path modulePath = base.resolve("modulePath");
-        tb.createDirectories(modulePath.resolve("m"));
-
-        String modLog = new JavacTask(tb)
-                .outdir(modulePath.resolve("m"))
-                .files(findJavaFiles(modulePathSrc))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!modLog.isEmpty())
-            throw new Exception("expected output not found: " + modLog);
-
-        Path src = base.resolve("src");
-        tb.writeJavaFiles(src, "package m; public class Extra { }");
-        Path classes = base.resolve("classes");
-        tb.createDirectories(classes);
-
-        String log = new JavacTask(tb)
-                .options("-Xmodule:m",
-                         "--class-path", classPath.toString(),
-                         "--source-path", sourcePath.toString(),
-                         "--module-path", modulePath.toString(),
-                         "--processor-path", System.getProperty("test.classes"),
-                         "-XDaccessInternalAPI=true",
-                         "-processor", CheckModuleContentProcessing.class.getName())
-                .outdir(classes)
-                .files(findJavaFiles(sourcePath))
-                .run()
-                .writeAll()
-                .getOutput(Task.OutputKind.DIRECT);
-
-        if (!log.isEmpty())
-            throw new Exception("expected output not found: " + log);
-    }
-
-    @SupportedAnnotationTypes("*")
-    public static final class CheckModuleContentProcessing extends AbstractProcessor {
-
-        @Override
-        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-            Symtab syms = Symtab.instance(((JavacProcessingEnvironment) processingEnv).getContext());
-            Elements elements = processingEnv.getElementUtils();
-            ModuleElement unnamedModule = syms.unnamedModule;
-            ModuleElement mModule = elements.getModuleElement("m");
-
-            assertNonNull("mModule found", mModule);
-            assertNonNull("src.Src from m", elements.getTypeElement(mModule, "src.Src"));
-            assertNull("cp.CP not from m", elements.getTypeElement(mModule, "cp.CP"));
-            assertNull("src.Src not from unnamed", elements.getTypeElement(unnamedModule, "src.Src"));
-            assertNonNull("cp.CP from unnamed", elements.getTypeElement(unnamedModule, "cp.CP"));
-
-            return false;
-        }
-
-        @Override
-        public SourceVersion getSupportedSourceVersion() {
-            return SourceVersion.latest();
-        }
-
-        private static void assertNonNull(String msg, Object val) {
-            if (val == null) {
-                throw new AssertionError(msg);
-            }
-        }
-
-        private static void assertNull(String msg, Object val) {
-            if (val != null) {
-                throw new AssertionError(msg);
-            }
-        }
-    }
-
-}
--- a/langtools/test/tools/javac/synthesize/Main.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/javac/synthesize/Main.java	Mon Feb 13 09:37:26 2017 +0100
@@ -92,12 +92,17 @@
         File empty = new File("empty");
         empty.mkdirs();
 
+        // files to compile are in a separate directory from test to avoid
+        // confusing jtreg
+        File src = new File(testSrc, "src");
+
         List<String> args = new ArrayList<String>();
         args.add("-classpath");
         args.add("empty");
 
         if (stdBootClassPath) {
-            args.add("-Xmodule:java.base");
+            args.add("--patch-module");
+            args.add("java.base=" + testSrc.getAbsolutePath());
         } else {
             args.add("--system");
             args.add("none");
@@ -108,9 +113,6 @@
         args.add("-d");
         args.add(".");
 
-        // files to compile are in a separate directory from test to avoid
-        // confusing jtreg
-        File src = new File(testSrc, "src");
         for (String f: files)
             args.add(new File(src, f).getPath());
 
--- a/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java	Fri Feb 10 15:42:17 2017 -0800
+++ b/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java	Mon Feb 13 09:37:26 2017 +0100
@@ -63,7 +63,7 @@
         Path sunMiscSrc = Paths.get(TEST_SRC, "patches", JDK_UNSUPPORTED);
         Path patchDir = PATCHES_DIR.resolve(JDK_UNSUPPORTED);
         assertTrue(CompilerUtils.compile(sunMiscSrc, patchDir,
-                                         "-Xmodule:" + JDK_UNSUPPORTED));
+                                         "--patch-module", JDK_UNSUPPORTED + "=" + sunMiscSrc.toString()));
 
         // compile com.sun.image.codec.jpeg types
         Path codecSrc = Paths.get(TEST_SRC, "patches", "java.desktop");