src/java.naming/share/classes/javax/naming/spi/NamingManager.java
Print this page
@@ -23,13 +23,11 @@
* questions.
*/
package javax.naming.spi;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
+import java.util.*;
import java.net.MalformedURLException;
import javax.naming.*;
import com.sun.naming.internal.VersionHelper;
import com.sun.naming.internal.ResourceManager;
@@ -623,19 +621,32 @@
}
/**
* Creates an initial context using the specified environment
* properties.
- *<p>
- * If an InitialContextFactoryBuilder has been installed,
- * it is used to create the factory for creating the initial context.
- * Otherwise, the class specified in the
- * <tt>Context.INITIAL_CONTEXT_FACTORY</tt> environment property is used.
- * Note that an initial context factory (an object that implements the
- * InitialContextFactory interface) must be public and must have a
- * public constructor that accepts no arguments.
- *
+ * <p>
+ * This is done as follows:
+ * <ul>
+ * <li>If an InitialContextFactoryBuilder has been installed,
+ * it is used to create the factory for creating the initial
+ * context</li>
+ * <li>Otherwise, the class specified in the
+ * <tt>Context.INITIAL_CONTEXT_FACTORY</tt> environment property
+ * is used
+ * <ul>
+ * <li>First, the {@linkplain java.util.ServiceLoader ServiceLoader}
+ * mechanism tries to locate an {@code InitialContextFactory}
+ * provider with system classloader</li>
+ * <li>Failing that, this implementation tries to locate a suitable
+ * {@code InitialContextFactory} using a built-in mechanism
+ * <br>
+ * (Note that an initial context factory (an object that implements
+ * the InitialContextFactory interface) must be public and must have
+ * a public constructor that accepts no arguments)</li>
+ * </ul>
+ * </li>
+ * </ul>
* @param env The possibly null environment properties used when
* creating the context.
* @return A non-null initial context.
* @exception NoInitialContextException If the
* <tt>Context.INITIAL_CONTEXT_FACTORY</tt> property
@@ -647,15 +658,15 @@
* @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext
*/
public static Context getInitialContext(Hashtable<?,?> env)
throws NamingException {
- InitialContextFactory factory;
+ InitialContextFactory factory = null;
InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder();
if (builder == null) {
- // No factory installed, use property
+ // No builder installed, use property
// Get initial context factory class name
String className = env != null ?
(String)env.get(Context.INITIAL_CONTEXT_FACTORY) : null;
if (className == null) {
@@ -664,20 +675,44 @@
"property, or in an application resource file: " +
Context.INITIAL_CONTEXT_FACTORY);
throw ne;
}
+ ServiceLoader<InitialContextFactory> loader =
+ ServiceLoader.load(InitialContextFactory.class,
+ ClassLoader.getSystemClassLoader());
+
+ Iterator<InitialContextFactory> iterator = loader.iterator();
+ try {
+ while (iterator.hasNext()) {
+ InitialContextFactory f = iterator.next();
+ if (f.getClass().getName().equals(className)) {
+ factory = f;
+ break;
+ }
+ }
+ } catch (ServiceConfigurationError e) {
+ NoInitialContextException ne =
+ new NoInitialContextException(
+ "Cannot load initial context factory "
+ + "'" + className + "'");
+ ne.setRootCause(e);
+ throw ne;
+ }
+
+ if (factory == null) {
try {
factory = (InitialContextFactory)
helper.loadClass(className).newInstance();
- } catch(Exception e) {
+ } catch (Exception e) {
NoInitialContextException ne =
new NoInitialContextException(
"Cannot instantiate class: " + className);
ne.setRootCause(e);
throw ne;
}
+ }
} else {
factory = builder.createInitialContextFactory(env);
}
return factory.getInitialContext(env);