8273026: Slow LoginContext.login() on multi threading application
Reviewed-by: weijun
This commit is contained in:
parent
15fd8a300b
commit
c0cda1db4f
@ -40,6 +40,10 @@ import java.util.ServiceLoader;
|
|||||||
import sun.security.util.PendingException;
|
import sun.security.util.PendingException;
|
||||||
import sun.security.util.ResourcesMgr;
|
import sun.security.util.ResourcesMgr;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.stream.*;
|
||||||
|
import java.util.ServiceLoader.Provider;
|
||||||
/**
|
/**
|
||||||
* <p> The {@code LoginContext} class describes the basic methods used
|
* <p> The {@code LoginContext} class describes the basic methods used
|
||||||
* to authenticate Subjects and provides a way to develop an
|
* to authenticate Subjects and provides a way to develop an
|
||||||
@ -222,6 +226,8 @@ public class LoginContext {
|
|||||||
|
|
||||||
private static final sun.security.util.Debug debug =
|
private static final sun.security.util.Debug debug =
|
||||||
sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]");
|
sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]");
|
||||||
|
private static final WeakHashMap<ClassLoader, Set<Provider<LoginModule>>> providersCache =
|
||||||
|
new WeakHashMap<>();
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
private void init(String name) throws LoginException {
|
private void init(String name) throws LoginException {
|
||||||
@ -288,6 +294,7 @@ public class LoginContext {
|
|||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
@ -691,21 +698,35 @@ public class LoginContext {
|
|||||||
// locate and instantiate the LoginModule
|
// locate and instantiate the LoginModule
|
||||||
//
|
//
|
||||||
String name = moduleStack[i].entry.getLoginModuleName();
|
String name = moduleStack[i].entry.getLoginModuleName();
|
||||||
@SuppressWarnings("removal")
|
Set<Provider<LoginModule>> lmProviders;
|
||||||
ServiceLoader<LoginModule> sc = AccessController.doPrivileged(
|
synchronized(providersCache){
|
||||||
(PrivilegedAction<ServiceLoader<LoginModule>>)
|
lmProviders = providersCache.get(contextClassLoader);
|
||||||
() -> ServiceLoader.load(
|
if (lmProviders == null){
|
||||||
LoginModule.class, contextClassLoader));
|
if (debug != null){
|
||||||
for (LoginModule m: sc) {
|
debug.println("Build ServiceProviders cache for ClassLoader: " + contextClassLoader.getName());
|
||||||
if (m.getClass().getName().equals(name)) {
|
}
|
||||||
moduleStack[i].module = m;
|
@SuppressWarnings("removal")
|
||||||
|
ServiceLoader<LoginModule> sc = AccessController.doPrivileged(
|
||||||
|
(PrivilegedAction<ServiceLoader<LoginModule>>)
|
||||||
|
() -> java.util.ServiceLoader.load(
|
||||||
|
LoginModule.class, contextClassLoader));
|
||||||
|
lmProviders = sc.stream().collect(Collectors.toSet());
|
||||||
|
if (debug != null){
|
||||||
|
debug.println("Discovered ServiceProviders for ClassLoader: " + contextClassLoader.getName());
|
||||||
|
lmProviders.forEach(System.err::println);
|
||||||
|
}
|
||||||
|
providersCache.put(contextClassLoader,lmProviders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Provider<LoginModule> lm: lmProviders){
|
||||||
|
if (lm.type().getName().equals(name)){
|
||||||
|
moduleStack[i].module = lm.get();
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
debug.println(name + " loaded as a service");
|
debug.println(name + " loaded as a service");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moduleStack[i].module == null) {
|
if (moduleStack[i].module == null) {
|
||||||
try {
|
try {
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
@ -26,9 +26,13 @@ import java.io.File;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8047789
|
* @bug 8047789 8273026
|
||||||
* @summary auth.login.LoginContext needs to be updated to work with modules
|
* @summary auth.login.LoginContext needs to be updated to work with modules
|
||||||
* @build FirstLoginModule SecondLoginModule
|
* @comment shows that the SecondLoginModule is still needed even if it's not in the JAAS login config file
|
||||||
|
* @build FirstLoginModule
|
||||||
|
* @clean SecondLoginModule
|
||||||
|
* @run main/othervm/fail Loader
|
||||||
|
* @build SecondLoginModule
|
||||||
* @run main/othervm Loader
|
* @run main/othervm Loader
|
||||||
*/
|
*/
|
||||||
public class Loader {
|
public class Loader {
|
||||||
@ -39,18 +43,7 @@ public class Loader {
|
|||||||
new File(System.getProperty("test.src"), "sl.conf").toString());
|
new File(System.getProperty("test.src"), "sl.conf").toString());
|
||||||
LoginContext lc = new LoginContext("me");
|
LoginContext lc = new LoginContext("me");
|
||||||
|
|
||||||
if (SecondLoginModule.isLoaded) {
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
lc.login();
|
lc.login();
|
||||||
|
|
||||||
// Although only FirstLoginModule is specified in the JAAS login
|
|
||||||
// config file, LoginContext will first create all LoginModule
|
|
||||||
// implementations that are registered as services, which include
|
|
||||||
// SecondLoginModule.
|
|
||||||
if (!SecondLoginModule.isLoaded) {
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class SecondLoginModule implements LoginModule {
|
public class SecondLoginModule implements LoginModule {
|
||||||
|
|
||||||
public static boolean isLoaded;
|
|
||||||
|
|
||||||
public SecondLoginModule() {
|
|
||||||
isLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(Subject subject, CallbackHandler callbackHandler,
|
public void initialize(Subject subject, CallbackHandler callbackHandler,
|
||||||
|
Loading…
Reference in New Issue
Block a user