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

unclassified new org.codehaus.groovy.runtime.GStringImpl java.lang.String java.lang.String[]

    XMLWordPrintable

    Details

    • Similar Issues:

      Description

      Defining and running a workflow, from a Groovy CPS DSL from SCM with this repo:
      https://github.com/witokondoria/jenkins-workflow-issues, branch master and script path test.groovy throws an exception:

      org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified new org.codehaus.groovy.runtime.GStringImpl java.lang.String java.lang.String[]
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onNewInstance(SandboxInterceptor.java:84)
      	at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:126)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedConstructor(Checker.java:123)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.constructorCall(SandboxInvoker.java:19)
      	at Script1.startServices(Script1.groovy:20)
      	at WorkflowScript.run(WorkflowScript:24)
      	at Unknown.Unknown(Unknown)
      	at ___cps.transform___(Native Method)
      	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:90)
      	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:76)
      	at sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
      	at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:71)
      	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:100)
      	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:76)
      	at sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	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:58)
      	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:145)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:106)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
      	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:268)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:71)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:177)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:175)
      	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
      	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:111)
      	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      	at java.lang.Thread.run(Thread.java:745)
      

        Attachments

          Issue Links

            Activity

            Hide
            jglick Jesse Glick added a comment -

            Just saw that the duplicate is actually a slightly different signature:

            unclassified new org.codehaus.groovy.runtime.GStringImpl groovy.lang.GString$2 java.lang.String[]
            
            Show
            jglick Jesse Glick added a comment - Just saw that the duplicate is actually a slightly different signature: unclassified new org.codehaus.groovy.runtime.GStringImpl groovy.lang.GString$2 java.lang.String[]
            Hide
            espenalb espenalb added a comment -

            Here is another one:
            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method java.lang.String join java.lang.String

            Show
            espenalb espenalb added a comment - Here is another one: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method java.lang.String join java.lang.String
            Hide
            rg Russell Gallop added a comment -

            Saw this with:

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method byte[] encodeBase64

            Show
            rg Russell Gallop added a comment - Saw this with: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method byte[] encodeBase64
            Hide
            psufoxman Ryan Fox added a comment -

            I saw this:

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field groovy.util.Node project

            Show
            psufoxman Ryan Fox added a comment - I saw this: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field groovy.util.Node project
            Hide
            greenscar James Sandlin added a comment - - edited

            can't use join

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method java.lang.String[] join
            Show
            greenscar James Sandlin added a comment - - edited can't use join org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method java.lang. String [] join
            Hide
            leandroferes Leandro Ribeiro added a comment - - edited

            The same as the one reported by Ryan Fox:

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field groovy.util.Node version

            (trying to read the tag "version" from a xml file).

            Env:
            Jenkins 2.10
            Pipeline plugin 2.2
            Script Security plugin 1.21

            Show
            leandroferes Leandro Ribeiro added a comment - - edited The same as the one reported by Ryan Fox: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field groovy.util.Node version (trying to read the tag "version" from a xml file). Env: Jenkins 2.10 Pipeline plugin 2.2 Script Security plugin 1.21
            Hide
            lionelve Lionel Orellana added a comment -

            org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method hudson.scm.SubversionChangeLogSet getMsg

            Jenkins 2.28
            Script Security plugin 1.24

            Show
            lionelve Lionel Orellana added a comment - org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method hudson.scm.SubversionChangeLogSet getMsg Jenkins 2.28 Script Security plugin 1.24
            Hide
            jglick Jesse Glick added a comment -

            Many of these are likely to be unrelated issues. There are numerous reasons why an “unclassified method” error can be thrown, due to different vagaries of Groovy semantics which are not properly handled.

            Show
            jglick Jesse Glick added a comment - Many of these are likely to be unrelated issues. There are numerous reasons why an “unclassified method” error can be thrown, due to different vagaries of Groovy semantics which are not properly handled.
            Hide
            abayer Andrew Bayer added a comment -

            So the original error here is because of the following:

            lib.KAFKAIMG = ['KAFKAIP', 'kafka:0.8.1.1', 1, "--env \"ZK_CONNECT=${-> lib.IPS['ZKIP']}:2181\" "]
            

            Specifically, referencing lib.KAFKAIMG[2] inside a GString itself is where things blow up. This is because something's going wrong with the nested lazy GString. Here's a more minimal reproduction case:

            def foo = "foo"
            def bar = "ha ${ -> foo } ha"
            echo "hee ${bar} hee"
            

            I'm not yet sure what inside the sandbox code is at fault here (or if it's actually somewhere off in CPS transformation), but hey, more info is useful.

            Show
            abayer Andrew Bayer added a comment - So the original error here is because of the following: lib.KAFKAIMG = [ 'KAFKAIP' , 'kafka:0.8.1.1' , 1, "--env \" ZK_CONNECT=${-> lib.IPS[ 'ZKIP' ]}:2181\ " " ] Specifically, referencing lib.KAFKAIMG [2] inside a GString itself is where things blow up. This is because something's going wrong with the nested lazy GString . Here's a more minimal reproduction case: def foo = "foo" def bar = "ha ${ -> foo } ha" echo "hee ${bar} hee" I'm not yet sure what inside the sandbox code is at fault here (or if it's actually somewhere off in CPS transformation), but hey, more info is useful.
            Hide
            abayer Andrew Bayer added a comment -

            It's CPS - same thing works fine in a script-security test, and when not sandboxed in a Pipeline job, fails with groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.codehaus.groovy.runtime.GStringImpl(java.lang.String, [Ljava.lang.String.

            Show
            abayer Andrew Bayer added a comment - It's CPS - same thing works fine in a script-security test, and when not sandboxed in a Pipeline job, fails with groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.codehaus.groovy.runtime.GStringImpl(java.lang.String, [Ljava.lang.String .
            Hide
            abayer Andrew Bayer added a comment - - edited

            And found it - well, found the problem, not yet a solution.

            GString#writeTo(Writer) will end up calling InvokerHelper.write(out, c.call()) if the GString replacement value is a Closure - i.e., "in a GString ${ -> thisPart} is a Closure with the -> included". That results in a CpsClosure being created and a CpsCallableInvocation getting thrown when GString#writeTo(Writer) is called. What we'd want there is to have that CpsCallableInvocation caught properly and handled by the CPS runtime, but because it's getting thrown within the GString internals, that's not happening.

            So what, if anything, can be done about this? Well, there's an easy way to work around it for users - don't do "closures ${ -> inside } GStrings" - just do "this ${instead}.". Lazy evaluation is nice but not if it, y'know, breaks all the things. =) But in terms of actually making lazy closures inside a GString work properly? Not sure yet if that's possible. It probably would require overriding GStringImpl with our own implementation of GString#writeTo(Writer), I think? Probably not worth doing...it might make more sense to error out with a useful message if we see this sort of scenario.

            Also worth noting - the following:

            def foo = "foo"
            echo "ha ${ -> foo } ha"
            

            will barf out with a CpsCallableInvocation directly. I'm pretty sure that the more complex scenario of a nested reference is giving the unclassified error because the CpsCallableInvocation from inside is mucking up the call to new GStringImpl.

            Show
            abayer Andrew Bayer added a comment - - edited And found it - well, found the problem, not yet a solution. GString#writeTo(Writer) will end up calling InvokerHelper.write(out, c.call()) if the GString replacement value is a Closure - i.e., "in a GString ${ -> thisPart} is a Closure with the -> included" . That results in a CpsClosure being created and a CpsCallableInvocation getting thrown when GString#writeTo(Writer) is called. What we'd want there is to have that CpsCallableInvocation caught properly and handled by the CPS runtime, but because it's getting thrown within the GString internals, that's not happening. So what, if anything, can be done about this? Well, there's an easy way to work around it for users - don't do "closures ${ -> inside } GStrings" - just do "this ${instead}." . Lazy evaluation is nice but not if it, y'know, breaks all the things. =) But in terms of actually making lazy closures inside a GString work properly? Not sure yet if that's possible. It probably would require overriding GStringImpl with our own implementation of GString#writeTo(Writer) , I think? Probably not worth doing...it might make more sense to error out with a useful message if we see this sort of scenario. Also worth noting - the following: def foo = "foo" echo "ha ${ -> foo } ha" will barf out with a CpsCallableInvocation directly. I'm pretty sure that the more complex scenario of a nested reference is giving the unclassified error because the CpsCallableInvocation from inside is mucking up the call to new GStringImpl .
            Hide
            witokondoria Javier Delgado added a comment -

            The fact of using a lazy evaluation (at the initial use case) was due first variable not being initialized on its definition, but at a later stage.

            My hacky fix, it someone needs it, was to reimplemtent the GStringImpl.toString method (creating a string from the GString strings and values) and providing that reimplementation on a NonCPS method

            Show
            witokondoria Javier Delgado added a comment - The fact of using a lazy evaluation (at the initial use case) was due first variable not being initialized on its definition, but at a later stage. My hacky fix, it someone needs it, was to reimplemtent the GStringImpl.toString method (creating a string from the GString strings and values) and providing that reimplementation on a NonCPS method
            Hide
            jglick Jesse Glick added a comment -

            I see no reason to try to support closures (lazy interpolation) inside a GString. This obscure Groovy feature can be easily replaced by the more straightforward idiom of defining a closure which returns a GString constructed using eager interpolation. So I am treating this as a duplicate of JENKINS-31314: the attempt to use this idiom ought to fail with a clear diagnostic message.

            Show
            jglick Jesse Glick added a comment - I see no reason to try to support closures (lazy interpolation) inside a GString . This obscure Groovy feature can be easily replaced by the more straightforward idiom of defining a closure which returns a GString constructed using eager interpolation. So I am treating this as a duplicate of JENKINS-31314 : the attempt to use this idiom ought to fail with a clear diagnostic message.

              People

              • Assignee:
                abayer Andrew Bayer
                Reporter:
                witokondoria Javier Delgado
              • Votes:
                7 Vote for this issue
                Watchers:
                14 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: