Skip to content
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

[JENKINS-55945] IllegalStateException trying to get user. #4107

Merged

Conversation

jeffret-b
Copy link
Contributor

This change catches the exception and returns false, invalidating the user session. This behavior is sensible, because if we are unable to validate the user we must assume the session is invalid.
Catching the error at this point reportedly helps with some scenarios and shouldn't cause any further harm.

This error shows up only in some scenarios or environments and I have been unable to reproduce it myself despite hours spent trying. This change is based upon one proposed and tested on the Jira ticket by Pavel Roskin. Without the change, Pavel reports encountering the error reliably. With the change, it didn't manifest.

There is a deeper problem here, as the exception is correctly thrown because of an illegal state. There must be one instance of AllUsers once the init sequence is complete and Jenkins shouldn't respond if it isn't. I encountered a similar error once, but in that case it originated in Jenkins.get(). It would be nice to figure out what to do about the illegal state, but I haven't been able to dig up any clues. I figure that this minor change will at least address the situation seen by some users.

As I haven't been able to reproduce the problem or determine any cause, I haven't been able to readily provide any autotests for the illegal state. I could try inserting some mocks, but those are notoriously clumsy and difficult, particularly for these sorts of things.

See JENKINS-55945.

Proposed changelog entries

  • Catch an occasional IllegalStateException on Jenkins restart and invalidate the user session. (JENKINS-55945)

Submitter checklist

  • JIRA issue is well described
  • Changelog entry appropriate for the audience affected by the change (users or developer, depending on the change). Examples
    * Use the Internal: prefix if the change has no user-visible impact (API, test frameworks, etc.)
  • Appropriate autotests or explanation to why this change has no tests
  • [N/A] For dependency updates: links to external changelogs and, if possible, full diffs

This change catches the exception and returns false, invalidating the user session. This behavior is sensible, because if we are unable to validate the user we must assume the session is invalid.
Catching the error at this point reportedly helps with some scenarios and shouldn't cause any further harm.
@jeffret-b jeffret-b requested review from Wadeck and jvz July 9, 2019 20:18
User userFromSession;
try {
userFromSession = User.getById(authentication.getName(), false);
} catch (IllegalStateException ise) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No-idiomatic abbreviations set a bad example to others. Common names for an exception are e, x and ex. Not a blocker.

@proski
Copy link

proski commented Jul 9, 2019

Sorry for not submitting this PR on my own! Looks good to me.

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just every RuntimeException ?

@jeffret-b
Copy link
Contributor Author

Sorry for not submitting this PR on my own! Looks good to me.

I figured I'd go ahead and get it proposed. I don't want to take away from the work you've done on it, though. You've been able to verify it fixes the issue, whereas no matter what I've tried I can't reproduce it.

@jeffret-b
Copy link
Contributor Author

Why not just every RuntimeException ?

We could, but I wanted to keep this narrowly focused on the specific issue some people have reported. I'm inclined to keep it that way, especially considering the reproduction difficulties and the init sequencing issues that must exist.

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whatever works

@oleg-nenashev oleg-nenashev added the ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback label Jul 10, 2019
@oleg-nenashev
Copy link
Member

Will merge tomorrow if no negative feedback

try {
userFromSession = User.getById(authentication.getName(), false);
} catch (IllegalStateException ise) {
logger.warn("Encountered IllegalStateException trying to get a user. System init may not have completed yet. Invalidating user session.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be useful to include the exception in the log message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I debated that myself. My opinion is that because the handling is so narrow, it would just introduce clutter to include the exception. If we broadened the catch, then we would definitely want to add the exception.

Copy link

@proski proski Jul 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It the issue is understood, a stack trace only makes the log look scarier. It's easy to misread a stack trace as an exception that wasn't handled properly.

On the other hand, the message from the exception could be useful to make sure we caught the correct exception.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jvz do you consider this comment as resolved?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, good with me.

@oleg-nenashev oleg-nenashev merged commit 8349ceb into jenkinsci:master Jul 11, 2019
olivergondza pushed a commit that referenced this pull request Aug 1, 2019
This change catches the exception and returns false, invalidating the user session. This behavior is sensible, because if we are unable to validate the user we must assume the session is invalid.
Catching the error at this point reportedly helps with some scenarios and shouldn't cause any further harm.

(cherry picked from commit 8349ceb)
DuMaM pushed a commit to jenkinsci/crowd2-plugin that referenced this pull request Apr 29, 2023
During my testing I have noticed that from time to time when restarting
Jenkins, an `IllegalStateException` is thrown. This issue is similar to
jenkinsci/jenkins#4107 in fact it is the same
issue as we make the same call in our code:


https://github.com/jenkinsci/crowd2-plugin/blob/ff4affe98a969c5bcd4de4211656a8db57e841b4/src/main/java/de/theit/jenkins/crowd/CrowdAuthenticationToken.java#L125

Before this patch the log looked like this:

```
Apr 24 08:23:18 Jenkins-McdCore java[516]: INFO: Jenkins stopped
Apr 24 08:23:19 Jenkins-McdCore java[516]: Apr 24, 2023 8:23:19 AM hudson.init.impl.InstallUncaughtExceptionHandler handleException
Apr 24 08:23:19 Jenkins-McdCore java[516]: WARNING: Caught unhandled exception with ID 2841997a-ee9d-4e6e-a1d0-e36079f288ec
Apr 24 08:23:19 Jenkins-McdCore java[516]: java.lang.IllegalStateException: Expected 1 instance of hudson.model.User$AllUsers but got 0
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at hudson.ExtensionList.lookupSingleton(ExtensionList.java:454)
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at hudson.model.User$AllUsers.getInstance(User.java:1098)
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at hudson.model.User$AllUsers.get(User.java:1116)
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at hudson.model.User.getOrCreateById(User.java:535)
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at hudson.model.User.getById(User.java:638)
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at de.theit.jenkins.crowd.CrowdAuthenticationToken.updateUserInfo(CrowdAuthenticationTok>
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at de.theit.jenkins.crowd.CrowdRememberMeServices.autoLogin(CrowdRememberMeServices.java>
Apr 24 08:23:19 Jenkins-McdCore java[516]:         at de.theit.jenkins.crowd.CrowdServletFilter.doFilter(CrowdServletFilter.java:177)
```

The server would still restart but would produce `Oops! A problem
occurred while processing the request.`.

After the patch:

```
Apr 24 20:13:22 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:22 PM hudson.lifecycle.Lifecycle onStatusUpdate
Apr 24 20:13:22 Jenkins-CrowdAAD java[242796]: INFO: Jenkins stopped
Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:23 PM de.theit.jenkins.crowd.CrowdRememberMeServices autoLogin
Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: WARNING: Encountered IllegalStateException. System init may not have completed yet.
Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:23 PM hudson.security.HttpSessionContextIntegrationFilter2 hasInvalidSessionSeed
Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: WARNING: Encountered IllegalStateException trying to get a user. System init may not have completed yet. Invalidating user session.
Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: Running from: /opt/jenkins_home/jenkins.war
Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: webroot: /opt/jenkins_home/war
Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:25 PM winstone.Logger logInternal
Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: INFO: Beginning extraction from war file

```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback
Projects
None yet
4 participants