Hello, What about simply rejecting overlapping programmatic registrations, and for the service loader using the natural order (class loader search order). I guess most extensions register new schemes only, as it was not easy before in such a central shared system component. an ordering api might not really help. Its might be better to allow specific versions like a factory or even something thread local? (Similar to jndi enc)
Bernd Am 01.02.2015 00:48 schrieb "Peter Levart" <peter.lev...@gmail.com>: > Hi Alan, > > On 01/31/2015 10:33 PM, Alan Bateman wrote: > > On 31/01/2015 19:42, Peter Levart wrote: > > 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. > > : > > 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/ > > > I don't think we should we expose ordering values in > URLStreamHandlerFactory, it looks a bit odd and not clear how an > implementation can choose a useful value. There is a general issue that > ServiceLoader doesn't currently support a means to order service providers > but I think we can re-examine that when we move to modules and and linking. > That is, have a consistent way to configure ordering that we can use > everywhere that ServiceLoader is used rather than doing one-off solutions. > > > I agree. Putting the order on the SPI API is not the right solution. The > order should be configured in one place. But there needs to be some kind of > handle each service exposes for order configuration to reference. So one > idea how to extend the ServiceLoader mechanism is this: > > create a special class-scope runtime annotation... > > public @interface ServiceProvider { > String name(); > } > > ...with which service implementation classes can optionally be annotated. > This could enable ServiceLoader API extension like: > > public static <S> ServiceLoader<S> load(Class<S> service, String > serviceProviderName) > > that would return an Iterable over implementations that are annotated with > a particular @ServiceProvider(name = ...) annotation (similar to security > Providers but simpler). > > In addition one could specify a system property with the key being > prefixed by service interface FQ class name, like: > > > java.net.URLStreamHandlerFactory.serviceLoaderOrder=providerName1,providerName2,providerName3,... > > > > > The other thing is that it's not clear how this would work for a factory > for the jar protocol that is itself deployed in a JAR file on the class > path. This is important for containers that want to do their own caching > and they want their jar protocol handler configured system-wide before > starting any applications. It's also part of the motive for the > addURLStreamHandlerFactory in the original proposal. > > > I see. But isn't URL.setURLStreamHandlerFactory() enough for that purpose? > It can only be set once, but there can only be *one* container that wants > it's jar protocol handler configured system-wide. > > Regards, Peter > > > I think you have good point with the setFactory permission, that does need > to be looked at. > > -Alan. > > >