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

Saves on templates don't propagate to implementing jobs after upgrading to 1.2

      Hi,

      after migrating from jenkins 1.642 to 2.13, with ez-templates 1.1.2 to 1.2.0, saving a template doesn't propagate the changes to the implementing jobs. Instead this exception is thrown on the logs (after a logger for com.joelj.jenkins.eztemplates is set up):

      18-Jul-2016 09:31:48.381 WARNING [Handling POST /jenkins/JOB_VIEW/MY_JOB/configSubmit from 10.4.11.43 : http-nio-8080-exec-6] hudson.model.listeners.ItemListener.forAll failed to send event to listener of class com.joelj.jenkins.eztemplates.TemplateProjectListener
       java.lang.NullPointerException
              at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187)
              at com.google.common.base.Predicates$InPredicate.<init>(Predicates.java:485)
              at com.google.common.base.Predicates$InPredicate.<init>(Predicates.java:481)
              at com.google.common.base.Predicates.in(Predicates.java:227)
              at com.joelj.jenkins.eztemplates.exclusion.Exclusions.configuredExclusions(Exclusions.java:55)
              at com.joelj.jenkins.eztemplates.utils.TemplateUtils.handleTemplateImplementationSaved(TemplateUtils.java:76)
              at com.joelj.jenkins.eztemplates.utils.TemplateUtils.handleTemplateSaved(TemplateUtils.java:28)
              at com.joelj.jenkins.eztemplates.TemplateProjectListener.onUpdated(TemplateProjectListener.java:21)
              at hudson.model.listeners.ItemListener$3.apply(ItemListener.java:195)
              at hudson.model.listeners.ItemListener$3.apply(ItemListener.java:193)
              at hudson.model.listeners.ItemListener.forAll(ItemListener.java:167)
              at hudson.model.listeners.ItemListener.fireOnUpdated(ItemListener.java:193)
              at hudson.model.Job.doConfigSubmit(Job.java:1221)
              at hudson.model.AbstractProject.doConfigSubmit(AbstractProject.java:796)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:497)
              at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:324)
              at org.kohsuke.stapler.interceptor.RequirePOST$Processor.invoke(RequirePOST.java:52)
              at org.kohsuke.stapler.PreInvokeInterceptedFunction.invoke(PreInvokeInterceptedFunction.java:26)
              at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:167)
              at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:100)
              at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:124)
              at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
              at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
              at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
              at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:233)
              at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
              at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
              at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
              at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:233)
              at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
              at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
              at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
              at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
              at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:135)
              at hudson.plugins.greenballs.GreenBallFilter.doFilter(GreenBallFilter.java:59)
              at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
              at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:126)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:49)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
              at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
              at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)
              at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
              at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
              at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:171)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
              at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
              at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614)
              at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
              at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
              at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
              at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
              at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
              at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
              at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
              at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
              at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
              at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
              at java.lang.Thread.run(Thread.java:745)
      

      The fix seems easy at first, just replace TemplateImplementationProperty#getExclusions() method with:

          public List<String> getExclusions() {
              return exclusions != null ? exclusions : Exclusions.DEFAULT;
          }
      

      However, when locally installing the plugin, jenkins complains about TemplateImplementationProperty not being Describable (java.lang.AssertionError: class com.joelj.jenkins.eztemplates.TemplateProperty is missing its descriptor).

      Jenkins docs suggest making TemplateImplementationProperty extend AbstractDescribableImpl, but as this class is already extending JobProperty, I gave up and switched back to ez-templates 1.1.2, that fixed the issue.

          [JENKINS-36749] Saves on templates don't propagate to implementing jobs after upgrading to 1.2

          Marc Carter added a comment -

          I did test various upgrade scenarios but this would be big problem if repeatable elsewhere.

          Marc Carter added a comment - I did test various upgrade scenarios but this would be big problem if repeatable elsewhere.

          Marc Carter added a comment -

          In reverse order:

          ... missing its descriptor

          This kind of thing happens all the time if running in debug mode or hpi:run etc. Something to do with reloaded classes and it's a Jenkins 'feature' I believe.

          return exclusions != null ? exclusions : Exclusions.DEFAULT;

          The NPE is not entirely unplanned and is actually saving you from a worse outcome which is that all Impls will get rewritten back to the template and lose many of their individual settings.

          saving a template doesn't propagate the changes to the implementing jobs

          The problem is genuine though, migrateExclusions (the key method here) only gets called from the Jelly code for an impl. Hence, they only get upgraded when you manually save the impl and not when automatically processed by a saved template. That's resolvable.

          Workaround until v1.2.1: downgrade again or manually Configure / Save each impl

          Marc Carter added a comment - In reverse order: ... missing its descriptor This kind of thing happens all the time if running in debug mode or hpi:run etc. Something to do with reloaded classes and it's a Jenkins 'feature' I believe. return exclusions != null ? exclusions : Exclusions.DEFAULT; The NPE is not entirely unplanned and is actually saving you from a worse outcome which is that all Impls will get rewritten back to the template and lose many of their individual settings. saving a template doesn't propagate the changes to the implementing jobs The problem is genuine though, migrateExclusions (the key method here) only gets called from the Jelly code for an impl. Hence, they only get upgraded when you manually save the impl and not when automatically processed by a saved template. That's resolvable. Workaround until v1.2.1: downgrade again or manually Configure / Save each impl

          Code changed in jenkins
          User: Marc Carter
          Path:
          src/main/java/com/joelj/jenkins/eztemplates/TemplateImplementationProperty.java
          src/main/java/com/joelj/jenkins/eztemplates/utils/TemplateUtils.java
          src/main/resources/com/joelj/jenkins/eztemplates/TemplateImplementationProperty/config.jelly
          http://jenkins-ci.org/commit/ez-templates-plugin/51d0fcb6915fcb501fa085b01451969134ba8b36
          Log:
          bugfix: JENKINS-36749 Saves on templates don't propagate to implementing jobs after upgrading to 1.2

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Marc Carter Path: src/main/java/com/joelj/jenkins/eztemplates/TemplateImplementationProperty.java src/main/java/com/joelj/jenkins/eztemplates/utils/TemplateUtils.java src/main/resources/com/joelj/jenkins/eztemplates/TemplateImplementationProperty/config.jelly http://jenkins-ci.org/commit/ez-templates-plugin/51d0fcb6915fcb501fa085b01451969134ba8b36 Log: bugfix: JENKINS-36749 Saves on templates don't propagate to implementing jobs after upgrading to 1.2

          Marc Carter added a comment -

          Fixed in 1.2.1

          Marc Carter added a comment - Fixed in 1.2.1

            drekbour Marc Carter
            juanpablo Juan Pablo Santos Rodríguez
            Votes:
            2 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: