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.