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:
    • Sprint:
      Pipeline - December
    • Similar Issues:

      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

            Hide
            brianeray Brian Ray added a comment -

            Note: The two plugins listings in the Attachments are nonexhaustive. Just limited them to Pipeline and Script Security given the nature of the issue.

            Show
            brianeray Brian Ray added a comment - Note: The two plugins listings in the Attachments are nonexhaustive. Just limited them to Pipeline and Script Security given the nature of the issue.
            Hide
            abayer Andrew Bayer added a comment -

            I've narrowed this down to workflow-cps - I can reproduce the error there but not in a non-Pipeline sandboxed Groovy script. Will investigate further.

            Show
            abayer Andrew Bayer added a comment - I've narrowed this down to workflow-cps - I can reproduce the error there but not in a non-Pipeline sandboxed Groovy script. Will investigate further.
            Hide
            abayer Andrew Bayer added a comment -

            Noting for myself as I dig into this tomorrow/Friday - I've determined this was caused by the move to groovy-cps 1.17 and script-security 1.30 (with groovy-sandbox 1.12). Exactly what in there is causing the problem, I'm not sure yet, but will keep looking.

            Show
            abayer Andrew Bayer added a comment - Noting for myself as I dig into this tomorrow/Friday - I've determined this was caused by the move to groovy-cps 1.17 and script-security 1.30 (with groovy-sandbox 1.12). Exactly what in there is causing the problem, I'm not sure yet, but will keep looking.
            Hide
            brianeray Brian Ray added a comment - - edited

            Excellent, thanks for digging into this. In the meantime it was easy enough for me to sweep our pipeline repos and bracket those variadic args to get me over the blocker. And I ran across some older code in which I'd had to do the same thing. It's interesting that the error has manifested consistently inconsistently in different contexts over time.

            Show
            brianeray Brian Ray added a comment - - edited Excellent, thanks for digging into this. In the meantime it was easy enough for me to sweep our pipeline repos and bracket those variadic args to get me over the blocker. And I ran across some older code in which I'd had to do the same thing. It's interesting that the error has manifested consistently inconsistently in different contexts over time.
            Hide
            abayer Andrew Bayer added a comment -

            Grr, running into weirdness due to sprintf not being whitelisted for some tests. Any chance you've got a version of this with another method call?

            Show
            abayer Andrew Bayer added a comment - Grr, running into weirdness due to sprintf not being whitelisted for some tests. Any chance you've got a version of this with another method call?
            Hide
            abayer Andrew Bayer added a comment -

            Ha, that actually revealed something - when I disable sandbox, it works fine. So it's definitely a problem with sandboxing. I'm just confused as to why I couldn't reproduce this in groovy-cps directly...more experiments needed!

            Show
            abayer Andrew Bayer added a comment - Ha, that actually revealed something - when I disable sandbox, it works fine. So it's definitely a problem with sandboxing. I'm just confused as to why I couldn't reproduce this in groovy-cps directly...more experiments needed!
            Hide
            abayer Andrew Bayer added a comment -

            And yeah, I'm not going to lose my mind over this since there is a workaround, but it still irritates me. =)

            Show
            abayer Andrew Bayer added a comment - And yeah, I'm not going to lose my mind over this since there is a workaround, but it still irritates me. =)
            Hide
            brianeray Brian Ray added a comment -

            Regarding trying a method other than sprintf() my gut instinct was that it also had something to do with Groovy's enhancement of Object, so I initially though to try printf(String,Object[]), but that didn't make much sense in the current use case. And use(Object[]) seemed like a real longshot given it does metaprogramming so ... I'll try to come up with another unrelated to Object.

            Show
            brianeray Brian Ray added a comment - Regarding trying a method other than sprintf() my gut instinct was that it also had something to do with Groovy's enhancement of Object , so I initially though to try printf(String,Object[]) , but that didn't make much sense in the current use case. And use(Object[]) seemed like a real longshot given it does metaprogramming so ... I'll try to come up with another unrelated to Object .
            Hide
            abayer Andrew Bayer added a comment -

            printf would always be weird because that ends up defaulting to something magically behind the scenes. I just tried String.format and it worked fine, so yeah, this is definitely related to DefaultGroovyMethods weirdness.

            Show
            abayer Andrew Bayer added a comment - printf would always be weird because that ends up defaulting to something magically behind the scenes. I just tried String.format and it worked fine, so yeah, this is definitely related to DefaultGroovyMethods weirdness.
            Hide
            brianeray Brian Ray added a comment - - edited

            OK that all makes sense. Some print* method(s) are intercepted and routed to echo IIRC.

            And my next experiment implicates DGM too, I think, by home-growing a method with the same signature.

            Interestingly in these tests it doesn't coerce the ArrayList<String>, and throws a distinct exception on the instance field initializer.

            class Smoosher {
              static String smooshEm( String val, Object[] otherVals ) {
                "$val $otherVals".toString()
              }
            }
            
            class ConstantsControl {
              static HOWDY_FOLKS_FMT = 'Good day'
              
              //Arraylist is *not* flattened--winds up as nested list
              static HOWDY_INDUSTRIOUS_ENGINEERS = Smoosher.smooshEm(
                HOWDY_FOLKS_FMT,
                [
                  'engineers',
                  'good people',
                ],
              )
            
              //NoClassDefFoundError on instantiation; see partial stack trace below
              String greeting = Smoosher.smooshEm(
                HOWDY_FOLKS_FMT,
                'friends',
                'in CI land',
              )
            }
            
            class ConstantsBoom {
              static HOWDY_FOLKS_FMT = 'Hello all'
              
              //variadic args are flattened; one-level list
              static HOWDY_JENKINS_DEVS = Smoosher.smooshEm(
                HOWDY_FOLKS_FMT,
                'developers',
                'out there in the Jenkins World',
              )
            }
            
            //Good day [[engineers, good people]]
            echo ConstantsControl.HOWDY_INDUSTRIOUS_ENGINEERS
            
            //Hello all [developers, out there in the Jenkins World]
            echo ConstantsBoom.HOWDY_JENKINS_DEVS
            
            //java.lang.NoClassDefFoundError: Could not initialize class ConstantsControl
            //	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            //	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
            //	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            //	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            //	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
            //	at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
            //	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
            //	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
            //	at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:198)
            //	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onNewInstance(GroovyInterceptor.java:42)
            //	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onNewInstance(SandboxInterceptor.java:136)
            //	at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:195)
            //	at org.kohsuke.groovy.sandbox.impl.Checker.checkedConstructor(Checker.java:200)
            //	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.constructorCall(SandboxInvoker.java:21)
            //	at WorkflowScript.run(WorkflowScript:45)
            //	at ___cps.transform___(Native Method) [etc...]
            cc = new ConstantsControl()
            echo cc.greeting
            
            Show
            brianeray Brian Ray added a comment - - edited OK that all makes sense. Some print* method(s) are intercepted and routed to echo IIRC. And my next experiment implicates DGM too, I think, by home-growing a method with the same signature. Interestingly in these tests it doesn't coerce the ArrayList<String> , and throws a distinct exception on the instance field initializer. class Smoosher { static String smooshEm( String val, Object [] otherVals ) { "$val $otherVals" .toString() } } class ConstantsControl { static HOWDY_FOLKS_FMT = 'Good day' //Arraylist is *not* flattened--winds up as nested list static HOWDY_INDUSTRIOUS_ENGINEERS = Smoosher.smooshEm( HOWDY_FOLKS_FMT, [ 'engineers' , 'good people' , ], ) //NoClassDefFoundError on instantiation; see partial stack trace below String greeting = Smoosher.smooshEm( HOWDY_FOLKS_FMT, 'friends' , 'in CI land' , ) } class ConstantsBoom { static HOWDY_FOLKS_FMT = 'Hello all' //variadic args are flattened; one-level list static HOWDY_JENKINS_DEVS = Smoosher.smooshEm( HOWDY_FOLKS_FMT, 'developers' , 'out there in the Jenkins World' , ) } //Good day [[engineers, good people]] echo ConstantsControl.HOWDY_INDUSTRIOUS_ENGINEERS //Hello all [developers, out there in the Jenkins World] echo ConstantsBoom.HOWDY_JENKINS_DEVS //java.lang.NoClassDefFoundError: Could not initialize class ConstantsControl // at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) // at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) // at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) // at java.lang.reflect.Constructor.newInstance(Constructor.java:423) // at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83) // at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105) // at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60) // at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235) // at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:198) // at org.kohsuke.groovy.sandbox.GroovyInterceptor.onNewInstance(GroovyInterceptor.java:42) // at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onNewInstance(SandboxInterceptor.java:136) // at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:195) // at org.kohsuke.groovy.sandbox.impl.Checker.checkedConstructor(Checker.java:200) // at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.constructorCall(SandboxInvoker.java:21) // at WorkflowScript.run(WorkflowScript:45) // at ___cps.transform___(Native Method) [etc...] cc = new ConstantsControl() echo cc.greeting
            Hide
            abayer Andrew Bayer added a comment -

            And I tell a lie - this is in script-security. A minimal test case failed there - it passed in groovy-sandbox but that was dumb on my part. The problem is that we're not behaving the same as Groovy when looking for a method that has an array in its signature but could be varargs. I need to look at the Groovy method dispatch logic to see how they're handling this.

            Show
            abayer Andrew Bayer added a comment - And I tell a lie - this is in script-security . A minimal test case failed there - it passed in groovy-sandbox but that was dumb on my part. The problem is that we're not behaving the same as Groovy when looking for a method that has an array in its signature but could be varargs. I need to look at the Groovy method dispatch logic to see how they're handling this.
            Hide
            abayer Andrew Bayer added a comment - - edited

            So... this method here seems to be the equivalent to our code here for method selection - ok, analogous, not equivalent. So that's probably what I need to derive from. I think it's still specific to DefaultGroovyMethods to get to the point where the method selection in question is relevant. Anyway, I'll come back to this later. =)

            Show
            abayer Andrew Bayer added a comment - - edited So... this method here seems to be the equivalent to our code here for method selection - ok, analogous, not equivalent. So that's probably what I need to derive from. I think it's still specific to DefaultGroovyMethods to get to the point where the method selection in question is relevant. Anyway, I'll come back to this later. =)
            Hide
            brianeray Brian Ray added a comment -

            Awesome. And that's why I leave the heavy lifting to real computer scientists ... everything I learned about modern languages came from 15 years of fighting with Cobol.

            Show
            brianeray Brian Ray added a comment - Awesome. And that's why I leave the heavy lifting to real computer scientists ... everything I learned about modern languages came from 15 years of fighting with Cobol.
            Hide
            brianeray Brian Ray added a comment - - edited

            Hit another one today. Until today I haven't tried using String.uncapitalize().

            //Works fine
            uc = 'brian'.capitalize()
            echo "uc=$uc"
            
            //hudson.remoting.ProxyException: groovy.lang.MissingMethodException: 
            //No signature of method: java.lang.String.uncapitalize() is applicable for 
            //argument types: () values: []
            //Possible solutions: uncapitalize(), capitalize()
            lc = 'Brian'.uncapitalize()
            echo "lc=$lc"
            

            Full stack trace is

            hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.String.uncapitalize() is applicable for argument types: () values: []
            Possible solutions: uncapitalize(), capitalize()
            	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 com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
            	at WorkflowScript.run(WorkflowScript:9)
            	at ___cps.transform___(Native Method)
            	at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
            	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
            	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:77)
            	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 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)
            

            CharSequence.uncapitalize() is relatively new, unlike capitalize(). And FWIW the latter is a deprecated DGM, while the former is not a DGM at all. Presumably so they will both be symmetrically non-DGM at some point.

            Show
            brianeray Brian Ray added a comment - - edited Hit another one today. Until today I haven't tried using String.uncapitalize() . //Works fine uc = 'brian' .capitalize() echo "uc=$uc" //hudson.remoting.ProxyException: groovy.lang.MissingMethodException: //No signature of method: java.lang. String .uncapitalize() is applicable for //argument types: () values: [] //Possible solutions: uncapitalize(), capitalize() lc = 'Brian' .uncapitalize() echo "lc=$lc" Full stack trace is hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.String.uncapitalize() is applicable for argument types: () values: [] Possible solutions: uncapitalize(), capitalize() 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 com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17) at WorkflowScript.run(WorkflowScript:9) at ___cps.transform___(Native Method) at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57) at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109) at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:77) 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 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) CharSequence.uncapitalize() is relatively new , unlike capitalize() . And FWIW the latter is a deprecated DGM , while the former is not a DGM at all. Presumably so they will both be symmetrically non-DGM at some point.
            Hide
            abayer Andrew Bayer added a comment -

            So: three months later, picking this up again. re uncapitalize(), as of Script Security 1.36, I'm getting

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.StringGroovyMethods uncapitalize java.lang.CharSequence
            

            Which is what I'd expect - it's not whitelisted, so...yeah.

            But regarding the original - that just gets weirder. I'm getting the following in the control case, for the instance field greeting:

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (ConstantsControl sprintf java.lang.String java.lang.String java.lang.String)
            	at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:180)
            	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:135)
            	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:120)
            	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$1.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 ConstantsControl.<init>(WorkflowScript:15)
            	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
            	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
            	at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
            	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
            	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
            	at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:198)
            	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onNewInstance(GroovyInterceptor.java:42)
            	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onNewInstance(SandboxInterceptor.java:146)
            	at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:195)
            	at org.kohsuke.groovy.sandbox.impl.Checker.checkedConstructor(Checker.java:200)
            	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.constructorCall(SandboxInvoker.java:21)
            	at WorkflowScript.run(WorkflowScript:38)
            ...
            

            If I comment out the initialization of ConstantsControl and echoing of cc.greeting, I get the original error on the static field. So...guh.

            Show
            abayer Andrew Bayer added a comment - So: three months later, picking this up again. re uncapitalize() , as of Script Security 1.36, I'm getting org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.StringGroovyMethods uncapitalize java.lang.CharSequence Which is what I'd expect - it's not whitelisted, so...yeah. But regarding the original - that just gets weirder. I'm getting the following in the control case, for the instance field greeting : org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang. String java.lang. Object (ConstantsControl sprintf java.lang. String java.lang. String java.lang. String ) at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:180) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:135) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:120) 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$1.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 ConstantsControl.<init>(WorkflowScript:15) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83) at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235) at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:198) at org.kohsuke.groovy.sandbox.GroovyInterceptor.onNewInstance(GroovyInterceptor.java:42) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onNewInstance(SandboxInterceptor.java:146) at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:195) at org.kohsuke.groovy.sandbox.impl.Checker.checkedConstructor(Checker.java:200) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.constructorCall(SandboxInvoker.java:21) at WorkflowScript.run(WorkflowScript:38) ... If I comment out the initialization of ConstantsControl and echoing of cc.greeting , I get the original error on the static field. So...guh.
            Hide
            abayer Andrew Bayer added a comment -

            Ok, script-security PR up at https://github.com/jenkinsci/script-security-plugin/pull/171 that fixes this. woo!

            Show
            abayer Andrew Bayer added a comment - Ok, script-security PR up at https://github.com/jenkinsci/script-security-plugin/pull/171 that fixes this. woo!
            Hide
            brianeray Brian Ray added a comment -

            Woo! indeed. Thanks.

            And I just retried the uncapitalize() method again on my local Jenkins. It behaved just like you found. After I whitelisted it, it worked fine.

            Show
            brianeray Brian Ray added a comment - Woo! indeed. Thanks. And I just retried the uncapitalize() method again on my local Jenkins. It behaved just like you found. After I whitelisted it, it worked fine.
            Hide
            abayer Andrew Bayer added a comment -

            In 1.38, releasing shortly.

            Show
            abayer Andrew Bayer added a comment - In 1.38, releasing shortly.
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in jenkins
            User: Andrew Bayer
            Path:
            src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/GroovyCallSiteSelector.java
            src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java
            http://jenkins-ci.org/commit/script-security-plugin/66a5ea87fc2ebfe48063dc0ee9d11d737621009d
            Log:
            [FIXED JENKINS-46213] Treat trailing array params as varargs

            Groovy's method lookup logic will treat `sprintf(fmt, "string", "other
            string")` the same as `sprintf(fmt, ["string", "other string"])`. We
            should emulate that.

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Andrew Bayer Path: src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/GroovyCallSiteSelector.java src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java http://jenkins-ci.org/commit/script-security-plugin/66a5ea87fc2ebfe48063dc0ee9d11d737621009d Log: [FIXED JENKINS-46213] Treat trailing array params as varargs Groovy's method lookup logic will treat `sprintf(fmt, "string", "other string")` the same as `sprintf(fmt, ["string", "other string"] )`. We should emulate that.

              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: