RFR 8064924: Update java.net.URL to work with modules
peter.levart at gmail.com
Sat Jan 31 19:42:59 UTC 2015
I looked at your solution to make URLStreamHandlerFactory interface a
service provider using ServiceLoader API and in addition adding new URL
static method to programmaticaly register URLStreamHandlerFactories.
There are a couple of issues with your approach I'd like to discuss.
The programmatic approach using static URL method does give you some
means of order in which registered URLStreamHandlerFactories are tried
to create URLStreamHandler for particular protocol - the registration
order. It means that this method should only be called by one "party" in
the VM or else it is hard to control the order of registration.
ServiceLoader is a declarative approach, but does not give you order by
default. Also, your ServiceLoader approach gives a way for
URLStreamHandlerFactories to register in the system without security
checks. If a particular
META-INF/services/java.net.URLStreamHandlerFactory is found, it's
content is used to load a class and instantiate a factory which is used
in URL constructors then. Previously, one had to have a "setFactory"
permission to set the URLStreamHandlerFactory or appropriate
PropertyPermission for seting the package prefix property. This can be
The java.protocol.handler.pkgs system property manipulation in
HttpSOAPConnection has a couple of issues as it is now (without your
- first, the property can be set too late, when https protocol has
already been used in URL constructions before any HttpSOAPConnection is
used. The URLStreamHandler cached in URL will be used for ever
regardless of HttpSOAPConnection setting the property later.
- second, the HttpSOAPConnection.initHttps is racy - it bases it's
decision to instantiate and add a security Provider on the
presence/absence of a particular package in the value of
java.protocol.handler.pkgs system property, which it modifies
afterwards. Concurrent calls to initHttps (which is called from
HttpSOAPConnection.doGet and .post) can lead to multiple security
Providers instantiations and adds...
Your question "why is jaxws using the old https client ??" is right on
the spot. Is it just because nobody has updated it yet? Why does it have
to choose the URLStreamHandlers based on JVM it is executing on (doesn't
IBM JVM already arrange for it's own HTTPS support by default?). Is it
maybe the security Provider that is dependent on these *old* HTTPS
implementations because it is using their internal APIs? This needs to
be cleared, I think.
Anyway, I think there is an alternative to programmatic registration
approach of URLStreamHandlerFactories. Using just ServiceLoader and a
new default method on URLStreamHandlerFactory interface to provide
order. Here's what I'm thinking about:
You see, even tests can be made to use this approach. I think
declarative approach is better because it doesn't depend on
Additional ideas you can take from this for your patch are the following:
- the way URLStreamHandlerFactories obtained from ServiceLoader are
security-checked before used. The implementation class / code source has
to be given "setFactory" permission if such factory is to be considered
- the way URLStreamHandlers are cached using ConcurrentHashMap instead
of Hashtable which simplifies caching "atomicity" checks and does not
use lock(s) on fast-path.
So what do you think of ServiceLoader-only approach?
On 01/30/2015 02:36 PM, Chris Hegarty wrote:
> This is phase 1, of getting java.net.URL work with modules.
> Being able to effectively specify URL protocol handler factories as fully qualified class names, through the 'java.protocol.handler.pkgs' system property is problematic. It requires the protocol handler factory implementation class to be public and accessible, as the current implementation tries to instantiate it through core reflection. Since the protocol handler factory must be an implementation of a URLStreamHandlerFactory, it lends itself to being retrofitted with a ServiceLoader lookup. Note, the 'java.protocol.handler.pkgs' system property mechanism predates ServiceLoader. URL protocol handlers would most likely have used service loader if it were available at the time.
> Some URL protocol handlers are fundamental to the platform itself, like 'file' and 'jar', it is not appropriate to attempt a service loader lookup for these, as they may lead to recursive initialization issues. However, Java Plugin, Webstart, and possibly other containers, do override the 'jar' handler. A new API will be provided for this purpose. Providing an API solution should not interfere with system initialization as it will only be called after the system comes up and user code is executing.
> The 'file' protocol handler factory will no longer be overridable, and the system property will no longer be consulted.
> Webrev and spec diffs:
> I want to agree the approach and spec first, so that the spec changes can be submitted for approval. A comprehensive test will be added before the code changes are finalised.
More information about the core-libs-dev