-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
8
-
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.
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.
- relates to
-
JDK-4191098 Two beans can't add new URLStreamHandlers
-
- Closed
-