8139607: -release option forces StandardJavaFileManager
authorjlahoda
Mon, 06 Nov 2017 13:10:43 +0100
changeset 47702 cf8310446245
parent 47701 be620a591379
child 47703 dbfac941197a
8139607: -release option forces StandardJavaFileManager Summary: Merging a --release specific file manager with the user-provided one, rather than altering the user-provided one. Reviewed-by: jjg, mcimadamore
src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java
src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java
src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java
src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java
src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java
src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java
src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformDescription.java
src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties
src/jdk.compiler/share/classes/module-info.java
src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java
src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java
test/langtools/tools/javac/file/SetLocationForModule.java
test/langtools/tools/javac/platform/PlatformProviderTest.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Mon Nov 06 13:10:43 2017 +0100
@@ -63,6 +63,7 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.Kind.*;
+import com.sun.tools.javac.main.DelegatingJavaFileManager;
 
 import com.sun.tools.javac.util.Dependencies.CompletionCause;
 
@@ -104,11 +105,6 @@
      */
     protected boolean userPathsFirst;
 
-    /**
-     * Switch: should read OTHER classfiles (.sig files) from PLATFORM_CLASS_PATH.
-     */
-    private boolean allowSigFiles;
-
     /** The log to use for verbose output
      */
     final Log log;
@@ -198,7 +194,6 @@
         cacheCompletionFailure = options.isUnset("dev");
         preferSource = "source".equals(options.get("-Xprefer"));
         userPathsFirst = options.isSet(Option.XXUSERPATHSFIRST);
-        allowSigFiles = context.get(PlatformDescription.class) != null;
 
         completionFailureName =
             options.isSet("failcomplete")
@@ -208,6 +203,9 @@
         // Temporary, until more info is available from the module system.
         boolean useCtProps;
         JavaFileManager fm = context.get(JavaFileManager.class);
+        if (fm instanceof DelegatingJavaFileManager) {
+            fm = ((DelegatingJavaFileManager) fm).getBaseFileManager();
+        }
         if (fm instanceof JavacFileManager) {
             JavacFileManager jfm = (JavacFileManager) fm;
             useCtProps = jfm.isDefaultBootClassPath() && jfm.isSymbolFileEnabled();
@@ -350,8 +348,7 @@
                 if (verbose) {
                     log.printVerbose("loading", currentClassFile.getName());
                 }
-                if (classfile.getKind() == JavaFileObject.Kind.CLASS ||
-                    classfile.getKind() == JavaFileObject.Kind.OTHER) {
+                if (classfile.getKind() == JavaFileObject.Kind.CLASS) {
                     reader.readClassFile(c);
                     c.flags_field |= getSupplementaryFlags(c);
                 } else {
@@ -454,7 +451,7 @@
                 q.flags_field |= EXISTS;
         JavaFileObject.Kind kind = file.getKind();
         int seen;
-        if (kind == JavaFileObject.Kind.CLASS || kind == JavaFileObject.Kind.OTHER)
+        if (kind == JavaFileObject.Kind.CLASS)
             seen = CLASS_SEEN;
         else
             seen = SOURCE_SEEN;
@@ -695,9 +692,7 @@
                list(PLATFORM_CLASS_PATH,
                     p,
                     p.fullname.toString(),
-                    allowSigFiles ? EnumSet.of(JavaFileObject.Kind.CLASS,
-                                               JavaFileObject.Kind.OTHER)
-                                  : EnumSet.of(JavaFileObject.Kind.CLASS)));
+                    EnumSet.of(JavaFileObject.Kind.CLASS)));
     }
     // where
         @SuppressWarnings("fallthrough")
