Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-45977

UserProperty not defensive - causes HTTP 500 errors when rendering myViews

      java.lang.AssertionError: class org.jenkinsci.plugins.googlelogin.GoogleUserInfo is missing its descriptor
      	at jenkins.model.Jenkins.getDescriptorOrDie(Jenkins.java:1537)
      	at hudson.model.UserProperty.getDescriptor(UserProperty.java:67)
      	at hudson.model.UserProperty.getDescriptor(UserProperty.java:52)
      	at hudson.model.Descriptor.toMap(Descriptor.java:989)
      	at hudson.model.User.getProperties(User.java:270)
      	at hudson.model.User.getPropertyActions(User.java:978)
      	at hudson.model.User.getDynamic(User.java:964)
      	at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
      	at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343)
      	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:184)
      	at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:372)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
      

      This can happen for a variety of reasons

      • one plugin is bad (should not affect others)
      • temporary issue in development
      • The UserProperty is loaded from a different class loader and as such the extension is not picked up at jenkins boot time - where it is acceptable to not show any configuration for the property.

          [JENKINS-45977] UserProperty not defensive - causes HTTP 500 errors when rendering myViews

          Li Ke added a comment -

          How can we fix this? Seems like we cannot just replace getDescriptorOrDie with getDescriptor. What's the expected behavior if no descriptor found?

          Li Ke added a comment - How can we fix this? Seems like we cannot just replace getDescriptorOrDie with getDescriptor. What's the expected behavior if no descriptor found?

          James Nord added a comment -

          getDescriptor() is not marked as notNull - and https://github.com/jenkinsci/jenkins/blob/b649939009f4a8c3356a953ca8d98a96244346c8/core/src/main/java/hudson/model/Descriptor.java#L987 should either catch the assertionError (which IMO should never be thrown at runtime without assertions being enabled) or check for null before populating the map.

          James Nord added a comment - getDescriptor() is not marked as notNull - and https://github.com/jenkinsci/jenkins/blob/b649939009f4a8c3356a953ca8d98a96244346c8/core/src/main/java/hudson/model/Descriptor.java#L987 should either catch the assertionError (which IMO should never be thrown at runtime without assertions being enabled) or check for null before populating the map.

          Jesse Glick added a comment -

          I do not get a 500, but rather a warning in the logs

          … WARNING	h.ExpressionFactory2$JexlExpression#evaluate: Caught exception evaluating: it.properties in /me/configure. Reason: java.lang.reflect.InvocationTargetException
          java.lang.AssertionError: class org.jenkinsci.plugins.googlelogin.GoogleUserInfo is missing its descriptor
          	at jenkins.model.Jenkins.getDescriptorOrDie(Jenkins.java:1521)
          	at hudson.model.UserProperty.getDescriptor(UserProperty.java:67)
          	at hudson.model.UserProperty.getDescriptor(UserProperty.java:52)
          	at hudson.model.Descriptor.toMap(Descriptor.java:987)
          	at hudson.model.User.getProperties(User.java:272)
          

          and then the rest of the page is broken because instance == null for other SomeUserProperty/config.jelly; in particular for MyViewsProperty this results in /viewExistsCheck?value=&exists=true being called rather than /user/dev/my-views/viewExistsCheck?value=&exists=true, with the result that Jenkins.doViewExistsCheck is called rather than MyViewsProperty.doViewExistsCheck, and while the View.CREATE check in the latter should always pass (since you have admin permission on your own User), on the former it will fail if you lack View.CREATE on Jenkins. Thus a 403 is returned from the AJAX call rather than a form validation response, and thus other AJAX calls on the same page are skipped and the whole form is more or less broken.

          Jesse Glick added a comment - I do not get a 500, but rather a warning in the logs … WARNING h.ExpressionFactory2$JexlExpression#evaluate: Caught exception evaluating: it.properties in /me/configure. Reason: java.lang.reflect.InvocationTargetException java.lang.AssertionError: class org.jenkinsci.plugins.googlelogin.GoogleUserInfo is missing its descriptor at jenkins.model.Jenkins.getDescriptorOrDie(Jenkins.java:1521) at hudson.model.UserProperty.getDescriptor(UserProperty.java:67) at hudson.model.UserProperty.getDescriptor(UserProperty.java:52) at hudson.model.Descriptor.toMap(Descriptor.java:987) at hudson.model.User.getProperties(User.java:272) and then the rest of the page is broken because instance == null for other SomeUserProperty/config.jelly ; in particular for MyViewsProperty this results in /viewExistsCheck?value=&exists=true being called rather than /user/dev/my-views/viewExistsCheck?value=&exists=true , with the result that Jenkins.doViewExistsCheck is called rather than MyViewsProperty.doViewExistsCheck , and while the View.CREATE check in the latter should always pass (since you have admin permission on your own User ), on the former it will fail if you lack View.CREATE on Jenkins . Thus a 403 is returned from the AJAX call rather than a form validation response, and thus other AJAX calls on the same page are skipped and the whole form is more or less broken.

          Jesse Glick added a comment -

          Merged minimal robustness fix towards 2.88.

          FTR the case I had observed seems to have been caused by a bug in CloudBees Jenkins Operations Center.

          Jesse Glick added a comment - Merged minimal robustness fix towards 2.88. FTR the case I had observed seems to have been caused by a bug in CloudBees Jenkins Operations Center.

            jglick Jesse Glick
            teilo James Nord
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: