New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8273026: Slow LoginContext.login() on multi threading application #5748
Conversation
👋 Welcome back Larry-N! A progress list of the required criteria for merging this PR into |
Webrevs
|
(PrivilegedAction<ServiceLoader<LoginModule>>) | ||
() -> java.util.ServiceLoader.load( | ||
LoginModule.class, contextClassLoader)); | ||
Set<Provider<LoginModule>> lmProviders = sc.stream().collect(Collectors.toSet()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably necessary to put the collect
call above inside doPriv as well. The actual class loading might happen later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing a JCK failure on this change. Will investigate more. At the same time, is it possible to merge this synchronized block into the one below?
Set<Provider<LoginModule>> lmp = cacheServiceProviders.get(contextClassLoader); | ||
for ( Provider<LoginModule> lm: lmp){ | ||
if (lm.type().getName().equals(name)){ | ||
moduleStack[i].module = lm.get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a small behavior change here. Originally the login module class is loaded first and then its name is checked. With this change, the name is first checked and then class loaded. This is certainly a performance boost but unfortunately the test at test/jdk/javax/security/auth/spi/Loader.java
would fail. That test was written to ensure that services provided through a service loader are checked first and then fallback to Class.forName()
. Either you need to enhance the test to confirm this in a new way, or it would have to be removed.
@wangweij With the new commit, I've moved filling ServiceProviders cache filling to login() method. And addressed your notice about correction for spi/Loader.java test. Could you please take a look when you have a chance? Thank you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Source code change looks mostly fine to me. I'm running some tests now. Will get back once they finish. Update: all related tests run fine.
As for the test, IMO, it was meant to show that SecondLoginModule
is still needed even if it's not in the JAAS login config file. Your updated test only prove it's not really instantiated. How about this:
Change the test directives to
* @build FirstLoginModule
* @run main/othervm/fail Loader
* @build SecondLoginModule
* @run main/othervm Loader
so that the login succeeds only after there exists a SecondLoginModule
. All those isLoaded
flags should be removed so their enclosing classes are not compiled automatically.
@@ -222,6 +226,7 @@ | |||
|
|||
private static final sun.security.util.Debug debug = | |||
sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]"); | |||
private static final WeakHashMap<ClassLoader, Set<Provider<LoginModule>>> cacheServiceProviders = new WeakHashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line can be a little shorter. There are some other lines below which is also quite long. The original limit was 80 chars but please be at most 90.
src/java.base/share/classes/javax/security/auth/login/LoginContext.java
Outdated
Show resolved
Hide resolved
moduleStack[i].module = lm.get(); | ||
if (debug != null) { | ||
debug.println(name + " loaded as a service"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please de-indent the if block above.
Thanks for the review, I'll update the code according to your notices. Sorry, I didn't catch the point with the test.
maybe you mean the test Loader.java itself? I have rolled back changes in Loader.java and FirstLoginModule.java, added directives that you proposed to Loader.java, but the test fails. |
Have you removed the |
Probably i do something wrong, but I've removed the isLoaded from both login modules classes, so the test looks like this:
and the jtreg says: |
On my machine, the 1st |
Thank you for the explanations. When I cleaned up the working directory all pass ok. ( And fails when I submitted the test a second time) |
Let's hope the directory is always clean when the test is actually launched. I have no other comments. Thanks for the patience. |
@Larry-N This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 397 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@wangweij) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
You might want to see if the "clean" action is useful here. See https://openjdk.java.net/jtreg/tag-spec.html. Update: I just tried. Adding a |
Thanks, I've added |
/integrate |
/sponsor |
Going to push as commit c0cda1d.
Your commit was automatically rebased without conflicts. |
Could the original JDK-8230297 be closed as a duplicate please? |
@efge Closed. Thanks for reminding. |
This fix adds a cache of service provider classes to LoginContext (in particular, it's a cache of LoginModules classes). The approach helps to increase the performance of the LoginContext.login() method significantly, especially in a multi-threading environment. Service Loader is used for polling on Service Provider classes, without instantiating LoginModules object if Service Provider name doesn't match record in .config file. The set of service providers is cached for each Context Loader separately.
This code passed successfully tier1 and tier2 tests on mac os.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/5748/head:pull/5748
$ git checkout pull/5748
Update a local copy of the PR:
$ git checkout pull/5748
$ git pull https://git.openjdk.java.net/jdk pull/5748/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 5748
View PR using the GUI difftool:
$ git pr show -t 5748
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/5748.diff