RFR JDK-8044627: Update JNDI to work with modules
Pavel Rappo
pavel.rappo at oracle.com
Tue Sep 16 14:14:49 UTC 2014
Daniel,
> Given that helper.loadClass uses the context class loader,
> Should you also simply use
> ServiceLoader<InitialContextFactory> loader =
> ServiceLoader.load(InitialContextFactory.class);
> at lines 680-681 ?
It needs to be the system class loader to allow for JNDI providers that might be on the class path or module path.
> Also it might be good to log an RFE against the ServiceLoader, so
> that you could look for a service implementation of a specific
> concrete class without having to instantiate all the other
> service implementations encountered along the way.
> Streams should provide a nice infrastructure for such an API.
> It would certainly be more robust than looping over
> ServiceLoader.iterator().next() - which is unfortunately the only
> option available to you at the moment.
IMO, it's not just an inconvenience, but rather a part of ServiceLoader's design. I mean, it's definitely designed to provide, so to say, a "one-to-many" mapping for the classes (providers) that implements some interface (a service) to a client. It merely delivers you implementations. You should than iterate though them and decide which one satisfies your needs. I'm not sure it's a good idea to get services based on their implementation classnames. It's more likely to be a little bit a flaw in design from the JNDI part -- when you have to specify the implementation class's FQN. But given the history of the JNDI (it's started as a project outside the JDK) -- it's totally understandable.
(Just as a side-note, have a look at these examples of usage of ServiceLoader:
java.net.InetAddress:862
java.time.chrono.AbstractChronology:274
java.time.chrono.AbstractChronology:307
javax.xml.validation.SchemaFactoryFinder:405
javax.xml.xpath.XPathFactoryFinder:403
java.time.zone.ZoneRulesProvider:177)
> Also - it would be good to clarify the specification of
> public static Context getInitialContext(Hashtable<?,?> env)
> It was not clear to me that you would loop over all the
> services found by the ServiceLoader until you'd find one
> whose concrete class matched the name pointed to by
> Context.INITIAL_CONTEXT_FACTORY.
Don't you think it becomes than 'overspecified'? Why should we want to tie ourselves?
> This seems a bit fragile to me - unless it's guaranteed that
> the various InitialContextFactory have no static initializer
> that might throw exceptions (such as SecurityException) - and
> that their default constructor does nothing (so that instantiating
> e.g. com.sun.jndi.cosnaming.CNCtxFactory when you're actually
> looking for com.sun.jndi.ldap.LdapCtxFactory has no side effect
> - which fortunately seems to be the case).
Well, no one can guarantee us this. Even a constructor could do all the things you've mentioned :) It's just the nature of a factory. It should better be stateless and without any side effects.
-Pavel
More information about the core-libs-dev
mailing list