@@ -709,11 +704,8 @@
             for (JavaFileObject fo : files) {
                 switch (fo.getKind()) {
                 case OTHER:
-                    if (!isSigFile(location, fo)) {
-                        extraFileActions(p, fo);
-                        break;
-                    }
-                    //intentional fall-through:
+                    extraFileActions(p, fo);
+                    break;
                 case CLASS:
                 case SOURCE: {
                     // TODO pass binaryName to includeClassFile
@@ -731,12 +723,6 @@
             }
         }
 
-        boolean isSigFile(Location location, JavaFileObject fo) {
-            return location == PLATFORM_CLASS_PATH &&
-                   allowSigFiles &&
-                   fo.getName().endsWith(".sig");
-        }
-
         Iterable<JavaFileObject> list(Location location,
                                       PackageSymbol p,
                                       String packageName,
@@ -755,8 +741,7 @@
                             JavaFileObject fo = original.next();
 
                             if (fo.getKind() != Kind.CLASS &&
-                                fo.getKind() != Kind.SOURCE &&
-                                !isSigFile(currentLoc, fo)) {
+                                fo.getKind() != Kind.SOURCE) {
                                 p.flags_field |= Flags.HAS_RESOURCE;
                             }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Mon Nov 06 13:10:43 2017 +0100
@@ -751,6 +751,11 @@
         return locations.hasLocation(location);
     }
 
+    protected boolean hasExplicitLocation(Location location) {
+        nullCheck(location);
+        return locations.hasExplicitLocation(location);
+    }
+
     @Override @DefinedBy(Api.COMPILER)
     public JavaFileObject getJavaFileForInput(Location location,
                                               String className,
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Nov 06 13:10:43 2017 +0100
@@ -452,6 +452,8 @@
             return (getPaths() != null);
         }
 
+        abstract boolean isExplicit();
+
         /**
          * @see StandardJavaFileManager#getLocation
          */
@@ -510,6 +512,8 @@
         final Location location;
         final Set<Option> options;
 
+        boolean explicit;
+
         /**
          * Create a handler. The location and options provide a way to map from a location or an
          * option to the corresponding handler.
@@ -554,6 +558,12 @@
             }
             return path;
         }
+
+        @Override
+        boolean isExplicit() {
+            return explicit;
+        }
+
     }
 
     /**
@@ -576,6 +586,8 @@
                 return false;
             }
 
+            explicit = true;
+
             // TODO: could/should validate outputDir exists and is a directory
             // need to decide how best to report issue for benefit of
             // direct API call on JavaFileManager.handleOption(specifies IAE)
@@ -594,6 +606,7 @@
             if (paths == null) {
                 outputDir = null;
             } else {
+                explicit = true;
                 outputDir = checkSingletonDirectory(paths);
             }
             moduleTable = null;
@@ -626,10 +639,11 @@
                 l = new ModuleLocationHandler(this, location.getName() + "[" + name + "]",
                         name, Collections.singletonList(out), true);
                 moduleTable.add(l);
-           } else {
+            } else {
                 l.searchPath = Collections.singletonList(out);
                 moduleTable.updatePaths(l);
             }
+            explicit = true;
         }
 
         @Override
@@ -685,6 +699,9 @@
             if (!options.contains(option)) {
                 return false;
             }
+
+            explicit = true;
+
             searchPath = value == null ? null
                     : Collections.unmodifiableCollection(createPath().addFiles(value));
             return true;
@@ -701,6 +718,7 @@
             if (files == null) {
                 p = computePath(null);
             } else {
+                explicit = true;
                 p = createPath().addFiles(files);
             }
             searchPath = Collections.unmodifiableCollection(p);
@@ -813,6 +831,8 @@
                 return false;
             }
 
+            explicit = true;
+
             option = canonicalize(option);
             optionValues.put(option, value);
             if (option == BOOT_CLASS_PATH) {
@@ -850,6 +870,7 @@
                 searchPath = null;  // reset to "uninitialized"
             } else {
                 isDefault = false;
+                explicit = true;
                 SearchPath p = new SearchPath().addFiles(files, false);
                 searchPath = Collections.unmodifiableCollection(p);
                 optionValues.clear();
@@ -996,6 +1017,11 @@
             return Collections.unmodifiableCollection(searchPath);
         }
 
+        @Override
+        boolean isExplicit() {
+            return true;
+        }
+
         @Override // defined by LocationHandler
         void setPaths(Iterable<? extends Path> paths) throws IOException {
             // defer to the parent to determine if this is acceptable
@@ -1179,6 +1205,7 @@
                 moduleTable.updatePaths(l);
             }
             l.explicit = true;
+            explicit = true;
         }
 
         private List<Path> checkPaths(Iterable<? extends Path> paths) throws IOException {
@@ -1498,6 +1525,7 @@
 
         @Override
         boolean handleOption(Option option, String value) {
+            explicit = true;
             init(value);
             return true;
         }
@@ -1681,6 +1709,7 @@
             }
 
             initModuleTable(map);
+            explicit = true;
             paths = Collections.unmodifiableList(newPaths);
         }
 
@@ -1703,6 +1732,7 @@
                 l.searchPath = validPaths;
                 moduleTable.updatePaths(l);
             }
+            explicit = true;
         }
 
         private List<Path> checkPaths(Iterable<? extends Path> paths) throws IOException {
@@ -1755,6 +1785,8 @@
                 return false;
             }
 
+            explicit = true;
+
             if (value == null) {
                 systemJavaHome = Locations.javaHome;
             } else if (value.equals("none")) {
@@ -1777,6 +1809,8 @@
             if (files == null) {
                 systemJavaHome = null;
             } else {
+                explicit = true;
+
                 Path dir = checkSingletonDirectory(files);
                 update(dir);
             }
@@ -1798,6 +1832,7 @@
                 l.searchPath = checkedPaths;
                 moduleTable.updatePaths(l);
             }
+            explicit = true;
         }
 
         private List<Path> checkPaths(Iterable<? extends Path> paths) throws IOException {
@@ -1918,6 +1953,8 @@
                 return false;
             }
 
+            explicit = true;
+
             moduleTable.clear();
 
             // Allow an extended syntax for --patch-module consisting of a series
@@ -2027,6 +2064,11 @@
         return (h == null ? false : h.isSet());
     }
 
+    boolean hasExplicitLocation(Location location) {
+        LocationHandler h = getHandler(location);
+        return (h == null ? false : h.isExplicit());
+    }
+
     Collection<Path> getLocation(Location location) {
         LocationHandler h = getHandler(location);
         return (h == null ? null : h.getPaths());
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Mon Nov 06 13:10:43 2017 +0100
@@ -30,7 +30,6 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
@@ -304,7 +303,8 @@
                 Option.SYSTEM, Option.UPGRADE_MODULE_PATH);
 
         if (platformString != null) {
-            PlatformDescription platformDescription = PlatformUtils.lookupPlatformDescription(platformString);
+            PlatformDescription platformDescription =
+                    PlatformUtils.lookupPlatformDescription(platformString);
 
             if (platformDescription == null) {
                 error("err.unsupported.release.version", platformString);
@@ -319,31 +319,10 @@
             if (!additionalOptions.test(platformDescription.getAdditionalOptions()))
                 return false;
 
-            Collection<Path> platformCP = platformDescription.getPlatformPath();
-
-            if (platformCP != null) {
-                JavaFileManager fm = getFileManager();
-
-                if (!(fm instanceof StandardJavaFileManager)) {
-                    error("err.release.not.standard.file.manager");
-                    return false;
-                }
-
-                try {
-                    StandardJavaFileManager sfm = (StandardJavaFileManager) fm;
-
-                    if (Source.instance(context).allowModules()) {
-                        sfm.handleOption("--system", Arrays.asList("none").iterator());
-                        sfm.setLocationFromPaths(StandardLocation.UPGRADE_MODULE_PATH, platformCP);
-                    } else {
-                        sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP);
-                    }
-                } catch (IOException ex) {
-                    log.printLines(PrefixKind.JAVAC, "msg.io");
-                    ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
-                    return false;
-                }
-            }
+            JavaFileManager platformFM = platformDescription.getFileManager();
+            DelegatingJavaFileManager.installReleaseFileManager(context,
+                                                                platformFM,
+                                                                getFileManager());
         }
 
         return true;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java	Mon Nov 06 13:10:43 2017 +0100
@@ -0,0 +1,273 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.main;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.util.Context;
+
+/**
+ * A JavaFileManager that delegates to one of two delegate ClassLoaders.
+ */
+public class DelegatingJavaFileManager implements JavaFileManager {
+
+    public static void installReleaseFileManager(Context context,
+                                                 JavaFileManager releaseFM,
+                                                 JavaFileManager originalFM) {
+        context.put(JavaFileManager.class, (JavaFileManager) null);
+        JavaFileManager nue = originalFM instanceof StandardJavaFileManager
+                ? new DelegatingSJFM(releaseFM,
+                                                        (StandardJavaFileManager) originalFM)
+                : new DelegatingJavaFileManager(releaseFM, originalFM);
+        context.put(JavaFileManager.class, nue);
+    }
+
+    private final JavaFileManager releaseFM;
+    private final JavaFileManager baseFM;
+
+    private DelegatingJavaFileManager(JavaFileManager releaseFM, JavaFileManager baseFM) {
+        this.releaseFM = releaseFM;
+        this.baseFM = baseFM;
+    }
+
+    private JavaFileManager delegate(Location location) {
+        if (releaseFM.hasLocation(location)) {
+            return releaseFM;
+        }
+        return baseFM;
+    }
+
+    @Override
+    public ClassLoader getClassLoader(Location location) {
+        return delegate(location).getClassLoader(location);
+    }
+
+    @Override
+    public Iterable<JavaFileObject> list(Location location, String packageName,
+                                         Set<Kind> kinds, boolean recurse) throws IOException {
+        return delegate(location).list(location, packageName, kinds, recurse);
+    }
+
+    @Override
+    public String inferBinaryName(Location location, JavaFileObject file) {
+        return delegate(location).inferBinaryName(location, file);
+    }
+
+    @Override
+    public boolean isSameFile(FileObject a, FileObject b) {
+        return baseFM.isSameFile(a, b);
+    }
+
+    @Override
+    public boolean handleOption(String current, Iterator<String> remaining) {
+        return baseFM.handleOption(current, remaining);
+    }
+
+    @Override
+    public boolean hasLocation(Location location) {
+        return releaseFM.hasLocation(location) || baseFM.hasLocation(location);
+    }
+
+    @Override
+    public JavaFileObject getJavaFileForInput(Location location, String className,
+                                              Kind kind) throws IOException {
+        return delegate(location).getJavaFileForInput(location, className, kind);
+    }
+
+    @Override
+    public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
+                                               FileObject sibling) throws IOException {
+        return delegate(location).getJavaFileForOutput(location, className, kind, sibling);
+    }
+
+    @Override
+    public FileObject getFileForInput(Location location, String packageName,
+                                      String relativeName) throws IOException {
+        return delegate(location).getFileForInput(location, packageName, relativeName);
+    }
+
+    @Override
+    public FileObject getFileForOutput(Location location, String packageName, String relativeName,
+                                       FileObject sibling) throws IOException {
+        return delegate(location).getFileForOutput(location, packageName, relativeName, sibling);
+    }
+
+    @Override
+    public void flush() throws IOException {
+        releaseFM.flush();
+        baseFM.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        releaseFM.close();
+        baseFM.close();
+    }
+
+    @Override
+    public Location getLocationForModule(Location location,
+                                         String moduleName) throws IOException {
+        return delegate(location).getLocationForModule(location, moduleName);
+    }
+
+    @Override
+    public Location getLocationForModule(Location location,
+                                         JavaFileObject fo) throws IOException {
+        return delegate(location).getLocationForModule(location, fo);
+    }
+
+    @Override
+    public <S> ServiceLoader<S> getServiceLoader(Location location,
+                                                 Class<S> service) throws IOException {
+        return delegate(location).getServiceLoader(location, service);
+    }
+
+    @Override
+    public String inferModuleName(Location location) throws IOException {
+        return delegate(location).inferModuleName(location);
+    }
+
+    @Override
+    public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
+        return delegate(location).listLocationsForModules(location);
+    }
+
+    @Override
+    public boolean contains(Location location, FileObject fo) throws IOException {
+        return delegate(location).contains(location, fo);
+    }
+
+    @Override
+    public int isSupportedOption(String option) {
+        return baseFM.isSupportedOption(option);
+    }
+
+    public JavaFileManager getBaseFileManager() {
+        return baseFM;
+    }
+
+    private static final class DelegatingSJFM extends DelegatingJavaFileManager
+                                              implements StandardJavaFileManager {
+
+        private final StandardJavaFileManager baseSJFM;
+
+        private DelegatingSJFM(JavaFileManager releaseFM,
+                                                  StandardJavaFileManager baseSJFM) {
+            super(releaseFM, baseSJFM);
+            this.baseSJFM = baseSJFM;
+        }
+
+        @Override
+        public boolean isSameFile(FileObject a, FileObject b) {
+            return baseSJFM.isSameFile(a, b);
+        }
+
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles
+                                                  (Iterable<? extends File> files) {
+            return baseSJFM.getJavaFileObjectsFromFiles(files);
+        }
+
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths
+                                                  (Iterable<? extends Path> paths) {
+            return baseSJFM.getJavaFileObjectsFromPaths(paths);
+        }
+
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
+            return baseSJFM.getJavaFileObjects(files);
+        }
+
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
+            return baseSJFM.getJavaFileObjects(paths);
+        }
+
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings
+                                                  (Iterable<String> names) {
+            return baseSJFM.getJavaFileObjectsFromStrings(names);
+        }
+
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
+            return baseSJFM.getJavaFileObjects(names);
+        }
+
+        @Override
+        public void setLocation(Location location,
+                                Iterable<? extends File> files) throws IOException {
+            baseSJFM.setLocation(location, files);
+        }
+
+        @Override
+        public void setLocationFromPaths(Location location,
+                                         Collection<? extends Path> paths) throws IOException {
+            baseSJFM.setLocationFromPaths(location, paths);
+        }
+
+        @Override
+        public void setLocationForModule(Location location, String moduleName,
+                                         Collection<? extends Path> paths) throws IOException {
+            baseSJFM.setLocationForModule(location, moduleName, paths);
+        }
+
+        @Override
+        public Iterable<? extends File> getLocation(Location location) {
+            return baseSJFM.getLocation(location);
+        }
+
+        @Override
+        public Iterable<? extends Path> getLocationAsPaths(Location location) {
+            return baseSJFM.getLocationAsPaths(location);
+        }
+
+        @Override
+        public Path asPath(FileObject file) {
+            return baseSJFM.asPath(file);
+        }
+
+        @Override
+        public void setPathFactory(PathFactory f) {
+            baseSJFM.setPathFactory(f);
+        }
+
+    }
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Mon Nov 06 13:10:43 2017 +0100
@@ -163,13 +163,12 @@
         Context context = new Context();
         JavacFileManager.preRegister(context); // can't create it until Log has been set up
         Result result = compile(args, context);
