[cp-patches] RFC: URL fix.

Olivier Jolly olivier.jolly at pcedev.com
Wed Mar 1 10:59:54 UTC 2006


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.
I suggest to ensure we do not register a |URLStreamHandlerFactory| (just 
adding a comment in the teslet) and then use a protocol with characters 
which are illegal as package name content (dots maybe, to keep it simple).
I'm pretty sure we can use some fancy ascii art as a protocol name to be 
sure it won't ever be valid :)
> --犬 Chris Burdess
+Olivier




More information about the Classpath-patches mailing list