Olivier Jolly wrote:
Chris Burdess wrote:

David Daney wrote:

With this test case (just added to mauve):

import java.net.URL;

public class URLTest {
    public static void main(String []args) {
        try {
            URL url = new URL("http://www.foo.bar.com";);
            url = new URL(url, "_urn:testing/");
            System.out.println("url: " + url);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Classpath is currently treating the "_urn:" as a protocol and discarding the context even though "_urn:" is not a valid protocol. Sun's runtime will append the spec to the context in this case instead of replacing the context.


There is no way to determine whether a URL scheme is "valid" or not, assuming that is even meaningful.

If we append the spec to the context in this case we should also do so in the case of

  url = new URL("http://www.foo.bar.com";);
  url = new URL(url, "http://www.foo.bar.com";);

this should produce "http://www.foo.bar.com/http://www.foo.bar.com";.

Actually, there is a way to determine whether a protocol is valid or not, or more precisely, whether we have an handler for it or no. According to the javadoc for the main constructor of java.net.URL in jdk 1.4.2 :

8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --

If this is the first URL object being created with the specified protocol, a /stream protocol handler/ object, an instance of class |URLStreamHandler|, is created for that protocol:

  1. If the application has previously set up an instance of
     |URLStreamHandlerFactory| as the stream handler factory, then the
     |createURLStreamHandler| method of that instance is called with
     the protocol string as an argument to create the stream protocol
     handler.
  2. If no |URLStreamHandlerFactory| has yet been set up, or if the
     factory's |createURLStreamHandler| method returns |null|, then the
     constructor finds the value of the system property:

                  java.protocol.handler.pkgs
If the value of that system property is not |null|, it is
     interpreted as a list of packages separated by a vertical slash
     character '|||'. The constructor tries to load the class named:

                  </package/>.</protocol/>.Handler
where </package/> is replaced by the name of the package and
     </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 |URLStreamHandler|, then the next package in the list
     is tried.
  3. If the previous step fails to find a protocol handler, then the
     constructor tries to load from a system default package.

</system default package/>.</protocol/>.Handler If this class does not exist, or if the class exists but it is not a subclass of |URLStreamHandler|, then a |MalformedURLException| is thrown.

8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --

So, to be comprehensive, we should ensure that all of those steps will fail before declaring a protocol as good for checking that it isn't interpreted.

In theory shouldn't all those steps be taken by the getURLStreamHandler method?

If so, then my patch would be essentially correct. Any failure to detect a valid protocol would be a bug in getURLStreamHandler and the subject of a different patch.

David Daney.

Reply via email to