Hello,
I am in the process of re-implementing the URL Handlers service for
Felix. The URL Handlers service is essentially a singleton, since it
must make calls to URL.setURLStreamHandlerFactory() and
URLConnection.setContentHandlerFactory(), which are singleton methods.
However, I would like to consider approaches for making it work when
multiple instances of the framework are in memory at the same time. As
far as I can see, there are at least three approaches:
1. First framework instance wins, every other framework instance is
out of luck. (However, they will be able to use the stream and
content handlers of the first framework instance implicitly.)
2. All stream and content handlers for all framework instances are
aggregated; thus, individual frameworks use a merged set of handlers.
3. Framework isolation is maintained, i.e., bundles in a given
framework instance only see handlers registered by bundles in the
same framework instance.
For me, #3 seems like the way to go, but I am not sure how easily this
can be achieved. My thought was to create a static implementation of the
URL Handler service with which each framework instance would register
upon creation.
When asked for a handler, I imagine that the URL Handlers service would
always return a handler proxy (except for built-in handlers), even if no
handlers existed, in which case the proxy would just throw some
reasonable exception when it was invoked. The reason to always return a
proxy is somewhat complicated, but is related to the fact that the JVM
libraries cache the answer in some cases and also because some framework
instances may have handlers registered and other may not, thus the
distinction between having and not having a handler is a little murky.
When a handler proxy is invoked it could use
SecurityManager.getClassContext() to get the call stack of classes and
walk up the call stack to get the first class that is loaded from a
bundle class loader. From the bundle class loader it could then find out
to which framework instance the bundle belonged and use this information
to find out if the framework instance has a registered handler service
that matches the request. If not, it would throw an appropriate
exception, if so the call would be delegated to the handler service.
Of course, there are probably a lot of little details I have not thought
about, but this is a general outline of how I am thinking of approaching
the problem. Also, I am figuring that we can optimize the single
framework instance case so that it doesn't have to do a lot of extra
work if only one framework instance exists.
Comments are welcome.
-> richard