Hi Chris,

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 fixed.

The java.protocol.handler.pkgs system property manipulation in HttpSOAPConnection has a couple of issues as it is now (without your changes):

- 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:

http://cr.openjdk.java.net/~plevart/jdk9-dev/URLStreamHandlerFactory/webrev.01/

You see, even tests can be made to use this approach. I think declarative approach is better because it doesn't depend on initialization order.

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 at all. - 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?


Regards, Peter


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:
   http://cr.openjdk.java.net/~chegar/8064924/00/

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.

-Chris.

Reply via email to