-        if (fileManager instanceof JavacFileManager) {
-            try {
-                // A fresh context was created above, so jfm must be a JavacFileManager
-                ((JavacFileManager)fileManager).close();
-            } catch (IOException ex) {
-                bugMessage(ex);
-            }
+        try {
+            // A fresh context was created above, so the file manager can be safely closed:
+            if (fileManager != null)
+                fileManager.close();
+        } catch (IOException ex) {
+            bugMessage(ex);
         }
         return result;
     }
@@ -247,9 +246,11 @@
 
         // init file manager
         fileManager = context.get(JavaFileManager.class);
-        if (fileManager instanceof BaseFileManager) {
-            ((BaseFileManager) fileManager).setContext(context); // reinit with options
-            ok &= ((BaseFileManager) fileManager).handleOptions(args.getDeferredFileManagerOptions());
+        JavaFileManager undel = fileManager instanceof DelegatingJavaFileManager ?
+                ((DelegatingJavaFileManager) fileManager).getBaseFileManager() : fileManager;
+        if (undel instanceof BaseFileManager) {
+            ((BaseFileManager) undel).setContext(context); // reinit with options
+            ok &= ((BaseFileManager) undel).handleOptions(args.getDeferredFileManagerOptions());
         }
 
         // handle this here so it works even if no other options given
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java	Mon Nov 06 13:10:43 2017 +0100
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.platform;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.net.URI;
 import java.nio.charset.Charset;
 import java.nio.file.DirectoryStream;
@@ -36,19 +37,33 @@
 import java.nio.file.Paths;
 import java.nio.file.ProviderNotFoundException;
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.stream.Stream;
 
 import javax.annotation.processing.Processor;
+import javax.tools.ForwardingJavaFileObject;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
 
 import com.sun.source.util.Plugin;
+import com.sun.tools.javac.file.CacheFSInfo;
+import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
 
 /** PlatformProvider for JDK N.
  *
@@ -66,7 +81,7 @@
 
     @Override
     public PlatformDescription getPlatform(String platformName, String options) {
-        return new PlatformDescriptionImpl(platformName.equals("10") ? "9" : platformName);
+        return new PlatformDescriptionImpl(platformName);
     }
 
     private static final String[] symbolFileLocation = { "lib", "ct.sym" };
@@ -113,47 +128,183 @@
         }
 
         @Override
-        public Collection<Path> getPlatformPath() {
-            List<Path> paths = new ArrayList<>();
+        public JavaFileManager getFileManager() {
+            Context context = new Context();
+            PrintWriter pw = new PrintWriter(System.err, true);
+            context.put(Log.errKey, pw);
+            CacheFSInfo.preRegister(context);
+            JavacFileManager fm = new JavacFileManager(context, true, null) {
+                @Override
+                public boolean hasLocation(Location location) {
+                    return super.hasExplicitLocation(location);
+                }
+
+                @Override
+                public JavaFileObject getJavaFileForInput(Location location, String className,
+                                                          Kind kind) throws IOException {
+                    if (kind == Kind.CLASS) {
+                        String fileName = className.replace('.', '/');
+                        JavaFileObject result =
+                                (JavaFileObject) getFileForInput(location,
+                                                                 "",
+                                                                 fileName + ".sig");
+
+                        if (result == null) {
+                            //in jrt://, the classfile may have the .class extension:
+                            result = (JavaFileObject) getFileForInput(location,
+                                                                      "",
+                                                                      fileName + ".class");
+                        }
+
+                        if (result != null) {
+                            return new SigJavaFileObject(result);
+                        } else {
+                            return null;
+                        }
+                    }
+
+                    return super.getJavaFileForInput(location, className, kind);
+                }
+
+                @Override
+                public Iterable<JavaFileObject> list(Location location,
+                                                     String packageName,
+                                                     Set<Kind> kinds,
+                                                     boolean recurse) throws IOException {
+                    Set<Kind> enhancedKinds = EnumSet.copyOf(kinds);
+
+                    enhancedKinds.add(Kind.OTHER);
+
+                    Iterable<JavaFileObject> listed = super.list(location, packageName,
+                                                                 enhancedKinds, recurse);
+
+                    return () -> new Iterator<JavaFileObject>() {
+                        private final Iterator<JavaFileObject> original = listed.iterator();
+                        private JavaFileObject next;
+                        @Override
+                        public boolean hasNext() {
+                            if (next == null) {
+                                while (original.hasNext()) {
+                                    JavaFileObject fo = original.next();
+
+                                    if (fo.getKind() == Kind.OTHER &&
+                                        fo.getName().endsWith(".sig")) {
+                                        next = new SigJavaFileObject(fo);
+                                        break;
+                                    }
+
+                                    if (kinds.contains(fo.getKind())) {
+                                        next = fo;
+                                        break;
+                                    }
+                                }
+                            }
+                            return next != null;
+                        }
+
+                        @Override
+                        public JavaFileObject next() {
+                            if (!hasNext())
+                                throw new NoSuchElementException();
+                            JavaFileObject result = next;
+                            next = null;
+                            return result;
+                        }
+
+                    };
+                }
+
+                @Override
+                public String inferBinaryName(Location location, JavaFileObject file) {
+                    if (file instanceof SigJavaFileObject) {
+                        file = ((SigJavaFileObject) file).getDelegate();
+                    }
+                    return super.inferBinaryName(location, file);
+                }
+
+            };
+
             Path file = findCtSym();
             // file == ${jdk.home}/lib/ct.sym
             if (Files.exists(file)) {
-                FileSystem fs = ctSym2FileSystem.get(file);
-                if (fs == null) {
-                    try {
+                try {
+                    FileSystem fs = ctSym2FileSystem.get(file);
+                    if (fs == null) {
                         ctSym2FileSystem.put(file, fs = FileSystems.newFileSystem(file, null));
-                    } catch (IOException ex) {
-                        throw new IllegalStateException(ex);
                     }
-                }
-                Path root = fs.getRootDirectories().iterator().next();
-                try (DirectoryStream<Path> dir = Files.newDirectoryStream(root)) {
-                    for (Path section : dir) {
-                        if (section.getFileName().toString().contains(version)) {
-                            Path systemModules = section.resolve("system-modules");
+
+                    List<Path> paths = new ArrayList<>();
+                    Path root = fs.getRootDirectories().iterator().next();
+                    boolean pathsSet = false;
+                    Charset utf8 = Charset.forName("UTF-8");
+
+                    try (DirectoryStream<Path> dir = Files.newDirectoryStream(root)) {
+                        for (Path section : dir) {
+                            if (section.getFileName().toString().contains(version)) {
+                                Path systemModules = section.resolve("system-modules");
+
+                                if (Files.isRegularFile(systemModules)) {
+                                    fm.handleOption("--system", Arrays.asList("none").iterator());
 
-                            if (Files.isRegularFile(systemModules)) {
-                                Path modules =
-                                        FileSystems.getFileSystem(URI.create("jrt:/"))
-                                                   .getPath("modules");
-                                try (Stream<String> lines =
-                                        Files.lines(systemModules, Charset.forName("UTF-8"))) {
-                                    lines.map(line -> modules.resolve(line))
-                                         .filter(mod -> Files.exists(mod))
-                                         .forEach(mod -> paths.add(mod));
+                                    Path jrtModules =
+                                            FileSystems.getFileSystem(URI.create("jrt:/"))
+                                                       .getPath("modules");
+                                    try (Stream<String> lines =
+                                            Files.lines(systemModules, utf8)) {
+                                        lines.map(line -> jrtModules.resolve(line))
+                                             .filter(mod -> Files.exists(mod))
+                                             .forEach(mod -> setModule(fm, mod));
+                                    }
+                                    pathsSet = true;
+                                } else {
+                                    paths.add(section);
                                 }
-                            } else {
-                                paths.add(section);
                             }
                         }
                     }
+
+                    if (!pathsSet) {
+                        fm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, paths);
+                    }
+
+                    return fm;
                 } catch (IOException ex) {
                     throw new IllegalStateException(ex);
                 }
             } else {
                 throw new IllegalStateException("Cannot find ct.sym!");
             }
-            return paths;
+        }
+
+        private static void setModule(StandardJavaFileManager fm, Path mod) {
+            try {
+                fm.setLocationForModule(StandardLocation.SYSTEM_MODULES,
+                                        mod.getFileName().toString(),
+                                        Collections.singleton(mod));
+            } catch (IOException ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+
+        private static class SigJavaFileObject extends ForwardingJavaFileObject<JavaFileObject> {
+
+            public SigJavaFileObject(JavaFileObject fileObject) {
+                super(fileObject);
+            }
+
+            @Override
+            public Kind getKind() {
+                return Kind.CLASS;
+            }
+
+            @Override
+            public boolean isNameCompatible(String simpleName, Kind kind) {
+                return super.isNameCompatible(simpleName + ".sig", Kind.OTHER);
+            }
+
+            public JavaFileObject getDelegate() {
+                return fileObject;
+            }
         }
 
         @Override
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformDescription.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformDescription.java	Mon Nov 06 13:10:43 2017 +0100
@@ -27,12 +27,11 @@
 
 import java.io.Closeable;
 import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
 import javax.annotation.processing.Processor;
+import javax.tools.JavaFileManager;
 
 import com.sun.source.util.Plugin;
 
@@ -45,12 +44,7 @@
  */
 public interface PlatformDescription extends Closeable {
 
-    /**Returns paths that should be used as the current platform's bootclasspath, or null if
-     * the default should be used.
-     *
-     * @return the current platforms's bootclasspath, or null for default
-     */
-    Collection<Path> getPlatformPath();
+    JavaFileManager getFileManager();
 
     /**Returns the source version that should be selected.
      * Equivalent to {@code -source N} on the command line.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Mon Nov 06 13:10:43 2017 +0100
@@ -435,6 +435,3 @@
 
 javac.err.unsupported.release.version=\
     release version {0} not supported
-
-javac.err.release.not.standard.file.manager=\
-    --release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
--- a/src/jdk.compiler/share/classes/module-info.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.compiler/share/classes/module-info.java	Mon Nov 06 13:10:43 2017 +0100
@@ -113,6 +113,7 @@
     exports com.sun.tools.javac.parser to
         jdk.jshell;
     exports com.sun.tools.javac.platform to
+        jdk.jdeps,
         jdk.javadoc;
     exports com.sun.tools.javac.tree to
         jdk.javadoc,
--- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java	Mon Nov 06 13:10:43 2017 +0100
@@ -37,15 +37,14 @@
 
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
 
 import com.sun.javadoc.*;
 import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.main.CommandLine;
-import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.file.BaseFileManager;
 import com.sun.tools.javac.main.Arguments;
+import com.sun.tools.javac.main.CommandLine;
+import com.sun.tools.javac.main.DelegatingJavaFileManager;
+import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.main.OptionHelper;
 import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
 import com.sun.tools.javac.platform.PlatformDescription;
@@ -398,17 +397,10 @@
 
             context.put(PlatformDescription.class, platformDescription);
 
-            Collection<Path> platformCP = platformDescription.getPlatformPath();
-
-            if (platformCP != null) {
-                if (fileManager instanceof StandardJavaFileManager) {
-                    StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
-
-                    sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP);
-                } else {
-                    usageError("main.release.not.standard.file.manager", platformString);
-                }
-            }
+            JavaFileManager platformFM = platformDescription.getFileManager();
+            DelegatingJavaFileManager.installReleaseFileManager(context,
+                                                                platformFM,
+                                                                fileManager);
         }
 
         compOpts.notifyListeners();
--- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Mon Nov 06 13:10:43 2017 +0100
@@ -124,7 +124,6 @@
 main.illegal_package_name=Illegal package name: "{0}"
 main.release.bootclasspath.conflict=option {0} cannot be used together with -release
 main.unsupported.release.version=release version {0} not supported
-main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
 main.option.invalid.value={0}
 tag.illegal_char_in_arr_dim=Tag {0}: Syntax Error in array dimension, method parameters: {1}
 tag.illegal_see_tag=Tag {0}: Syntax Error in method parameters: {1}
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java	Mon Nov 06 13:10:43 2017 +0100
@@ -38,6 +38,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -45,18 +46,22 @@
 import java.util.Set;
 import java.util.Queue;
 import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.StandardLocation;
 import javax.tools.ToolProvider;
 
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.platform.JDKPlatformProvider;
 
 import com.sun.tools.jdeprscan.scan.Scan;
 
@@ -383,32 +388,24 @@
                      .map(TypeElement::toString)
                      .collect(toList()));
         } else {
-            // TODO: kind of a hack...
-            // Create a throwaway compilation task with options "--release N"
-            // which has the side effect of setting the file manager's
-            // PLATFORM_CLASS_PATH to the right value.
-            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
-            StandardJavaFileManager fm =
-                compiler.getStandardFileManager(this, null, StandardCharsets.UTF_8);
-            JavaCompiler.CompilationTask task =
-                compiler.getTask(null, fm, this, List.of("--release", release), null, null);
-            List<Path> paths = new ArrayList<>();
-            for (Path p : fm.getLocationAsPaths(StandardLocation.PLATFORM_CLASS_PATH)) {
-                try (Stream<Path> str = Files.walk(p)) {
-                    str.forEachOrdered(paths::add);
-                }
+            JDKPlatformProvider pp = new JDKPlatformProvider();
+            if (StreamSupport.stream(pp.getSupportedPlatformNames().spliterator(),
+                                 false)
+                             .noneMatch(n -> n.equals(release))) {
+                return false;
+            }
+            JavaFileManager fm = pp.getPlatform(release, "").getFileManager();
+            List<String> classNames = new ArrayList<>();
+            for (JavaFileObject fo : fm.list(StandardLocation.PLATFORM_CLASS_PATH,
+                                             "",
+                                             EnumSet.of(Kind.CLASS),
+                                             true)) {
+                classNames.add(fm.inferBinaryName(StandardLocation.PLATFORM_CLASS_PATH, fo));
             }
 
             options.add("-Xlint:-options");
 
-            return doClassNames(
-                paths.stream()
-                     .filter(path -> path.toString().endsWith(".sig"))
-                     .map(path -> path.subpath(1, path.getNameCount()))
-                     .map(Path::toString)
-                     .map(s -> s.replaceAll("\\.sig$", ""))
-                     .map(s -> s.replace('/', '.'))
-                     .collect(toList()));
+            return doClassNames(classNames);
         }
     }
 
--- a/test/langtools/tools/javac/file/SetLocationForModule.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/test/langtools/tools/javac/file/SetLocationForModule.java	Mon Nov 06 13:10:43 2017 +0100
@@ -123,8 +123,11 @@
                 checkEqual("override setting 2",
                            fm2.getLocationAsPaths(m), override1);
 
+                Location firstLocation =
+                        fm2.listLocationsForModules(locn).iterator().next().iterator().next();
+
                 checkEqual("override setting 2b",
-                           fm2.getLocationAsPaths(fm2.listLocationsForModules(locn).iterator().next().iterator().next()),
+                           fm2.getLocationAsPaths(firstLocation),
                            override1);
             }
 
@@ -214,6 +217,19 @@
                        fm.getLocationAsPaths(fm.listLocationsForModules(locn).iterator().next().iterator().next()),
                        override1);
 
+            try (StandardJavaFileManager fm2 = comp.getStandardFileManager(null, null, null)) {
+                fm2.setLocationForModule(locn, "m", List.of(override1));
+                checkEqual("override setting 1",
+                           fm2.getLocationAsPaths(m), override1);
+
+                Location firstLocation =
+                        fm2.listLocationsForModules(locn).iterator().next().iterator().next();
+
+                checkEqual("override setting 1b",
+                           fm2.getLocationAsPaths(firstLocation),
+                           override1);
+            }
+
             Path override2 = Files.createDirectories(base.resolve("override2"));
             fm.setLocationFromPaths(m, List.of(override2));
             checkEqual("override setting 2",
--- a/test/langtools/tools/javac/platform/PlatformProviderTest.java	Mon Oct 30 21:23:10 2017 +0100
+++ b/test/langtools/tools/javac/platform/PlatformProviderTest.java	Mon Nov 06 13:10:43 2017 +0100
@@ -41,9 +41,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -57,8 +55,8 @@
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.TypeElement;
 import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
 import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
 import javax.tools.ToolProvider;
 
 // import com.sun.source.util.JavacTask;
@@ -111,7 +109,7 @@
                               "getPlatform(name, " + expectedParameter + ")",
                               "getSourceVersion",
                               "getTargetVersion",
-                              "getPlatformPath",
+                              "getFileManager",
                               "testPlugin: [testPluginKey=testPluginValue]",
                               "process: {testAPKey=testAPValue}",
                               "process: {testAPKey=testAPValue}",
@@ -187,13 +185,10 @@
         private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
         private final StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null);
 
-
         @Override
-        public Collection<Path> getPlatformPath() {
-            System.err.println("getPlatformPath");
-            List<Path> result = new ArrayList<>();
-            fm.getLocationAsPaths(StandardLocation.PLATFORM_CLASS_PATH).forEach(p -> { result.add(p); });
-            return result;
+        public JavaFileManager getFileManager() {
+            System.err.println("getFileManager");
+            return fm;
         }
 
         @Override