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

Passing map literal values to method in shared library causes UnsupportedOperationException

    Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Environment:
    • Similar Issues:

      Description

      Passing a map literal value to a custom step function inside of a shared library appears to cause an "UnsupportedOperationException" and gives the following error message

      BUG! exception in phase 'semantic analysis' in source unit 'WorkflowScript' The lookup for foo.Foo caused a failed compilaton. There should not have been any compilation from this call.

      I've reproduced this error for the following toy case:

      Jenkinsfile:

      /* Import the utility library that contains the Foo class. */
      @Library('jenkins-build-utilities@debug')
      import foo.Foo
      
      def fooObj = new Foo(this)
      
      node('system')
      {
          stage('FooHello')
          {
              fooObj.sayHello()
          }
      }
      

      Foo class in shared library:

      // src/foo/Foo.groovy
      package foo
      
      class Foo implements Serializable {
      
       private def jenkins = null
      
       Foo(jenkinsfile) { this.jenkins = jenkinsfile }
      
       public def sayHello() { customEcho [message: "Hello from Foo!"] }
      
       public def customEcho(arg) { jenkins.echo arg.message }
      }
      

      Note that this code only throws an exception when a literal map value is passed to customEcho. If I rewrite the method sayHello as given below, then no exception occurs:

      // This version of sayHello will work and will print "Hello from Foo!" to the
      // console.
      public def sayHello() { 
        def mapVariable = [message: "Hello from Foo!"]
        customEcho mapVariable
      }
      

      Finally, I want to mention that we are pretty sure that the original code, which was directly passing literal map values to another method, was working in prior versions of Jenkins and the Pipeline: Groovy plugin.  I've tried reverting the versions of both Jenkins and the plugin and this bug exists in the following versions:

      Jenkins 2.124 - 2.134

      Pipeline: Groovy plugin 2.53 - 2.54

      I was not able to find a prior version in which this bug disappears, but I'm thinking that this might be caused by the Pipeline: Groovy plugin since that was recently upgraded several versions.

      Console Output from failing example:

      java.lang.UnsupportedOperationException
      at com.cloudbees.groovy.cps.CpsTransformer.visitMapEntryExpression(CpsTransformer.java:944)
      at org.codehaus.groovy.ast.expr.MapEntryExpression.visit(MapEntryExpression.java:39)
      at com.cloudbees.groovy.cps.CpsTransformer.visit(CpsTransformer.java:346)
      at com.cloudbees.groovy.cps.CpsTransformer$24.run(CpsTransformer.java:834)
      at com.cloudbees.groovy.cps.CpsTransformer.makeChildren(CpsTransformer.java:435)
      at com.cloudbees.groovy.cps.CpsTransformer.makeNode(CpsTransformer.java:398)
      at com.cloudbees.groovy.cps.CpsTransformer.visitBinaryExpression(CpsTransformer.java:829)
      at org.codehaus.groovy.ast.expr.BinaryExpression.visit(BinaryExpression.java:51)
      at com.cloudbees.groovy.cps.CpsTransformer.visit(CpsTransformer.java:346)
      at com.cloudbees.groovy.cps.CpsTransformer.visitExpressionStatement(CpsTransformer.java:577)
      at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:42)
      at com.cloudbees.groovy.cps.CpsTransformer.visit(CpsTransformer.java:346)
      at com.cloudbees.groovy.cps.CpsTransformer.visit(CpsTransformer.java:352)
      at com.cloudbees.groovy.cps.CpsTransformer$5.run(CpsTransformer.java:503)
      at com.cloudbees.groovy.cps.CpsTransformer.makeChildren(CpsTransformer.java:435)
      at com.cloudbees.groovy.cps.CpsTransformer.makeNode(CpsTransformer.java:398)
      at com.cloudbees.groovy.cps.CpsTransformer.visitBlockStatement(CpsTransformer.java:500)
      at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      at com.cloudbees.groovy.cps.CpsTransformer.visit(CpsTransformer.java:346)
      at com.cloudbees.groovy.cps.CpsTransformer$2.run(CpsTransformer.java:377)
      at com.cloudbees.groovy.cps.CpsTransformer.makeChildren(CpsTransformer.java:435)
      at com.cloudbees.groovy.cps.CpsTransformer.makeNode(CpsTransformer.java:398)
      at com.cloudbees.groovy.cps.CpsTransformer.visitWithSafepoint(CpsTransformer.java:363)
      at com.cloudbees.groovy.cps.CpsTransformer.visitMethod(CpsTransformer.java:222)
      at com.cloudbees.groovy.cps.CpsTransformer.call(CpsTransformer.java:132)
      at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1065)
      at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
      at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
      at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
      at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:254)
      at groovy.lang.GroovyClassLoader.recompile(GroovyClassLoader.java:761)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:718)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$TimingLoader.loadClass(CpsGroovyShell.java:158)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:545)
      at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:185)
      at org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:170)
      at org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:126)
      at org.codehaus.groovy.control.ResolveVisitor.resolveToOuter(ResolveVisitor.java:676)
      at org.codehaus.groovy.control.ResolveVisitor.resolve(ResolveVisitor.java:313)
      at org.codehaus.groovy.control.ResolveVisitor.visitClass(ResolveVisitor.java:1236)
      at org.codehaus.groovy.control.ResolveVisitor.startResolving(ResolveVisitor.java:176)
      at org.codehaus.groovy.control.CompilationUnit$12.call(CompilationUnit.java:663)
      at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:943)
      at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605)
      at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:554)
      at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
      at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
      at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
      at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:131)
      at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:125)
      at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:560)
      at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:521)
      at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:330)
      at hudson.model.ResourceController.execute(ResourceController.java:97)
      at hudson.model.Executor.run(Executor.java:429)

      1 error

      at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
      at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
      at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
      at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
      at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
      at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:254)
      at groovy.lang.GroovyClassLoader.recompile(GroovyClassLoader.java:761)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:718)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$TimingLoader.loadClass(CpsGroovyShell.java:158)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677)
      at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:545)
      at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:185)
      Caused: BUG! exception in phase 'semantic analysis' in source unit 'WorkflowScript' The lookup for foo.Foo caused a failed compilaton. There should not have been any compilation from this call.
      at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:190)
      at org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:170)
      at org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:126)
      at org.codehaus.groovy.control.ResolveVisitor.resolveToOuter(ResolveVisitor.java:676)
      at org.codehaus.groovy.control.ResolveVisitor.resolve(ResolveVisitor.java:313)
      at org.codehaus.groovy.control.ResolveVisitor.visitClass(ResolveVisitor.java:1236)
      at org.codehaus.groovy.control.ResolveVisitor.startResolving(ResolveVisitor.java:176)
      at org.codehaus.groovy.control.CompilationUnit$12.call(CompilationUnit.java:663)
      at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:943)
      at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605)
      at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:554)
      at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
      at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
      at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
      at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:131)
      at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:125)
      at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:560)
      at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:521)
      at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:330)
      at hudson.model.ResourceController.execute(ResourceController.java:97)
      at hudson.model.Executor.run(Executor.java:429)
      Finished: FAILURE

        Attachments

          Activity

          Hide
          missedone nick tan added a comment -

          I met the similar issue, 

          by surrounding the map literal with parentheses, i can bypass the issue:
          customEcho ([message: "Hello from Foo!"])

          Show
          missedone nick tan added a comment - I met the similar issue,  by surrounding the map literal with parentheses, i can bypass the issue: customEcho ( [message: "Hello from Foo!"] )

            People

            • Assignee:
              Unassigned
              Reporter:
              kulladam86 Adam Kullberg
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: