diff -u new/src/java.base/share/classes/java/io/FilePermission.java new/src/java.base/share/classes/java/io/FilePermission.java
--- new/src/java.base/share/classes/java/io/FilePermission.java	2016-08-25 11:28:24.583447700 +0800
+++ new/src/java.base/share/classes/java/io/FilePermission.java	2016-09-01 22:20:56.770074200 +0800
@@ -33,8 +33,9 @@
 import java.util.StringJoiner;
 import java.util.Vector;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
 
+import jdk.internal.misc.JavaIOFilePermissionAccess;
+import jdk.internal.misc.SharedSecrets;
 import sun.nio.fs.DefaultFileSystemProvider;
 import sun.security.action.GetPropertyAction;
 import sun.security.util.FilePermCompat;
@@ -262,35 +263,32 @@
     }
 
     static {
-        FilePermCompat.newPermPlusAltPathFunction = new Function<>() {
-            @Override
-            public FilePermission apply(FilePermission input) {
-                if (input.npath2 == null && !input.allFiles) {
-                    Path npath2 = altPath(input.npath);
-                    if (npath2 != null) {
-                        FilePermission np = new FilePermission(input);
-                        np.npath2 = npath2;
-                        return np;
+        SharedSecrets.setJavaIOFilePermissionAccess(
+            new JavaIOFilePermissionAccess() {
+                public FilePermission newPermPlusAltPath(FilePermission input) {
+                    if (input.npath2 == null && !input.allFiles) {
+                        Path npath2 = altPath(input.npath);
+                        if (npath2 != null) {
+                            FilePermission np = new FilePermission(input);
+                            np.npath2 = npath2;
+                            return np;
+                        }
                     }
+                    return input;
                 }
-                return input;
-            }
-        };
-
-        FilePermCompat.newPermUsingAltPathFunction = new Function<>() {
-            @Override
-            public FilePermission apply(FilePermission input) {
-                if (!input.allFiles) {
-                    Path npath2 = altPath(input.npath);
-                    if (npath2 != null) {
-                        FilePermission np = new FilePermission(input);
-                        np.npath = npath2;
-                        return np;
+                public FilePermission newPermUsingAltPath(FilePermission input) {
+                    if (!input.allFiles) {
+                        Path npath2 = altPath(input.npath);
+                        if (npath2 != null) {
+                            FilePermission np = new FilePermission(input);
+                            np.npath = npath2;
+                            return np;
+                        }
                     }
+                    return null;
                 }
-                return null;
             }
-        };
+        );
     }
 
     /**
diff -u new/src/java.base/share/classes/java/security/AccessControlContext.java new/src/java.base/share/classes/java/security/AccessControlContext.java
--- new/src/java.base/share/classes/java/security/AccessControlContext.java	2016-08-25 11:28:32.274093700 +0800
+++ new/src/java.base/share/classes/java/security/AccessControlContext.java	2016-09-01 22:21:03.570121100 +0800
@@ -446,7 +446,7 @@
         }
 
         for (int i=0; i< context.length; i++) {
-            if (context[i] != null && !context[i].impliesWithAltFP(perm)) {
+            if (context[i] != null && !context[i].impliesWithAltFilePerm(perm)) {
                 if (dumpDebug) {
                     debug.println("access denied " + perm);
                 }
diff -u new/src/java.base/share/classes/java/security/ProtectionDomain.java new/src/java.base/share/classes/java/security/ProtectionDomain.java
--- new/src/java.base/share/classes/java/security/ProtectionDomain.java	2016-08-25 11:28:40.058188400 +0800
+++ new/src/java.base/share/classes/java/security/ProtectionDomain.java	2016-09-01 22:21:10.803595400 +0800
@@ -304,13 +304,11 @@
         }
 
         if (!staticPermissions &&
-                Policy.getPolicyNoCheck().implies(this, perm)) {
+            Policy.getPolicyNoCheck().implies(this, perm)) {
             return true;
         }
         if (permissions != null) {
-            if (permissions.implies(perm)) {
-                return true;
-            }
+            return permissions.implies(perm);
         }
 
         return false;
@@ -326,7 +324,7 @@
      * This method is called by {@link AccessControlContext#checkPermission}
      * and not intended to be called by an application.
      */
-    boolean impliesWithAltFP(Permission perm) {
+    boolean impliesWithAltFilePerm(Permission perm) {
 
         // If this is a subclass of ProtectionDomain. Call the old method.
         if (!FilePermCompat.compat || getClass() != ProtectionDomain.class) {
reverted:
--- new/src/java.base/share/classes/sun/security/util/IOUtils.java	2016-08-25 11:29:03.263792600 +0800
+++ old/src/java.base/share/classes/sun/security/util/IOUtils.java	2016-08-25 11:29:04.218108300 +0800
@@ -29,15 +29,10 @@
 
 package sun.security.util;
 
-import jdk.internal.misc.Unsafe;
-
 import java.io.EOFException;
-import java.io.FilePermission;
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.Permission;
 import java.util.Arrays;
-import java.util.function.Function;
 
 public class IOUtils {
 
diff -u new/src/java.base/share/classes/sun/security/util/FilePermCompat.java new/src/java.base/share/classes/sun/security/util/FilePermCompat.java
--- new/src/java.base/share/classes/sun/security/util/FilePermCompat.java	2016-08-25 11:29:45.937089100 +0800
+++ new/src/java.base/share/classes/sun/security/util/FilePermCompat.java	2016-09-01 22:22:15.945112900 +0800
@@ -25,26 +25,25 @@
 
 package sun.security.util;
 
-import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
 import java.io.FilePermission;
 import java.security.Permission;
-import java.util.function.Function;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * Take care of FilePermission compatibility after JDK-8164705.
  */
 public class FilePermCompat {
     /**
-     * New behavior? Default "new".
+     * New behavior? Keep compatibility? Both default true.
      */
     public static final boolean nb;
     public static final boolean compat;
 
     static {
         String flag = GetPropertyAction.privilegedGetProperty(
-                "jdk.filepermission.canonicalize", "compat");
+                "jdk.io.permissionsUseCanonicalPath", "false");
         switch (flag) {
             case "true":
                 nb = false;
@@ -52,51 +51,26 @@
                 break;
             case "false":
                 nb = true;
-                compat = false;
-                break;
-            case "compat":
-                nb = true;
                 compat = true;
                 break;
             default:
                 throw new RuntimeException(
-                        "Invalid jdk.filepermission.canonicalize: " + flag);
+                        "Invalid jdk.io.permissionsUseCanonicalPath: " + flag);
         }
     }
 
-    /**
-     * These fields will be initialized by FilePermission in a static
-     * block, so that they can access its internals.
-     */
-    public static Function<FilePermission,FilePermission>
-            newPermPlusAltPathFunction, newPermUsingAltPathFunction;
-
-    /**
-     * Returns a new FilePermission plus an alternative path.
-     *
-     * @param input the input
-     * @return the new FilePermission plus the alt path (as npath2)
-     *         or the input itself if no alt path is available.
-     */
     public static Permission newPermPlusAltPath(Permission input) {
         if (compat && input instanceof FilePermission) {
-            Unsafe.getUnsafe().ensureClassInitialized(FilePermission.class);
-            return newPermPlusAltPathFunction.apply((FilePermission) input);
+            return SharedSecrets.getJavaIOFilePermissionAccess()
+                    .newPermPlusAltPath((FilePermission) input);
         }
         return input;
     }
 
-    /**
-     * Returns a new FilePermission using an alternative path.
-     *
-     * @param input the input
-     * @return the new FilePermission using the alt path (as npath)
-     *         or null if no alt path is available
-     */
     public static Permission newPermUsingAltPath(Permission input) {
         if (input instanceof FilePermission) {
-            Unsafe.getUnsafe().ensureClassInitialized(FilePermission.class);
-            return newPermUsingAltPathFunction.apply((FilePermission) input);
+            return SharedSecrets.getJavaIOFilePermissionAccess()
+                    .newPermUsingAltPath((FilePermission) input);
         }
         return null;
     }
reverted:
--- new/test/java/io/FilePermission/samepath.sh	2016-08-25 11:29:58.095274900 +0800
+++ /dev/null	2016-08-25 11:29:59.000000000 +0800
@@ -1,139 +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.
-#
-
-# @test
-# @bug 8164705
-# @summary Still able to read file on the same path
-#
-# @run shell samepath.sh
-
-if [ "${TESTSRC}" = "" ] ; then
-   TESTSRC="."
-fi
-
-if [ "${TESTJAVA}" = "" ] ; then
-  JAVA_CMD=`which java`
-  TESTJAVA=`dirname $JAVA_CMD`/..
-fi
-
-JAVA="$TESTJAVA/bin/java -Djava.security.manager"
-JAVAC=$TESTJAVA/bin/javac
-JAR=$TESTJAVA/bin/jar
-
-if [ -f $TESTJAVA/bin/jlink ]; then
-    JAKE=true
-else
-    JAKE=false
-fi
-
-cat > App.java <<EOF
-package sp;
-import java.io.InputStream;
-import java.io.FileInputStream;
-public class App {
-    public static void main(String[] args) throws Exception {
-        boolean f = true;
-        StringBuilder sb = new StringBuilder();
-        String expected = null;
-        for (String s: args) {
-            if (expected == null) {
-                expected = s;
-            } else if (s.equals("-")) {
-                f = false;
-            } else if (f) {
-                try (InputStream is = new FileInputStream(s)) {
-                    is.readAllBytes();
-                    sb.append('+');
-                } catch (SecurityException se) {
-                    System.out.println(se);
-                    sb.append('S');
-                } catch (Exception e) {
-                    System.out.println(e);
-                    sb.append('-');
-                }
-            } else {
-                try (InputStream is = App.class.getResourceAsStream(s)) {
-                    is.readAllBytes();
-                    sb.append('+');
-                } catch (NullPointerException npe) {
-                    System.out.println(npe);
-                    sb.append('0');
-                } catch (Exception e) {
-                    System.out.println(e);
-                    sb.append('-');
-                }
-            }
-        }
-        if (!sb.toString().equals(expected)) {
-            throw new Exception("Expected " + expected + ", actually " + sb);
-        } else {
-            System.out.println("OK");
-        }
-    }
-}
-EOF
-
-cat > module-info.java <<EOF
-module sp {
-    exports sp;
-}
-EOF
-
-mkdir classes oldjar newjar
-mkdir -p m/sp
-
-$JAVAC -d classes App.java || exit 1
-rm classes/module-info.class 2> /dev/null
-echo base > classes/base
-echo child > classes/sp/child
-$JAR cvf oldjar/old.jar -C classes .
-
-if [ $JAKE = true ]; then
-    $JAVAC -d m/sp App.java module-info.java || exit 1
-    echo base > m/sp/base
-    echo child > m/sp/sp/child
-    $JAR cvf newjar/new.jar -C m/sp .
-fi
-
-$JAVA -cp classes sp.App S+++++ x classes/base classes/sp/child - child /base ../base || exit 1
-$JAVA -cp oldjar/old.jar sp.App S++0 classes/base - child /base ../base || exit 11
-if [ $JAKE = true ]; then
-    $JAVA -mp m -m sp/sp.App S+++++ m/sp m/sp/base m/sp/sp/child - child /base ../base || exit 21
-    $JAVA -mp newjar -m sp/sp.App SSS++0 m/sp m/sp/base m/sp/sp/child - child /base ../base || exit 31
-fi
-
-# For Windows, we also check viewing from another drive. Even if there is no
-# ALT_DRIVE: we can also check if C:x and x are the same file.
-
-# We do not support so much.
-if [ -f /usr/bin/cygpath---XXX ]; then
-    [ -d /cygdrive/d ] && ALT_DRIVE=D || ALT_DRIVE=C
-    JAVA=`cygpath -m $TESTJAVA`"/bin/java -Djava.security.manager"
-    cmd /c "$ALT_DRIVE: && $JAVA -cp C:classes sp.App S+++++ C:x C:classes/base C:classes/sp/child - child /base ../base" || exit 41
-    cmd /c "$ALT_DRIVE: && $JAVA -cp C:oldjar/old.jar sp.App S++0 C:classes/base - child /base ../base" || exit 51
-    if [ $JAKE = true ]; then
-        cmd /c "$ALT_DRIVE: && $JAVA -mp C:m -m sp/sp.App S+++++ C:m/sp C:m/sp/base C:m/sp/sp/child - child /base ../base" || exit 61
-        cmd /c "$ALT_DRIVE: && $JAVA -mp C:newjar -m sp/sp.App SSS++0 C:m/sp C:m/sp/base C:m/sp/sp/child - child /base ../base" || exit 71
-    fi
-fi
-echo Done
diff -u new/test/sun/security/util/FilePermCompat/Flag.java new/test/sun/security/util/FilePermCompat/Flag.java
--- new/test/sun/security/util/FilePermCompat/Flag.java	2016-08-25 11:30:10.694687200 +0800
+++ new/test/sun/security/util/FilePermCompat/Flag.java	2016-09-01 22:22:50.292834600 +0800
@@ -27,9 +27,8 @@
  * @summary check jdk.filepermission.canonicalize
  * @library /java/security/testlibrary/
  * @modules java.base/jdk.internal.misc
- * @run main/othervm -Djdk.filepermission.canonicalize=true Flag truetrue
- * @run main/othervm -Djdk.filepermission.canonicalize=false Flag falsefalse
- * @run main/othervm -Djdk.filepermission.canonicalize=compat Flag falsetrue
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=true Flag truetrue
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=false Flag falsetrue
  * @run main/othervm Flag falsetrue
  */
 
only in patch2:
unchanged:
--- old/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	2016-09-01 22:21:18.260490500 +0800
+++ new/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	2016-09-01 22:21:17.294984800 +0800
@@ -29,6 +29,7 @@
 import java.util.jar.JarFile;
 import java.io.Console;
 import java.io.FileDescriptor;
+import java.io.FilePermission;
 import java.io.ObjectInputStream;
 import java.io.RandomAccessFile;
 import java.security.ProtectionDomain;
@@ -58,6 +59,7 @@
     private static JavaNetSocketAccess javaNetSocketAccess;
     private static JavaNioAccess javaNioAccess;
     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
+    private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
     private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
     private static JavaSecurityAccess javaSecurityAccess;
     private static JavaUtilZipFileAccess javaUtilZipFileAccess;
@@ -201,6 +203,17 @@
         javaIOFileDescriptorAccess = jiofda;
     }
 
+    public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
+        if (javaIOFilePermissionAccess == null)
+            unsafe.ensureClassInitialized(FilePermission.class);
+
+        return javaIOFilePermissionAccess;
+    }
+
+    public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) {
+        javaIOFilePermissionAccess = jiofpa;
+    }
+
     public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
         if (javaIOFileDescriptorAccess == null)
             unsafe.ensureClassInitialized(FileDescriptor.class);
only in patch2:
unchanged:
--- /dev/null	2016-09-01 22:22:11.000000000 +0800
+++ new/src/java.base/share/classes/jdk/internal/misc/JavaIOFilePermissionAccess.java	2016-09-01 22:22:09.978471900 +0800
@@ -0,0 +1,48 @@
+/*
+ * 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.  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 jdk.internal.misc;
+
+import java.io.FilePermission;
+
+public interface JavaIOFilePermissionAccess {
+
+    /**
+     * Returns a new FilePermission plus an alternative path.
+     *
+     * @param input the input
+     * @return the new FilePermission plus the alt path (as npath2)
+     *         or the input itself if no alt path is available.
+     */
+    FilePermission newPermPlusAltPath(FilePermission input);
+
+    /**
+     * Returns a new FilePermission using an alternative path.
+     *
+     * @param input the input
+     * @return the new FilePermission using the alt path (as npath)
+     *         or null if no alt path is available
+     */
+    FilePermission newPermUsingAltPath(FilePermission input);
+}
only in patch2:
unchanged:
--- /dev/null	2016-09-01 22:22:28.000000000 +0800
+++ new/test/java/io/FilePermission/ReadFileOnPath.java	2016-09-01 22:22:27.359520300 +0800
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8164705
+ * @library /lib/testlibrary /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @run main ReadFileOnPath
+ * @summary Still able to read file on the same path
+ */
+
+import jdk.test.lib.process.ProcessTools;
+
+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.List;
+
+public class ReadFileOnPath {
+
+    private static final Path SRC_DIR    = Paths.get(System.getProperty("test.src"));
+    private static final Path HERE_DIR   = Paths.get(".");
+    private static final Path MODS_DIR   = Paths.get("modules");
+
+    public static void main(String args[]) throws Exception {
+        CompilerUtils.compile(SRC_DIR.resolve("m"), MODS_DIR.resolve("m"));
+        Files.write(MODS_DIR.resolve("m/base"), "base".getBytes());
+        Files.write(MODS_DIR.resolve("m/p/child"), "child".getBytes());
+        JarUtils.createJarFile(HERE_DIR.resolve("old.jar"),
+                MODS_DIR.resolve("m"),
+                "base", "p/App.class", "p/child");
+        JarUtils.createJarFile(HERE_DIR.resolve("new.jar"),
+                MODS_DIR.resolve("m"),
+                "module-info.class", "base", "p/App.class", "p/child");
+
+        // exploded module
+        test("--module-path", "modules", "-m", "m/p.App", "SS+++++");
+
+        // module in jar
+        test("--module-path", "new.jar", "-m", "m/p.App", "SSSS++0");
+
+        // exploded classpath
+        test("-cp", "modules/m", "p.App", "SS+++++");
+
+        // classpath in jar
+        test("-cp", "old.jar", "p.App", "SSSS++0");
+    }
+
+    static void test(String... args) throws Exception {
+        List<String> cmds = new ArrayList<>();
+        cmds.add("-Djava.security.manager");
+        cmds.addAll(Arrays.asList(args));
+        cmds.addAll(List.of(
+                "x", "modules/m", "modules/m/base", "modules/m/p/child",
+                "-", "child", "/base", "../base"));
+        ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()]))
+                .shouldHaveExitValue(0);
+    }
+}
only in patch2:
unchanged:
--- /dev/null	2016-09-01 22:22:34.000000000 +0800
+++ new/test/java/io/FilePermission/m/module-info.java	2016-09-01 22:22:33.180356500 +0800
@@ -0,0 +1,3 @@
+module m {
+    exports p;
+}
only in patch2:
unchanged:
--- /dev/null	2016-09-01 22:22:40.000000000 +0800
+++ new/test/java/io/FilePermission/m/p/App.java	2016-09-01 22:22:38.900011600 +0800
@@ -0,0 +1,44 @@
+package p;
+import java.io.InputStream;
+import java.io.FileInputStream;
+public class App {
+    public static void main(String[] args) throws Exception {
+        boolean f = true;
+        StringBuilder sb = new StringBuilder();
+        String expected = null;
+        for (String s: args) {
+            if (expected == null) {
+                expected = s;
+            } else if (s.equals("-")) {
+                f = false;
+            } else if (f) {
+                try (InputStream is = new FileInputStream(s)) {
+                    is.readAllBytes();
+                    sb.append('+');
+                } catch (SecurityException se) {
+                    System.out.println(se);
+                    sb.append('S');
+                } catch (Exception e) {
+                    System.out.println(e);
+                    sb.append('-');
+                }
+            } else {
+                try (InputStream is = App.class.getResourceAsStream(s)) {
+                    is.readAllBytes();
+                    sb.append('+');
+                } catch (NullPointerException npe) {
+                    System.out.println(npe);
+                    sb.append('0');
+                } catch (Exception e) {
+                    System.out.println(e);
+                    sb.append('-');
+                }
+            }
+        }
+        if (!sb.toString().equals(expected)) {
+            throw new Exception("Expected " + expected + ", actually " + sb);
+        } else {
+            System.out.println("OK");
+        }
+    }
+}