src/java.base/share/classes/java/net/URL.java

Print this page

        

@@ -266,10 +266,27 @@
      *     thrown from the {@code createURLStreamHandler}, if encountered, will
      *     be propagated to the calling thread. The {@code
      *     createURLStreamHandler} method of each provider, if instantiated, is
      *     invoked, with the protocol string, until a provider returns non-null,
      *     or all providers have been exhausted.
+     * <li>If the previous step fails to find a protocol handler, the
+     *     constructor reads the value of the system property:
+     *     <blockquote>{@code
+     *         java.protocol.handler.pkgs
+     *     }</blockquote>
+     *     If the value of that system property is not {@code null},
+     *     it is interpreted as a list of packages separated by a vertical
+     *     slash character '{@code |}'. The constructor tries to load
+     *     the class named:
+     *     <blockquote>{@code
+     *         <package>.<protocol>.Handler
+     *     }</blockquote>
+     *     where {@code <package>} is replaced by the name of the package
+     *     and {@code <protocol>} is replaced by the name of the protocol.
+     *     If this class does not exist, or if the class exists but it is not
+     *     a subclass of {@code URLStreamHandler}, then the next package
+     *     in the list is tried.
      * <li>If the previous step fails to find a protocol handler, then the
      *     constructor tries to load a built-in protocol handler.
      *     If this class does not exist, or if the class exists but it is not a
      *     subclass of {@code URLStreamHandler}, then a
      *     {@code MalformedURLException} is thrown.

@@ -1137,10 +1154,43 @@
             }
             return null;
         }
     }
 
+    private static URLStreamHandler lookupViaProperty(String protocol) {
+        String packagePrefixList = java.security.AccessController.doPrivileged(
+                new PrivilegedAction<String>() {
+                    public String run() {
+                        return System.getProperty(protocolPathProp, "");
+                    }
+                });
+        String[] packagePrefixes = packagePrefixList.split("\\|");
+
+        URLStreamHandler handler = null;
+        for (int i=0; handler == null && i<packagePrefixes.length; i++) {
+            String packagePrefix = packagePrefixes[i].trim();
+            try {
+                String clsName = packagePrefix + "." + protocol + ".Handler";
+                Class<?> cls = null;
+                try {
+                    cls = Class.forName(clsName);
+                } catch (ClassNotFoundException e) {
+                    ClassLoader cl = ClassLoader.getSystemClassLoader();
+                    if (cl != null) {
+                        cls = cl.loadClass(clsName);
+                    }
+                }
+                if (cls != null) {
+                    handler = (URLStreamHandler)cls.newInstance();
+                }
+            } catch (Exception e) {
+                // any number of exceptions can get thrown here
+            }
+        }
+        return handler;
+    }
+
     private static Iterator<URLStreamHandlerProvider> providers() {
         return new Iterator<URLStreamHandlerProvider>() {
 
             ClassLoader cl = ClassLoader.getSystemClassLoader();
             ServiceLoader<URLStreamHandlerProvider> sl =

@@ -1249,10 +1299,14 @@
             }
 
             if (handler == null && !protocol.equalsIgnoreCase("jar")) {
                 handler = lookupViaProviders(protocol);
             }
+
+            if (handler == null) {
+                handler = lookupViaProperty(protocol);
+            }
         }
 
         synchronized (streamHandlerLock) {
             if (handler == null) {
                 // Try the built-in protocol handler