-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
8333103: Re-examine the console provider loading #19467
8333103: Re-examine the console provider loading #19467
Conversation
👋 Welcome back naoto! A progress list of the required criteria for merging this PR into |
@naotoj 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 41 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. ➡️ To integrate this PR with the above commit message to the |
Webrevs
|
if (jc != null) { | ||
return new ProxyingConsole(jc); | ||
} | ||
break; |
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.
break; |
The original findAny
is only after filter(Objects::nonNull)
meaning we don't return null
on a null jcp.console
result.
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.
Yes, break
guarantees that the search completes one way or another once the module name has been matched. This is not how it used to be done.
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.
Right. Since findAny
is after the module name matching, there is at most 1 match. In the case we didn't find any, the final orElse(null)
eventually returns null. So the refactored code is semantically the same.
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 only semantically the same if we assume a module can only provide a single JdkConsoleProvider
, no? The break;
disallows multiple providers (for disjoint sets of charsets) in a single module.
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.
Claes has described the issue well. Like I said, break
short-circuits the search. If a module can provide more than one console provider, the suggested stream-less replacement is not equivalent.
If a module can provide more than one console provider, not only the code needs to be fixed, but a relevant test should be added too. The test should be in this PR, but tagged with the initial bug, 8295803, not this (performance) bug.
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.
In fact, this started simply for incorporating JLine implementation into Console, and using ServiceLoader was a mere means to load its impl as it resides outside the java.base module. So yes, module and its console implementation is 1:1, which is reflected by the system property jdk.console
that takes the module name. So that break;
effectively shortcut the unnecessary looping (I don't think it would happen btw).
That said, I think it needs to be described in the comment above that piece of code. I will add it shortly.
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.
So, it's the previous (stream) version that was more permissive and inadvertently so, yes?
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.
Yes, correct. If hypothetically Jline provided two impls, it were not specified which impl was used. Now we only use the first one found.
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.
The change to replace lambda with anonymous class looks OK to me.
Would it be possible to provide more context/background here? This is not code that is used during startup. Is there benchmark data to share for first use of java.io.IO ? |
I think this was brought to the fore by https://openjdk.org/jeps/477 where running the example implicit main:
.. brings in this code. This PR is one of several to try and smoothen a few rough edges that makes the startup of that quite a bit heavier than the baseline non-implicit Hello World. |
Just to clarify a bit, this is only vaguely related to the implicitly declared classes. The actual issue is that having two programs:
and:
(note there are no implicitly declared classes, and no implicit imports in the samples), there is a considerable difference in the runtime of (compiled versions) of these classes. E.g. on my laptop:
(Vast) majority of the time is spent in JLine initialization. There's https://bugs.openjdk.org/browse/JDK-8333086 for that, where the intent is to avoid initializing JLine for simple printing. There may be other opportunities to make JLine initialization faster in case we need to initialize it. |
/integrate |
Going to push as commit 9686e80.
Your commit was automatically rebased without conflicts. |
There is an initialization code in
Console
class that searches for the Console implementations. Refactoring the init code not to use lambda/stream would reduce the (initial) number of loaded classes by about 100 for java.base implementations. This would become relevant when the java.io.IO (JEP 477) uses Console as the underlying framework.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/19467/head:pull/19467
$ git checkout pull/19467
Update a local copy of the PR:
$ git checkout pull/19467
$ git pull https://git.openjdk.org/jdk.git pull/19467/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 19467
View PR using the GUI difftool:
$ git pr show -t 19467
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/19467.diff
Webrev
Link to Webrev Comment