< prev index next >
src/java.naming/share/classes/javax/naming/spi/NamingManager.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -23,18 +23,23 @@
* questions.
*/
package javax.naming.spi;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.UndeclaredThrowableException;
import java.net.MalformedURLException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.*;
import javax.naming.*;
import com.sun.naming.internal.VersionHelper;
import com.sun.naming.internal.ResourceManager;
import com.sun.naming.internal.FactoryEnumeration;
+import jdk.internal.loader.ClassLoaderValue;
/**
* This class contains methods for creating context objects
* and objects referred to by location information in the naming
* or directory service.
@@ -77,10 +82,13 @@
/**
* Package-private; used by DirectoryManager and NamingManager.
*/
private static ObjectFactoryBuilder object_factory_builder = null;
+ private static final ClassLoaderValue<InitialContextFactory> FACTORIES_CACHE =
+ new ClassLoaderValue<>();
+
/**
* The ObjectFactoryBuilder determines the policy used when
* trying to load object factories.
* See getObjectInstance() and class ObjectFactory for a description
* of the default policy.
@@ -670,10 +678,11 @@
* @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext
*/
public static Context getInitialContext(Hashtable<?,?> env)
throws NamingException {
+ ClassLoader loader;
InitialContextFactory factory = null;
InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder();
if (builder == null) {
// No builder installed, use property
@@ -687,29 +696,59 @@
"property, or in an application resource file: " +
Context.INITIAL_CONTEXT_FACTORY);
throw ne;
}
- ServiceLoader<InitialContextFactory> loader =
- ServiceLoader.load(InitialContextFactory.class);
+ if (System.getSecurityManager() == null) {
+ loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) loader = ClassLoader.getSystemClassLoader();
+ } else {
+ PrivilegedAction<ClassLoader> pa = () -> {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ return (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
+ };
+ loader = AccessController.doPrivileged(pa);
+ }
- Iterator<InitialContextFactory> iterator = loader.iterator();
+ ClassLoaderValue<InitialContextFactory>.Sub<String> key = FACTORIES_CACHE.sub(className);
try {
- while (iterator.hasNext()) {
- InitialContextFactory f = iterator.next();
- if (f.getClass().getName().equals(className)) {
- factory = f;
- break;
+ factory = key.computeIfAbsent(loader, (ld, ky) -> {
+ String cn = ky.key();
+ InitialContextFactory fac = getFactory(cn);
+ return fac;
+ });
+ } catch (UndeclaredThrowableException e) {
+ if (e.getUndeclaredThrowable() instanceof NoInitialContextException) {
+ throw (NoInitialContextException) e.getUndeclaredThrowable();
+ }
}
+ } else {
+ factory = builder.createInitialContextFactory(env);
+ }
+
+ return factory.getInitialContext(env);
}
+
+ private static InitialContextFactory getFactory(String className) {
+ InitialContextFactory factory;
+ try {
+ ServiceLoader<InitialContextFactory> loader =
+ ServiceLoader.load(InitialContextFactory.class);
+
+ factory = loader
+ .stream()
+ .map(ServiceLoader.Provider::get)
+ .filter(f -> f.getClass().getName().equals(className))
+ .findFirst()
+ .orElse(null);
} catch (ServiceConfigurationError e) {
NoInitialContextException ne =
new NoInitialContextException(
"Cannot load initial context factory "
+ "'" + className + "'");
ne.setRootCause(e);
- throw ne;
+ throw new UndeclaredThrowableException(ne);
}
if (factory == null) {
try {
@SuppressWarnings("deprecation")
@@ -718,18 +757,14 @@
} catch (Exception e) {
NoInitialContextException ne =
new NoInitialContextException(
"Cannot instantiate class: " + className);
ne.setRootCause(e);
- throw ne;
+ throw new UndeclaredThrowableException(ne);
}
}
- } else {
- factory = builder.createInitialContextFactory(env);
- }
-
- return factory.getInitialContext(env);
+ return factory;
}
/**
* Sets the InitialContextFactory builder to be builder.
< prev index next >