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

HistoryWidget/entry.jelly throws NullPointerException

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Critical Critical
    • core

      I have a job with 100 builds in the history. Builds 69 through 100 are listed in the job page. When I click "more..." to see jobs 68 and older I get the following exception:

      Status Code: 500
      Exception: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Users/Gili/.jenkins/war/WEB-INF/lib/jenkins-core-1.485.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException
      Stacktrace:
      
      javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Users/Gili/.jenkins/war/WEB-INF/lib/jenkins-core-1.485.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException
      	at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:103)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:574)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:659)
      	at org.kohsuke.stapler.MetaClass$12.dispatch(MetaClass.java:384)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:574)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:659)
      	at org.kohsuke.stapler.MetaClass$6.doDispatch(MetaClass.java:241)
      	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:574)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:659)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:488)
      	at org.kohsuke.stapler.Stapler.service(Stapler.java:162)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:45)
      	at winstone.ServletConfiguration.execute(ServletConfiguration.java:248)
      	at winstone.RequestDispatcher.forward(RequestDispatcher.java:333)
      	at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:376)
      	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:95)
      	at hudson.plugins.audit_trail.AuditTrailFilter.doFilter(AuditTrailFilter.java:66)
      	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:98)
      	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:87)
      	at winstone.FilterConfiguration.execute(FilterConfiguration.java:194)
      	at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:366)
      	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:47)
      	at winstone.FilterConfiguration.execute(FilterConfiguration.java:194)
      	at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:366)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
      	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
      	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:164)
      	at winstone.FilterConfiguration.execute(FilterConfiguration.java:194)
      	at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:366)
      	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:50)
      	at winstone.FilterConfiguration.execute(FilterConfiguration.java:194)
      	at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:366)
      	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81)
      	at winstone.FilterConfiguration.execute(FilterConfiguration.java:194)
      	at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:366)
      	at winstone.RequestDispatcher.forward(RequestDispatcher.java:331)
      	at winstone.RequestHandlerThread.processRequest(RequestHandlerThread.java:215)
      	at winstone.RequestHandlerThread.run(RequestHandlerThread.java:138)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
      	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
      	at java.util.concurrent.FutureTask.run(Unknown Source)
      	at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      	at java.lang.Thread.run(Unknown Source)
      Caused by: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Users/Gili/.jenkins/war/WEB-INF/lib/jenkins-core-1.485.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException
      	at org.apache.commons.jelly.impl.TagScript.handleException(TagScript.java:726)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:281)
      	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
      	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:81)
      	at org.kohsuke.stapler.jelly.IncludeTag.doTag(IncludeTag.java:146)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
      	at org.apache.commons.jelly.tags.core.ForEachTag.doTag(ForEachTag.java:150)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:81)
      	at org.kohsuke.stapler.jelly.IncludeTag.doTag(IncludeTag.java:146)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:81)
      	at org.kohsuke.stapler.jelly.IncludeTag.doTag(IncludeTag.java:146)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:98)
      	at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:119)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:81)
      	at org.kohsuke.stapler.jelly.IncludeTag.doTag(IncludeTag.java:146)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:98)
      	at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
      	at org.apache.commons.jelly.tags.core.OtherwiseTag.doTag(OtherwiseTag.java:41)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
      	at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
      	at org.apache.commons.jelly.tags.core.ChooseTag.doTag(ChooseTag.java:38)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:119)
      	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
      	at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:81)
      	at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:63)
      	at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:53)
      	at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:95)
      	... 45 more
      Caused by: java.lang.NullPointerException
      	at java.util.Calendar.setTime(Unknown Source)
      	at java.text.SimpleDateFormat.format(Unknown Source)
      	at java.text.SimpleDateFormat.format(Unknown Source)
      	at java.text.DateFormat.format(Unknown Source)
      	at org.apache.commons.jelly.tags.fmt.FormatDateTag.doTag(FormatDateTag.java:182)
      	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
      	... 100 more
      

          [JENKINS-15499] HistoryWidget/entry.jelly throws NullPointerException

          cowwoc created issue -

          Hansen Loke added a comment -

          I get this error after upgrading to Jenkins 1.485 too

          Hansen Loke added a comment - I get this error after upgrading to Jenkins 1.485 too

          There is/was a critical bug or two in 1.485 related to the lazy loading. See JENKINS-15465 and JENKINS-15439. I'm pretty sure that those are the issues that you are seeing.

          Kohsuke backported the fixes to the 1.486 release candidate build. You can download a pre-release build from
          https://ci.jenkins-ci.org/view/Jenkins%20core/job/jenkins_rc_branch/279/

          Richard Mortimer added a comment - There is/was a critical bug or two in 1.485 related to the lazy loading. See JENKINS-15465 and JENKINS-15439 . I'm pretty sure that those are the issues that you are seeing. Kohsuke backported the fixes to the 1.486 release candidate build. You can download a pre-release build from https://ci.jenkins-ci.org/view/Jenkins%20core/job/jenkins_rc_branch/279/

          Itaru Ogawa added a comment -

          I saw the exact same error even with 1.486.

          Status Code: 500
          Exception: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/ROOT/WEB-INF/lib/jenkins-core-1.486.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException
          Stacktrace:
          javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/ROOT/WEB-INF/lib/jenkins-core-1.486.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException
          	at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:103)
          	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:574)
                  ...
          

          Itaru Ogawa added a comment - I saw the exact same error even with 1.486. Status Code: 500 Exception: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/ROOT/WEB-INF/lib/jenkins-core-1.486.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException Stacktrace: javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/ROOT/WEB-INF/lib/jenkins-core-1.486.jar!/hudson/widgets/HistoryWidget/entry.jelly:39:106: <i:formatDate> java.lang.NullPointerException at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:103) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:574) ...

          Hansen Loke added a comment -

          Updated to 1.486 and the issue is still there, similar backtrace.

          Hansen Loke added a comment - Updated to 1.486 and the issue is still there, similar backtrace.

          Looking at the output from an affected job the /job/hudson8462/buildHistory/all output contains a link to the console output which contains //console.

          <tr class="build-row no-wrap "><td><a href="/job/hudson8462//console">
          

          The build number should be between the // so that suggests that ${build} is null in /hudson/widgets/HistoryWidget/entry.jelly

          That in turn means that getRenderList() in HistoryWidget.java is returning null values in the list.

          Richard Mortimer added a comment - Looking at the output from an affected job the /job/hudson8462/buildHistory/all output contains a link to the console output which contains //console. <tr class= "build-row no-wrap " ><td><a href= "/job/hudson8462 //console" > The build number should be between the // so that suggests that ${build} is null in /hudson/widgets/HistoryWidget/entry.jelly That in turn means that getRenderList() in HistoryWidget.java is returning null values in the list.

          The failure can be provoked easily by directly accessing the "buildHistory/all" data for any job irrespective of the number of build records that it has stored. i.e. access to teh

          https://ci.jenkins-ci.org/job/jenkins_main_trunk/buildHistory/all
          

          Digging deeper into this issue and the problem is more subtle than HistoryWidget#getRenderList() returning an Iterable that returns null values. In the "all" case it returns the underlying RunList for the job.

          Having examined the RunList at runtime I can see that it implements both the Iterable and Map interfaces. It looks like Jelly in core/src/main/resources/hudson/widgets/HistoryWidget/entries.jelly is iterating over this by getting the entrySet() of the map. The individual entries of the entrySet are Map.Entry values rather than the Run entry that we expect. This causes jelly to fail to access the individual components of the entry and eventually causes the NPE that is reported in this bug.

          I can see from instrumenting the code that the Jelly iterator in
          The problem is that in 1.485 the underlying RunList is now a

          Richard Mortimer added a comment - The failure can be provoked easily by directly accessing the "buildHistory/all" data for any job irrespective of the number of build records that it has stored. i.e. access to teh https: //ci.jenkins-ci.org/job/jenkins_main_trunk/buildHistory/all Digging deeper into this issue and the problem is more subtle than HistoryWidget#getRenderList() returning an Iterable that returns null values. In the "all" case it returns the underlying RunList for the job. Having examined the RunList at runtime I can see that it implements both the Iterable and Map interfaces. It looks like Jelly in core/src/main/resources/hudson/widgets/HistoryWidget/entries.jelly is iterating over this by getting the entrySet() of the map. The individual entries of the entrySet are Map.Entry values rather than the Run entry that we expect. This causes jelly to fail to access the individual components of the entry and eventually causes the NPE that is reported in this bug. I can see from instrumenting the code that the Jelly iterator in The problem is that in 1.485 the underlying RunList is now a

          I think that this change in behaviour came about by the change to using lazy loading of build records. Due to this change the RunList is now a RunMap which implements Map and hence causes the problem.

          This needs Kohsuke's input because I suspect the fix needs to be made carefully to somehow hide the map because I'm sure that there is lots of Jelly code that will be otherwise silently broken too.

          Richard Mortimer added a comment - I think that this change in behaviour came about by the change to using lazy loading of build records. Due to this change the RunList is now a RunMap which implements Map and hence causes the problem. This needs Kohsuke's input because I suspect the fix needs to be made carefully to somehow hide the map because I'm sure that there is lots of Jelly code that will be otherwise silently broken too.
          Richard Mortimer made changes -
          Assignee New: Kohsuke Kawaguchi [ kohsuke ]

          See https://github.com/oldelvet/jenkins/tree/jenkins-15499-demo for an example that fixes the specific HistoryWidget problem. I don't intend that this as a final fix but provide it to highlight that wrapping the iterable in a clean class restores previous working behaviour.

          Richard Mortimer added a comment - See https://github.com/oldelvet/jenkins/tree/jenkins-15499-demo for an example that fixes the specific HistoryWidget problem. I don't intend that this as a final fix but provide it to highlight that wrapping the iterable in a clean class restores previous working behaviour.

            oldelvet Richard Mortimer
            cowwoc cowwoc
            Votes:
            37 Vote for this issue
            Watchers:
            48 Start watching this issue

              Created:
              Updated:
              Resolved: