changeset 12323:a78d16774e0b

8064925: URLConnection::getContent needs to be updated to work with modules Reviewed-by: chegar, alanb
author prappo
date Fri, 10 Jul 2015 16:40:12 +0100
parents 1c8bca2ebba1
children 9c2f63c20429
files src/java.base/share/classes/java/net/ContentHandler.java src/java.base/share/classes/java/net/ContentHandlerFactory.java src/java.base/share/classes/java/net/URLConnection.java src/java.desktop/share/classes/META-INF/services/java.net.ContentHandlerFactory src/java.desktop/share/classes/sun/awt/www/content/MultimediaContentHandlers.java src/java.desktop/share/classes/sun/awt/www/content/audio/aiff.java src/java.desktop/share/classes/sun/awt/www/content/audio/basic.java src/java.desktop/share/classes/sun/awt/www/content/audio/wav.java src/java.desktop/share/classes/sun/awt/www/content/audio/x_aiff.java src/java.desktop/share/classes/sun/awt/www/content/audio/x_wav.java src/java.desktop/share/classes/sun/awt/www/content/image/gif.java src/java.desktop/share/classes/sun/awt/www/content/image/jpeg.java src/java.desktop/share/classes/sun/awt/www/content/image/png.java src/java.desktop/share/classes/sun/awt/www/content/image/x_xbitmap.java src/java.desktop/share/classes/sun/awt/www/content/image/x_xpixmap.java src/java.desktop/share/classes/sun/net/www/content/audio/aiff.java src/java.desktop/share/classes/sun/net/www/content/audio/basic.java src/java.desktop/share/classes/sun/net/www/content/audio/wav.java src/java.desktop/share/classes/sun/net/www/content/audio/x_aiff.java src/java.desktop/share/classes/sun/net/www/content/audio/x_wav.java src/java.desktop/share/classes/sun/net/www/content/image/gif.java src/java.desktop/share/classes/sun/net/www/content/image/jpeg.java src/java.desktop/share/classes/sun/net/www/content/image/png.java src/java.desktop/share/classes/sun/net/www/content/image/x_xbitmap.java src/java.desktop/share/classes/sun/net/www/content/image/x_xpixmap.java test/java/net/URLConnection/ContentHandlers/ContentHandlersTest.java test/java/net/URLConnection/ContentHandlers/broken_constructor_factory.template test/java/net/URLConnection/ContentHandlers/broken_factory.template test/java/net/URLConnection/ContentHandlers/plain.template test/java/net/URLConnection/ContentHandlers/test.template
diffstat 30 files changed, 1250 insertions(+), 552 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/net/ContentHandler.java	Thu Jul 09 16:37:55 2015 -0700
+++ b/src/java.base/share/classes/java/net/ContentHandler.java	Fri Jul 10 16:40:12 2015 +0100
@@ -44,14 +44,14 @@
  * instance of a subclass of {@code ContentHandler}, and its
  * {@code getContent} method is called to create the object.
  * <p>
- * If no content handler could be found, URLConnection will
- * look for a content handler in a user-defineable set of places.
+ * If no content handler could be {@linkplain URLConnection#getContent() found},
+ * URLConnection will look for a content handler in a user-definable set of places.
  * Users can define a vertical-bar delimited set of class prefixes
- * to search through by defining the <i>java.content.handler.pkgs</i>
+ * to search through by defining the <i>{@value java.net.URLConnection#contentPathProp}</i>
  * property. The class name must be of the form:
  * <blockquote>
  *     <i>{package-prefix}.{major}.{minor}</i>
- *     <P>
+ *     <p>
  *     where <i>{major}.{minor}</i> is formed by taking the
  *     content-type string, replacing all slash characters with a
  *     {@code period} ('.'), and all other non-alphanumeric characters
@@ -82,6 +82,7 @@
  * @since   1.0
  */
 abstract public class ContentHandler {
+
     /**
      * Given a URL connect stream positioned at the beginning of the
      * representation of an object, this method reads that stream and
@@ -104,8 +105,8 @@
      * @param      urlc   a URL connection.
      * @param      classes      an array of types requested
      * @return     the object read by the {@code ContentHandler} that is
-     *                 the first match of the suggested types.
-     *                 null if none of the requested  are supported.
+     *                 the first match of the suggested types or
+     *                 {@code null} if none of the requested  are supported.
      * @exception  IOException  if an I/O error occurs while reading the object.
      * @since 1.3
      */
@@ -113,12 +114,11 @@
     public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
         Object obj = getContent(urlc);
 
-        for (int i = 0; i < classes.length; i++) {
-          if (classes[i].isInstance(obj)) {
+        for (Class<?> c : classes) {
+            if (c.isInstance(obj)) {
                 return obj;
-          }
+            }
         }
         return null;
     }
-
 }
--- a/src/java.base/share/classes/java/net/ContentHandlerFactory.java	Thu Jul 09 16:37:55 2015 -0700
+++ b/src/java.base/share/classes/java/net/ContentHandlerFactory.java	Fri Jul 10 16:40:12 2015 +0100
@@ -39,12 +39,13 @@
  * @since   1.0
  */
 public interface ContentHandlerFactory {
+
     /**
      * Creates a new {@code ContentHandler} to read an object from
      * a {@code URLStreamHandler}.
      *
      * @param   mimetype   the MIME type for which a content handler is desired.
-
+     *
      * @return  a new {@code ContentHandler} to read an object from a
      *          {@code URLStreamHandler}.
      * @see     java.net.ContentHandler
--- a/src/java.base/share/classes/java/net/URLConnection.java	Thu Jul 09 16:37:55 2015 -0700
+++ b/src/java.base/share/classes/java/net/URLConnection.java	Fri Jul 10 16:40:12 2015 +0100
@@ -28,8 +28,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.security.PrivilegedAction;
 import java.util.Hashtable;
 import java.util.Date;
+import java.util.Iterator;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
 import java.util.StringTokenizer;
 import java.util.Collections;
 import java.util.Map;
@@ -107,7 +111,7 @@
  *   <li>{@code getContentType}
  *   <li>{@code getDate}
  *   <li>{@code getExpiration}
- *   <li>{@code getLastModifed}
+ *   <li>{@code getLastModified}
  * </ul>
  * <p>
  * provide convenient access to these fields. The
@@ -695,16 +699,30 @@
      * This method first determines the content type of the object by
      * calling the {@code getContentType} method. If this is
      * the first time that the application has seen that specific content
-     * type, a content handler for that content type is created:
+     * type, a content handler for that content type is created.
+     * <p> This is done as follows:
      * <ol>
      * <li>If the application has set up a content handler factory instance
      *     using the {@code setContentHandlerFactory} method, the
      *     {@code createContentHandler} method of that instance is called
      *     with the content type as an argument; the result is a content
      *     handler for that content type.
-     * <li>If no content handler factory has yet been set up, or if the
-     *     factory's {@code createContentHandler} method returns
-     *     {@code null}, then this method tries to load a content handler
+     * <li>If no {@code ContentHandlerFactory} has yet been set up,
+     *     or if the factory's {@code createContentHandler} method
+     *     returns {@code null}, then the {@linkplain java.util.ServiceLoader
+     *     ServiceLoader} mechanism is used to locate {@linkplain
+     *     java.net.ContentHandlerFactory ContentHandlerFactory}
+     *     implementations using the system class
+     *     loader. The order that factories are located is implementation
+     *     specific, and an implementation is free to cache the located
+     *     factories. A {@linkplain java.util.ServiceConfigurationError
+     *     ServiceConfigurationError}, {@code Error} or {@code RuntimeException}
+     *     thrown from the {@code createContentHandler}, if encountered, will
+     *     be propagated to the calling thread. The {@code
+     *     createContentHandler} method of each factory, if instantiated, is
+     *     invoked, with the content type, until a factory returns non-null,
+     *     or all factories have been exhausted.
+     * <li>Failing that, this method tries to load a content handler
      *     class as defined by {@link java.net.ContentHandler ContentHandler}.
      *     If the class does not exist, or is not a subclass of {@code
      *     ContentHandler}, then an {@code UnknownServiceException} is thrown.
@@ -855,8 +873,7 @@
      * @see #getDoInput()
      */
     public void setDoInput(boolean doinput) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         doInput = doinput;
     }
 
@@ -885,8 +902,7 @@
      * @see #getDoOutput()
      */
     public void setDoOutput(boolean dooutput) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         doOutput = dooutput;
     }
 
@@ -911,8 +927,7 @@
      * @see     #getAllowUserInteraction()
      */
     public void setAllowUserInteraction(boolean allowuserinteraction) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         allowUserInteraction = allowuserinteraction;
     }
 
@@ -974,8 +989,7 @@
      * @see #getUseCaches()
      */
     public void setUseCaches(boolean usecaches) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         useCaches = usecaches;
     }
 
@@ -1000,8 +1014,7 @@
      * @see     #getIfModifiedSince()
      */
     public void setIfModifiedSince(long ifmodifiedsince) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         ifModifiedSince = ifmodifiedsince;
     }
 
@@ -1055,12 +1068,11 @@
      *                  (e.g., "{@code Accept}").
      * @param   value   the value associated with it.
      * @throws IllegalStateException if already connected
-     * @throws NullPointerException if key is <CODE>null</CODE>
+     * @throws NullPointerException if key is {@code null}
      * @see #getRequestProperty(java.lang.String)
      */
     public void setRequestProperty(String key, String value) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         if (key == null)
             throw new NullPointerException ("key is null");
 
@@ -1084,8 +1096,7 @@
      * @since 1.4
      */
     public void addRequestProperty(String key, String value) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
         if (key == null)
             throw new NullPointerException ("key is null");
 
@@ -1107,8 +1118,7 @@
      * @see #setRequestProperty(java.lang.String, java.lang.String)
      */
     public String getRequestProperty(String key) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
 
         if (requests == null)
             return null;
@@ -1129,8 +1139,7 @@
      * @since 1.4
      */
     public Map<String,List<String>> getRequestProperties() {
-        if (connected)
-            throw new IllegalStateException("Already connected");
+        checkConnected();
 
         if (requests == null)
             return Collections.emptyMap();
@@ -1183,7 +1192,7 @@
     /**
      * The ContentHandler factory.
      */
-    static ContentHandlerFactory factory;
+    private static volatile ContentHandlerFactory factory;
 
     /**
      * Sets the {@code ContentHandlerFactory} of an
@@ -1216,37 +1225,45 @@
         factory = fac;
     }
 
-    private static Hashtable<String, ContentHandler> handlers = new Hashtable<>();
+    private static final Hashtable<String, ContentHandler> handlers = new Hashtable<>();
 
     /**
      * Gets the Content Handler appropriate for this connection.
      */
-    synchronized ContentHandler getContentHandler()
-        throws UnknownServiceException
-    {
+    private ContentHandler getContentHandler() throws UnknownServiceException {
         String contentType = stripOffParameters(getContentType());
-        ContentHandler handler = null;
-        if (contentType == null)
+        if (contentType == null) {
             throw new UnknownServiceException("no content-type");
-        try {
-            handler = handlers.get(contentType);
+        }
+
+        ContentHandler handler = handlers.get(contentType);
+        if (handler != null)
+            return handler;
+
+        if (factory != null) {
+            handler = factory.createContentHandler(contentType);
             if (handler != null)
                 return handler;
-        } catch(Exception e) {
         }
 
-        if (factory != null)
-            handler = factory.createContentHandler(contentType);
-        if (handler == null) {
-            try {
-                handler = lookupContentHandlerClassFor(contentType);
-            } catch(Exception e) {
-                e.printStackTrace();
-                handler = UnknownContentHandler.INSTANCE;
-            }
-            handlers.put(contentType, handler);
+        handler = lookupContentHandlerViaProvider(contentType);
+
+        if (handler != null) {
+            ContentHandler h = handlers.putIfAbsent(contentType, handler);
+            return h != null ? h : handler;
         }
-        return handler;
+
+        try {
+            handler = lookupContentHandlerClassFor(contentType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            handler = UnknownContentHandler.INSTANCE;
+        }
+
+        assert handler != null;
+
+        ContentHandler h = handlers.putIfAbsent(contentType, handler);
+        return h != null ? h : handler;
     }
 
     /*
@@ -1270,10 +1287,10 @@
     private static final String contentPathProp = "java.content.handler.pkgs";
 
     /**
-     * Looks for a content handler in a user-defineable set of places.
-     * By default it looks in sun.net.www.content, but users can define a
-     * vertical-bar delimited set of class prefixes to search through in
-     * addition by defining the java.content.handler.pkgs property.
+     * Looks for a content handler in a user-definable set of places.
+     * By default it looks in {@value #contentClassPrefix}, but users can define
+     * a vertical-bar delimited set of class prefixes to search through in
+     * addition by defining the {@value #contentPathProp} property.
      * The class name must be of the form:
      * <pre>
      *     {package-prefix}.{major}.{minor}
@@ -1281,11 +1298,10 @@
      *     YoyoDyne.experimental.text.plain
      * </pre>
      */
-    private ContentHandler lookupContentHandlerClassFor(String contentType)
-        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+    private ContentHandler lookupContentHandlerClassFor(String contentType) {
         String contentHandlerClassName = typeToPackageName(contentType);
 
-        String contentHandlerPkgPrefixes =getContentHandlerPkgPrefixes();
+        String contentHandlerPkgPrefixes = getContentHandlerPkgPrefixes();
 
         StringTokenizer packagePrefixIter =
             new StringTokenizer(contentHandlerPkgPrefixes, "|");
@@ -1305,17 +1321,46 @@
                     }
                 }
                 if (cls != null) {
-                    ContentHandler handler =
-                        (ContentHandler)cls.newInstance();
-                    return handler;
+                    return (ContentHandler) cls.newInstance();
                 }
-            } catch(Exception e) {
-            }
+            } catch(Exception ignored) { }
         }
 
         return UnknownContentHandler.INSTANCE;
     }
 
+    private ContentHandler lookupContentHandlerViaProvider(String contentType) {
+        return AccessController.doPrivileged(
+                new PrivilegedAction<>() {
+                    @Override
+                    public ContentHandler run() {
+                        ClassLoader cl = ClassLoader.getSystemClassLoader();
+                        ServiceLoader<ContentHandlerFactory> sl =
+                                ServiceLoader.load(ContentHandlerFactory.class, cl);
+
+                        Iterator<ContentHandlerFactory> iterator = sl.iterator();
+
+                        ContentHandler handler = null;
+                        while (iterator.hasNext()) {
+                            ContentHandlerFactory f;
+                            try {
+                                f = iterator.next();
+                            } catch (ServiceConfigurationError e) {
+                                if (e.getCause() instanceof SecurityException) {
+                                    continue;
+                                }
+                                throw e;
+                            }
+                            handler = f.createContentHandler(contentType);
+                            if (handler != null) {
+                                break;
+                            }
+                        }
+                        return handler;
+                    }
+                });
+    }
+
     /**
      * Utility function to map a MIME content type into an equivalent
      * pair of class name components.  For example: "text/html" would
@@ -1345,8 +1390,8 @@
      * Returns a vertical bar separated list of package prefixes for potential
      * content handlers.  Tries to get the java.content.handler.pkgs property
      * to use as a set of package prefixes to search.  Whether or not
-     * that property has been defined, the sun.net.www.content is always
-     * the last one on the returned package list.
+     * that property has been defined, the {@value #contentClassPrefix}
+     * is always the last one on the returned package list.
      */
     private String getContentHandlerPkgPrefixes() {
         String packagePrefixList = AccessController.doPrivileged(
@@ -1764,9 +1809,12 @@
         return skipped;
     }
 
+    private void checkConnected() {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+    }
 }
 
-
 class UnknownContentHandler extends ContentHandler {
     static final ContentHandler INSTANCE = new UnknownContentHandler();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/META-INF/services/java.net.ContentHandlerFactory	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  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.
+#
+
+# Provider for content handlers
+sun.awt.www.content.MultimediaContentHandlers
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/MultimediaContentHandlers.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 sun.awt.www.content;
+
+import sun.awt.www.content.audio.wav;
+import sun.awt.www.content.audio.x_aiff;
+import sun.awt.www.content.image.gif;
+import sun.awt.www.content.audio.aiff;
+import sun.awt.www.content.audio.basic;
+import sun.awt.www.content.audio.x_wav;
+import sun.awt.www.content.image.jpeg;
+import sun.awt.www.content.image.png;
+import sun.awt.www.content.image.x_xbitmap;
+import sun.awt.www.content.image.x_xpixmap;
+
+import java.net.ContentHandler;
+import java.net.ContentHandlerFactory;
+
+public final class MultimediaContentHandlers implements ContentHandlerFactory {
+
+    @Override
+    public ContentHandler createContentHandler(String mimetype) {
+        switch (mimetype) {
+            case "audio/aiff":      return new aiff();
+            case "audio/basic":     return new basic();
+            case "audio/wav":       return new wav();
+            case "audio/x-aiff":    return new x_aiff();
+            case "audio/x-wav":     return new x_wav();
+            case "image/gif":       return new gif();
+            case "image/jpeg":      return new jpeg();
+            case "image/png":       return new png();
+            case "image/x-xbitmap": return new x_xbitmap();
+            case "image/x-xpixmap": return new x_xpixmap();
+            default:                return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/audio/aiff.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/**
+ * Basic .aiff audio handler.
+ * @author  Jeff Nisewanger
+ */
+package sun.awt.www.content.audio;
+
+import java.net.*;
+import java.io.IOException;
+import sun.applet.AppletAudioClip;
+
+/**
+ * Returns an AppletAudioClip object.
+ */
+public class aiff extends ContentHandler {
+    public Object getContent(URLConnection uc) throws IOException {
+        return new AppletAudioClip(uc);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/audio/basic.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/**
+ * Basic .au and .snd audio handler.
+ * @author  Jeff Nisewanger
+ */
+package sun.awt.www.content.audio;
+
+import java.net.*;
+import java.io.IOException;
+import sun.applet.AppletAudioClip;
+
+/**
+ * Returns an AppletAudioClip object.
+ * This provides backwards compatibility with the behavior
+ * of ClassLoader.getResource().getContent() on JDK1.1.
+ */
+public class basic extends ContentHandler {
+    public Object getContent(URLConnection uc) throws IOException {
+        return new AppletAudioClip(uc);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/audio/wav.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/**
+ * Basic .wav audio handler.
+ * @author  Jeff Nisewanger
+ */
+package sun.awt.www.content.audio;
+
+import java.net.*;
+import java.io.IOException;
+import sun.applet.AppletAudioClip;
+
+/**
+ * Returns an AppletAudioClip object.
+ */
+public class wav extends ContentHandler {
+    public Object getContent(URLConnection uc) throws IOException {
+        return new AppletAudioClip(uc);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/audio/x_aiff.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/**
+ * Basic .aiff audio handler.
+ * @author  Jeff Nisewanger
+ */
+package sun.awt.www.content.audio;
+
+import java.net.*;
+import java.io.IOException;
+import sun.applet.AppletAudioClip;
+
+/**
+ * Returns an AppletAudioClip object.
+ */
+public class x_aiff extends ContentHandler {
+    public Object getContent(URLConnection uc) throws IOException {
+        return new AppletAudioClip(uc);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/audio/x_wav.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/**
+ * Basic .wav audio handler.
+ * @author  Jeff Nisewanger
+ */
+package sun.awt.www.content.audio;
+
+import java.net.*;
+import java.io.IOException;
+import sun.applet.AppletAudioClip;
+
+/**
+ * Returns an AppletAudioClip object.
+ */
+public class x_wav extends ContentHandler {
+    public Object getContent(URLConnection uc) throws IOException {
+        return new AppletAudioClip(uc);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/image/gif.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1994, 2013, 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 sun.awt.www.content.image;
+
+import java.net.*;
+import sun.awt.image.*;
+import java.io.IOException;
+import java.awt.Image;
+import java.awt.Toolkit;
+
+
+public class gif extends ContentHandler {
+    public Object getContent(URLConnection urlc) throws java.io.IOException {
+        return new URLImageSource(urlc);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
+        Class<?>[] cls = classes;
+        for (int i = 0; i < cls.length; i++) {
+            if (cls[i].isAssignableFrom(URLImageSource.class)) {
+                return new URLImageSource(urlc);
+            }
+            if (cls[i].isAssignableFrom(Image.class)) {
+                Toolkit tk = Toolkit.getDefaultToolkit();
+                return tk.createImage(new URLImageSource(urlc));
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/image/jpeg.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 2013, 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 sun.awt.www.content.image;
+
+import java.net.*;
+import sun.awt.image.*;
+import java.io.IOException;
+import java.awt.Image;
+import java.awt.Toolkit;
+
+public class jpeg extends ContentHandler {
+    public Object getContent(URLConnection urlc) throws java.io.IOException {
+        return new URLImageSource(urlc);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
+        Class<?>[] cls = classes;
+        for (int i = 0; i < cls.length; i++) {
+            if (cls[i].isAssignableFrom(URLImageSource.class)) {
+                return new URLImageSource(urlc);
+            }
+            if (cls[i].isAssignableFrom(Image.class)) {
+                Toolkit tk = Toolkit.getDefaultToolkit();
+                return tk.createImage(new URLImageSource(urlc));
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/image/png.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1999, 2013, 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 sun.awt.www.content.image;
+
+import java.net.*;
+import java.io.IOException;
+import sun.awt.image.*;
+import java.awt.Image;
+import java.awt.Toolkit;
+
+public class png extends ContentHandler {
+    public Object getContent(URLConnection urlc) throws java.io.IOException {
+        return new URLImageSource(urlc);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
+        Class<?>[] cls = classes;
+        for (int i = 0; i < cls.length; i++) {
+            if (cls[i].isAssignableFrom(URLImageSource.class)) {
+                return new URLImageSource(urlc);
+            }
+            if (cls[i].isAssignableFrom(Image.class)) {
+                Toolkit tk = Toolkit.getDefaultToolkit();
+                return tk.createImage(new URLImageSource(urlc));
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/image/x_xbitmap.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1994, 2013, 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 sun.awt.www.content.image;
+
+import java.net.*;
+import sun.awt.image.*;
+import java.awt.Image;
+import java.awt.Toolkit;
+
+public class x_xbitmap extends ContentHandler {
+    public Object getContent(URLConnection urlc) throws java.io.IOException {
+        return new URLImageSource(urlc);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Object getContent(URLConnection urlc, Class[] classes) throws java.io.IOException {
+        Class<?>[] cls = classes;
+        for (int i = 0; i < cls.length; i++) {
+            if (cls[i].isAssignableFrom(URLImageSource.class)) {
+                return new URLImageSource(urlc);
+            }
+            if (cls[i].isAssignableFrom(Image.class)) {
+                Toolkit tk = Toolkit.getDefaultToolkit();
+                return tk.createImage(new URLImageSource(urlc));
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/www/content/image/x_xpixmap.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1994, 2013, 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 sun.awt.www.content.image;
+
+import java.net.*;
+import sun.awt.image.*;
+import java.awt.Image;
+import java.awt.Toolkit;
+
+public class x_xpixmap extends ContentHandler {
+    public Object getContent(URLConnection urlc) throws java.io.IOException {
+        return new URLImageSource(urlc);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Object getContent(URLConnection urlc, Class[] classes) throws java.io.IOException {
+        Class<?>[] cls = classes;
+        for (int i = 0; i < cls.length; i++) {
+            if (cls[i].isAssignableFrom(URLImageSource.class)) {
+                return new URLImageSource(urlc);
+            }
+            if (cls[i].isAssignableFrom(Image.class)) {
+                Toolkit tk = Toolkit.getDefaultToolkit();
+                return tk.createImage(new URLImageSource(urlc));
+            }
+        }
+        return null;
+    }
+}
--- a/src/java.desktop/share/classes/sun/net/www/content/audio/aiff.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/**
- * Basic .aiff audio handler.
- * @author  Jeff Nisewanger
- */
-package sun.net.www.content.audio;
-
-import java.net.*;
-import java.io.IOException;
-import sun.applet.AppletAudioClip;
-
-/**
- * Returns an AppletAudioClip object.
- */
-public class aiff extends ContentHandler {
-    public Object getContent(URLConnection uc) throws IOException {
-        return new AppletAudioClip(uc);
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/audio/basic.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/**
- * Basic .au and .snd audio handler.
- * @author  Jeff Nisewanger
- */
-package sun.net.www.content.audio;
-
-import java.net.*;
-import java.io.IOException;
-import sun.applet.AppletAudioClip;
-
-/**
- * Returns an AppletAudioClip object.
- * This provides backwards compatibility with the behavior
- * of ClassLoader.getResource().getContent() on JDK1.1.
- */
-public class basic extends ContentHandler {
-    public Object getContent(URLConnection uc) throws IOException {
-        return new AppletAudioClip(uc);
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/audio/wav.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/**
- * Basic .wav audio handler.
- * @author  Jeff Nisewanger
- */
-package sun.net.www.content.audio;
-
-import java.net.*;
-import java.io.IOException;
-import sun.applet.AppletAudioClip;
-
-/**
- * Returns an AppletAudioClip object.
- */
-public class wav extends ContentHandler {
-    public Object getContent(URLConnection uc) throws IOException {
-        return new AppletAudioClip(uc);
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/audio/x_aiff.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/**
- * Basic .aiff audio handler.
- * @author  Jeff Nisewanger
- */
-package sun.net.www.content.audio;
-
-import java.net.*;
-import java.io.IOException;
-import sun.applet.AppletAudioClip;
-
-/**
- * Returns an AppletAudioClip object.
- */
-public class x_aiff extends ContentHandler {
-    public Object getContent(URLConnection uc) throws IOException {
-        return new AppletAudioClip(uc);
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/audio/x_wav.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/**
- * Basic .wav audio handler.
- * @author  Jeff Nisewanger
- */
-package sun.net.www.content.audio;
-
-import java.net.*;
-import java.io.IOException;
-import sun.applet.AppletAudioClip;
-
-/**
- * Returns an AppletAudioClip object.
- */
-public class x_wav extends ContentHandler {
-    public Object getContent(URLConnection uc) throws IOException {
-        return new AppletAudioClip(uc);
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/image/gif.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1994, 2013, 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 sun.net.www.content.image;
-
-import java.net.*;
-import sun.awt.image.*;
-import java.io.IOException;
-import java.awt.Image;
-import java.awt.Toolkit;
-
-
-public class gif extends ContentHandler {
-    public Object getContent(URLConnection urlc) throws java.io.IOException {
-        return new URLImageSource(urlc);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
-        Class<?>[] cls = classes;
-        for (int i = 0; i < cls.length; i++) {
-            if (cls[i].isAssignableFrom(URLImageSource.class)) {
-                return new URLImageSource(urlc);
-            }
-            if (cls[i].isAssignableFrom(Image.class)) {
-                Toolkit tk = Toolkit.getDefaultToolkit();
-                return tk.createImage(new URLImageSource(urlc));
-            }
-        }
-        return null;
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/image/jpeg.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 1995, 2013, 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 sun.net.www.content.image;
-
-import java.net.*;
-import sun.awt.image.*;
-import java.io.IOException;
-import java.awt.Image;
-import java.awt.Toolkit;
-
-public class jpeg extends ContentHandler {
-    public Object getContent(URLConnection urlc) throws java.io.IOException {
-        return new URLImageSource(urlc);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
-        Class<?>[] cls = classes;
-        for (int i = 0; i < cls.length; i++) {
-            if (cls[i].isAssignableFrom(URLImageSource.class)) {
-                return new URLImageSource(urlc);
-            }
-            if (cls[i].isAssignableFrom(Image.class)) {
-                Toolkit tk = Toolkit.getDefaultToolkit();
-                return tk.createImage(new URLImageSource(urlc));
-            }
-        }
-        return null;
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/image/png.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, 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 sun.net.www.content.image;
-
-import java.net.*;
-import java.io.IOException;
-import sun.awt.image.*;
-import java.awt.Image;
-import java.awt.Toolkit;
-
-public class png extends ContentHandler {
-    public Object getContent(URLConnection urlc) throws java.io.IOException {
-        return new URLImageSource(urlc);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
-        Class<?>[] cls = classes;
-        for (int i = 0; i < cls.length; i++) {
-            if (cls[i].isAssignableFrom(URLImageSource.class)) {
-                return new URLImageSource(urlc);
-            }
-            if (cls[i].isAssignableFrom(Image.class)) {
-                Toolkit tk = Toolkit.getDefaultToolkit();
-                return tk.createImage(new URLImageSource(urlc));
-            }
-        }
-        return null;
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/image/x_xbitmap.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1994, 2013, 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 sun.net.www.content.image;
-
-import java.net.*;
-import sun.awt.image.*;
-import java.awt.Image;
-import java.awt.Toolkit;
-
-public class x_xbitmap extends ContentHandler {
-    public Object getContent(URLConnection urlc) throws java.io.IOException {
-        return new URLImageSource(urlc);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public Object getContent(URLConnection urlc, Class[] classes) throws java.io.IOException {
-        Class<?>[] cls = classes;
-        for (int i = 0; i < cls.length; i++) {
-            if (cls[i].isAssignableFrom(URLImageSource.class)) {
-                return new URLImageSource(urlc);
-            }
-            if (cls[i].isAssignableFrom(Image.class)) {
-                Toolkit tk = Toolkit.getDefaultToolkit();
-                return tk.createImage(new URLImageSource(urlc));
-            }
-        }
-        return null;
-    }
-}
--- a/src/java.desktop/share/classes/sun/net/www/content/image/x_xpixmap.java	Thu Jul 09 16:37:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1994, 2013, 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 sun.net.www.content.image;
-
-import java.net.*;
-import sun.awt.image.*;
-import java.awt.Image;
-import java.awt.Toolkit;
-
-public class x_xpixmap extends ContentHandler {
-    public Object getContent(URLConnection urlc) throws java.io.IOException {
-        return new URLImageSource(urlc);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public Object getContent(URLConnection urlc, Class[] classes) throws java.io.IOException {
-        Class<?>[] cls = classes;
-        for (int i = 0; i < cls.length; i++) {
-            if (cls[i].isAssignableFrom(URLImageSource.class)) {
-                return new URLImageSource(urlc);
-            }
-            if (cls[i].isAssignableFrom(Image.class)) {
-                Toolkit tk = Toolkit.getDefaultToolkit();
-                return tk.createImage(new URLImageSource(urlc));
-            }
-        }
-        return null;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/URLConnection/ContentHandlers/ContentHandlersTest.java	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.SequenceInputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+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.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singleton;
+import static java.util.Collections.singletonMap;
+
+/*
+ * @test
+ * @bug 8064925
+ * @summary Basic test for ContentHandler. Ensures discovery paths for content
+ *          handlers follow a particular order.
+ */
+public class ContentHandlersTest {
+
+    public static void main(String[] args) throws Throwable {
+        step1_ContentHandlerFactory();
+        step2_ServiceLoader();
+        step3_UserDefined();
+        step4_BuiltIn();
+    }
+
+    private static void step1_ContentHandlerFactory() throws IOException {
+        String factoryClassFqn = "net.java.openjdk.test.TestContentHandlerFactory";
+
+        Path tmp = Files.createDirectory(Paths.get("ContentHandlersTest-1"));
+
+        Path src = templatesHome().resolve("test.template");
+        Path dst = tmp.resolve("Test.java");
+        Files.copy(src, dst);
+
+        Path build = Files.createDirectory(tmp.resolve("build"));
+
+        Path dst1 = fromTemplate(templatesHome().resolve("broken_factory.template"),
+                factoryClassFqn, tmp);
+
+        javac(build, dst, dst1);
+
+        Result r = java(emptyMap(), singleton(build), "Test", factoryClassFqn);
+
+        if (r.exitValue == 0 || !r.output.startsWith(
+                stackTraceStringForBrokenFactory(factoryClassFqn))) {
+            throw new RuntimeException(
+                    "Expected a different kind of failure: " + r.output);
+        }
+    }
+
+    private static void step2_ServiceLoader() throws IOException {
+        String factoryClassFqn = "net.java.openjdk.test.TestContentHandlerFactory";
+
+        Path tmp = Files.createDirectory(Paths.get("ContentHandlersTest-2"));
+
+        Path src = templatesHome().resolve("test.template");
+        Path dst = tmp.resolve("Test.java");
+        Files.copy(src, dst);
+
+        Path dst1 = fromTemplate(templatesHome().resolve("broken_constructor_factory.template"),
+                factoryClassFqn, tmp);
+
+        Path build = Files.createDirectory(tmp.resolve("build"));
+
+        javac(build, dst);
+
+        Path explodedJar = Files.createDirectory(tmp.resolve("exploded-jar"));
+        Path services = Files.createDirectories(explodedJar.resolve("META-INF")
+                .resolve("services"));
+
+        Path s = services.resolve("java.net.ContentHandlerFactory");
+
+        try (FileWriter fw = new FileWriter(s.toFile())) {
+            fw.write(factoryClassFqn);
+        }
+
+        javac(explodedJar, dst1);
+        jar(tmp.resolve("test.jar"), explodedJar);
+
+        Files.copy(tmp.resolve("test.jar"), build.resolve("test.jar"));
+
+        Result r = java(emptyMap(), asList(build.resolve("test.jar"), build), "Test");
+
+        if (r.exitValue == 0 || !verifyOutput(r.output, factoryClassFqn))
+            throw new RuntimeException(r.output);
+    }
+
+    private static void step3_UserDefined() throws IOException {
+        String packagePrefix = "net.java.openjdk.test";
+        String fqn = packagePrefix + ".text.plain";
+
+        Path tmp = Files.createDirectory(Paths.get("ContentHandlersTest-3"));
+
+        Path src = templatesHome().resolve("test.template");
+        Path dst = tmp.resolve("Test.java");
+        Files.copy(src, dst);
+
+        Path dst1 = fromTemplate(templatesHome().resolve("plain.template"),
+                fqn, tmp);
+
+        Path build = Files.createDirectory(tmp.resolve("build"));
+
+        javac(build, dst);
+
+        Path classes = Files.createDirectory(tmp.resolve("classes"));
+
+        javac(classes, dst1);
+
+        Map<String, String> m = singletonMap("java.content.handler.pkgs", packagePrefix);
+        Result r = java(m, asList(build, classes), "Test");
+
+        if (r.exitValue != 0 || !r.output.contains(fqn))
+            throw new RuntimeException(r.output);
+    }
+
+    private static void step4_BuiltIn() throws IOException {
+        Path tmp = Files.createDirectory(Paths.get("ContentHandlersTest-4"));
+
+        Path src = templatesHome().resolve("test.template");
+        Path dst = tmp.resolve("Test.java");
+        Files.copy(src, dst);
+
+        Path build = Files.createDirectory(tmp.resolve("build"));
+
+        javac(build, dst);
+
+        Result r = java(emptyMap(), singleton(build), "Test");
+
+        if (r.exitValue != 0 || !r.output.contains("sun.net.www.content.text.PlainTextInputStream"))
+            throw new RuntimeException(r.output);
+    }
+
+    private static String stackTraceStringForBrokenFactory(String fqn) {
+        return "Exception in thread \"main\" java.lang.RuntimeException: " +
+                "This is a broken factory. It is supposed to throw this exception.";
+    }
+
+    private static Path fromTemplate(Path srcTemplate,
+                                     String factoryFqn,
+                                     Path dstFolder) throws IOException {
+
+        String factorySimpleName, packageName;
+        int i = factoryFqn.lastIndexOf('.');
+        if (i < 0) {
+            packageName = "";
+            factorySimpleName = factoryFqn;
+        } else {
+            packageName = factoryFqn.substring(0, i);
+            factorySimpleName = factoryFqn.substring(i + 1);
+        }
+
+        Path result = dstFolder.resolve(factorySimpleName + ".java");
+        File dst = result.toFile();
+        File src = srcTemplate.toFile();
+        try (BufferedReader r = new BufferedReader(new FileReader(src));
+             BufferedWriter w = new BufferedWriter(new FileWriter(dst))) {
+
+            List<String> lines = processTemplate(packageName, factorySimpleName,
+                    r.lines()).collect(Collectors.toList());
+
+            Iterator<String> it = lines.iterator();
+            if (it.hasNext())
+                w.write(it.next());
+            while (it.hasNext()) {
+                w.newLine();
+                w.write(it.next());
+            }
+        }
+        return result;
+    }
+
+    private static Stream<String> processTemplate(String packageName,
+                                                  String factorySimpleName,
+                                                  Stream<String> lines) {
+        Function<String, String> pckg;
+
+        if (packageName.isEmpty()) {
+            pckg = s -> s.contains("$package") ? "" : s;
+        } else {
+            pckg = s -> s.replaceAll("\\$package", packageName);
+        }
+
+        Function<String, String> factory
+                = s -> s.replaceAll("\\$className", factorySimpleName);
+
+        return lines.map(pckg).map(factory);
+    }
+
+    // IMO, that's the easiest way that gives you a fair amount of confidence in
+    // that j.u.ServiceLoader is loading a factory rather than Class.forName
+    private static boolean verifyOutput(String output, String fqn) {
+        String s1 = String.format("java.util.ServiceConfigurationError: " +
+                "java.net.ContentHandlerFactory: " +
+                "Provider %s could not be instantiated", fqn);
+
+        return output.contains(s1);
+    }
+
+    private static void jar(Path jarName, Path jarRoot) {
+        String jar = getJDKTool("jar");
+        ProcessBuilder p = new ProcessBuilder(jar, "cf", jarName.toString(),
+                "-C", jarRoot.toString(), ".");
+        quickFail(run(p));
+    }
+
+    private static void javac(Path compilationOutput, Path... sourceFiles) {
+        String javac = getJDKTool("javac");
+        List<String> commands = new ArrayList<>();
+        commands.addAll(asList(javac, "-d", compilationOutput.toString()));
+        List<Path> paths = asList(sourceFiles);
+        commands.addAll(paths.stream()
+                .map(Path::toString)
+                .collect(Collectors.toList()));
+        quickFail(run(new ProcessBuilder(commands)));
+    }
+
+    private static void quickFail(Result r) {
+        if (r.exitValue != 0)
+            throw new RuntimeException(r.output);
+    }
+
+    private static Result java(Map<String, String> properties,
+                               Collection<Path> classpath,
+                               String classname, String... args) {
+
+        String java = getJDKTool("java");
+
+        List<String> commands = new ArrayList<>();
+        commands.add(java);
+        commands.addAll(properties.entrySet()
+                .stream()
+                .map(e -> "-D" + e.getKey() + "=" + e.getValue())
+                .collect(Collectors.toList()));
+
+        String cp = classpath.stream()
+                .map(Path::toString)
+                .collect(Collectors.joining(File.pathSeparator));
+        commands.add("-cp");
+        commands.add(cp);
+        commands.add(classname);
+        commands.addAll(Arrays.asList(args));
+
+        return run(new ProcessBuilder(commands));
+    }
+
+    private static Result run(ProcessBuilder b) {
+        Process p;
+        try {
+            p = b.start();
+        } catch (IOException e) {
+            throw new RuntimeException(
+                    format("Couldn't start process '%s'", b.command()), e);
+        }
+
+        String output;
+        try {
+            output = toString(p.getInputStream(), p.getErrorStream());
+        } catch (IOException e) {
+            throw new RuntimeException(
+                    format("Couldn't read process output '%s'", b.command()), e);
+        }
+
+        try {
+            p.waitFor();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(
+                    format("Process hasn't finished '%s'", b.command()), e);
+        }
+
+        return new Result(p.exitValue(), output);
+    }
+
+    private static String getJDKTool(String name) {
+        String testJdk = System.getProperty("test.jdk");
+        if (testJdk == null)
+            throw new RuntimeException("Please provide test.jdk property at a startup");
+        return testJdk + File.separator + "bin" + File.separator + name;
+    }
+
+    private static Path templatesHome() {
+        String testSrc = System.getProperty("test.src");
+        if (testSrc == null)
+            throw new RuntimeException("Please provide test.src property at a startup");
+        return Paths.get(testSrc);
+    }
+
+    private static String toString(InputStream... src) throws IOException {
+        StringWriter dst = new StringWriter();
+        Reader concatenated =
+                new InputStreamReader(
+                        new SequenceInputStream(
+                                Collections.enumeration(asList(src))));
+        copy(concatenated, dst);
+        return dst.toString();
+    }
+
+    private static void copy(Reader src, Writer dst) throws IOException {
+        int len;
+        char[] buf = new char[1024];
+        try {
+            while ((len = src.read(buf)) != -1)
+                dst.write(buf, 0, len);
+        } finally {
+            try {
+                src.close();
+            } catch (IOException ignored1) {
+            } finally {
+                try {
+                    dst.close();
+                } catch (IOException ignored2) {
+                }
+            }
+        }
+    }
+
+    private static class Result {
+
+        final int exitValue;
+        final String output;
+
+        private Result(int exitValue, String output) {
+            this.exitValue = exitValue;
+            this.output = output;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/URLConnection/ContentHandlers/broken_constructor_factory.template	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package $package;
+
+import java.net.ContentHandler;
+import java.net.ContentHandlerFactory;
+
+public class $className implements ContentHandlerFactory {
+
+    public $className() {
+        throw new RuntimeException(
+                "This is a broken factory. It is supposed to throw this exception.");
+    }
+
+    @Override
+    public ContentHandler createContentHandler(String mimetype) {
+        throw new RuntimeException( "This method is not supposed to be called.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/URLConnection/ContentHandlers/broken_factory.template	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package $package;
+
+import java.net.ContentHandler;
+import java.net.ContentHandlerFactory;
+
+public class $className implements ContentHandlerFactory {
+
+    @Override
+    public ContentHandler createContentHandler(String mimetype) {
+        throw new RuntimeException(
+                "This is a broken factory. It is supposed to throw this exception.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/URLConnection/ContentHandlers/plain.template	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 $package;
+
+import java.io.IOException;
+import java.net.ContentHandler;
+import java.net.URLConnection;
+
+public final class $className extends ContentHandler {
+
+    @Override
+    public Object getContent(URLConnection urlc) throws IOException {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/URLConnection/ContentHandlers/test.template	Fri Jul 10 16:40:12 2015 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.ContentHandlerFactory;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+public class Test {
+
+    public static void main(String[] args) throws Exception {
+        if (args.length > 0) {
+            String fqn = args[0];
+
+            @SuppressWarnings("unchecked")
+            Class<? extends ContentHandlerFactory> c =
+                    (Class<? extends ContentHandlerFactory>) Class.forName(fqn);
+
+            ContentHandlerFactory f = c.newInstance();
+
+            URLConnection.setContentHandlerFactory(f);
+        }
+
+        // One does not simply use a ContentHandler...
+        // From an end user perspective ContentHandler is used indirectly
+        // and it's more like SPI rather than API. So there's a certain amount
+        // of preparations needs to be done beforehand.
+
+        URLStreamHandlerFactory streamHandlerFactory =
+                (protocol) ->
+                        new URLStreamHandler() {
+                            @Override
+                            protected URLConnection openConnection(URL u) {
+                                return newUrlConnection(u);
+                            }
+                        };
+
+        URL.setURLStreamHandlerFactory(streamHandlerFactory);
+
+        // Finally
+        Object content = new URL("whatever:").getContent();
+
+        System.out.println("Content class is: " + content.getClass());
+    }
+
+    private static URLConnection newUrlConnection(URL u) {
+        return new URLConnection(u) {
+            @Override public void connect() { }
+
+            @Override
+            public InputStream getInputStream() { return null; }
+
+            @Override public String getContentType() { return "text/plain"; }
+        };
+    }
+}