Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8262102

java.net.URL setURLStreamHandlerFactory can be called only once per VM.

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Java 8

      A DESCRIPTION OF THE PROBLEM :
      Related to 4191098

      Issue: java.net.URL setURLStreamHandlerFactory can be called only once per VM.

      Problem:

      This approach makes it impossible to use "chaining" handlers factories which can be
      added transparently by "singleton" classes.

      Concept:

      User may construct a singleton protocol handler factory class which:
      1. Sends all requests it failed to solve to it's parent factory or by other means
        allows default (previously set) handler to do the job.
      2. Is set as protocol handler factory in static class initializer.

      Example concept:

      class Handler implements....
      {
          static{
                        synchronized(?1?)
                       {
                              URL.setURLStreamHandlerFactory( new Handler(?2? ))

                       };
      };

      This type of construct is extremally easy to use, as it is enough to refer to protocol
      handler factory class either directly or in-directly to transparently register the handler.
      For an example if I need to support "help" protocol in my application the sole fact that
      I did called any method from help system class will transparently register a protocol, because they will trigger loading of Handler class.

      Thous any code which indirectly touches the Handler class will register the handler.

      User may have more than one such class and may wish all of them to register transparently.

      As You probably noticed the safe support for this style chaining requires ?1? which
      is a way of getting synchronized on URL.streamHandlerLock and ?2? which
      is the way of retriving currently set handler factory:

       static URLStreamHandlerFactory getURLStreamHandlerFactory()
       
      I'm NOT proposing to do that.
       
      The obvious troubles of this approach are:
       1.An exposure of internal lock what is a bad practice;
       2.A risk that single faulty handler factory in chain will completely break URL system
        thous will prevent classes from being loaded by URLClassLoaders. Notice, this
        risk is still there because URL does not try to fall back to default behaviour
        when stream handler factory throws an exception.

      Proposal:
        
      In this ehancement request I do propose You do try something slightly different
      but certainly more safe:

        static void addURLStreamHandlerFactory(...
        static void removeURLStreamHandlerFactory(....
        
      The getURLStreamHandler() should:
      1.Try all handlers from most recently added to
        added as first until it will find a factory which does return non-null value;
      2.Capture Throwable thrown by a handler factory and try next handler factory.
        Throw collected exceptions only if all handlers have failed. Alternatively
        fall back to default behaviour as if no factory was set.
        
      In the API of URLStreamHandlerFactory.createURLStreamHandler
      should be explained, that it should return null if it doesn't know the protocol.
      This is in fact the behaviour assumed in URL but never specified.

      Known work around:

       Update system property "java.protocol.handler.pkgs".
       
       Problem:
        1.Cannot be done in a globally thread-safe way.
      2.The list is ALWAYS extended by "sun.net.www.protocol" regardless
      if it was the wish of a user or it was not.

            Unassigned Unassigned
            tongwan Andrew Wang
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: