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

Varargs call to sprintf() from static field throws MissingMethodException after plugins upgrade

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Minor
    • Resolution: Fixed
    • Component/s: script-security-plugin
    • Labels:
      None
    • Environment:
    • Similar Issues:
    • Sprint:
      Pipeline - December

      Description

      After upgrading my local dev Jenkins instance core and plugins, calling sprintf() with varargs from the initial value of a static field throws the following exception. (Running in sandbox mode.):

      hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.Class.sprintf() is applicable for argument types: (java.lang.String, java.lang.String, java.lang.String) values: [Hello all you %s out there in %s, developers, the Jenkins World]
      Possible solutions: sprintf(java.lang.String, java.lang.Object), sprintf(java.lang.String, [Ljava.lang.Object;), printf(java.lang.String, [Ljava.lang.Object;), printf(java.lang.String, java.lang.Object), println(), print(java.io.PrintWriter)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:121)
      	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:153)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:157)
      	at org.kohsuke.groovy.sandbox.impl.Checker$checkedCall$2.callStatic(Unknown Source)
      	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194)
      	at ConstantsBoom.<clinit>(WorkflowScript:26)
      	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:498)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
      	at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1855)
      	at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3758)
      	at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:177)
      	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
      	at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:284)
      	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:334)
      	at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:282)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:286)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
      	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
      Caused: hudson.remoting.ProxyException: java.lang.ExceptionInInitializerError
      	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:498)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
      	at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1855)
      	at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3758)
      	at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:177)
      	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
      	at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:284)
      	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:334)
      	at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:282)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:286)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
      	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
      	at WorkflowScript.run(WorkflowScript:48)
      	at ___cps.transform___(Native Method)
      	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
      	at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
      	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
      	at sun.reflect.GeneratedMethodAccessor365.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
      	at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
      	at com.cloudbees.groovy.cps.Next.step(Next.java:83)
      	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:173)
      	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:162)
      	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
      	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
      	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:162)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:35)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:32)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:32)
      	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:330)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:82)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:242)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:230)
      	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
      	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      	at java.lang.Thread.run(Thread.java:748)
      

      A script to reproduce, along with a few control tests that do not throw the exception, is:

      class ConstantsControl {
        static HOWDY_FOLKS_FMT = 'Good day %s wherever you are in %s'
        
        //two args; last presumably autocasted to Object[]
        static HOWDY_INDUSTRIOUS_ENGINEERS = sprintf(
          HOWDY_FOLKS_FMT,
          [
            'engineers',
            'the world',
          ],
        )
      
        //3 args; variadic call String, Object...; last autocasted to Object[]
        String greeting = sprintf(
          HOWDY_FOLKS_FMT,
          'friends',
          'CI land',
        )
      }
      
      class ConstantsBoom {
        static HOWDY_FOLKS_FMT = 'Hello all you %s out there in %s'
        
        //MissingMethodException as below
        static HOWDY_JENKINS_DEVS = sprintf(
          HOWDY_FOLKS_FMT,
          'developers',
          'the Jenkins World',
        )
      }
      
      //Production: script-security 1.29 + workflow-cps 2.36
      //Local: script-security 1.31 + workflow-cps 2.39
      //
      //(control tests); no exceptions in either Jenkins instance
      echo ConstantsControl.HOWDY_INDUSTRIOUS_ENGINEERS
      
      cc = new ConstantsControl()
      echo cc.greeting
      
      //Production: script-security 1.29 + workflow-cps 2.36
      //no exception
      //
      //Local: script-security 1.31 + workflow-cps 2.39
      //hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No 
      //signature of method: java.lang.Class.sprintf() is applicable for argument 
      //types: (java.lang.String, java.lang.String, java.lang.String) ...
      echo ConstantsBoom.HOWDY_JENKINS_DEVS
      

      As noted in the comments the variadic call in the static field works fine in the older production instance, and the variadic call in the instance field works fine in both instances. Plus there's the workaround of passing an ArrayList. The <clinit> context makes me wonder if this is similar to the recent issues with static initializers and final fields, but that's just a guess.

        Attachments

          Issue Links

            Activity

            brianeray Brian Ray created issue -
            abayer Andrew Bayer made changes -
            Field Original Value New Value
            Component/s script-security-plugin [ 18520 ]
            abayer Andrew Bayer made changes -
            Assignee Andrew Bayer [ abayer ]
            abayer Andrew Bayer made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            abayer Andrew Bayer made changes -
            Component/s script-security-plugin [ 18520 ]
            Component/s workflow-cps-plugin [ 21713 ]
            jamesdumay James Dumay made changes -
            Sprint Pipeline - December [ 446 ]
            jamesdumay James Dumay made changes -
            Rank Ranked lower
            abayer Andrew Bayer made changes -
            Status In Progress [ 3 ] Open [ 1 ]
            abayer Andrew Bayer made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            abayer Andrew Bayer made changes -
            Status In Progress [ 3 ] In Review [ 10005 ]
            abayer Andrew Bayer made changes -
            Remote Link This issue links to "PR #171 (Web Link)" [ 19302 ]
            abayer Andrew Bayer made changes -
            Status In Review [ 10005 ] Resolved [ 5 ]
            Resolution Fixed [ 1 ]

              People

              • Assignee:
                abayer Andrew Bayer
                Reporter:
                brianeray Brian Ray
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: