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

Labels in implicitly returned closures cause a NullPointerException during Groovy compilation

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • workflow-cps-plugin
    • None
    • core:2.401.2

      When using a labeled block and a break statement like the following:

      pipeline {
          agent any
          stages {
              stage('Main') {
                  steps {
                      script {
                          echo "OK"
                          outerloop:
                      		for (int i = 0; i < 2; i++) {
                      		  if (i > 0) {
                      		      echo "${i}"
                      		  } else {
                      		      break outerloop
                      		  }
                      		}
                      }
                  }
              }
          }
      }
      

      it fails with the following:

      java.lang.NullPointerException
      	at org.codehaus.groovy.control.LabelVerifier.visitBreakStatement(LabelVerifier.java:126)
      	at org.codehaus.groovy.ast.stmt.BreakStatement.visit(BreakStatement.java:46)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
      	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitIfElse(CodeVisitorSupport.java:117)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitIfElse(ClassCodeVisitorSupport.java:206)
      	at org.codehaus.groovy.ast.stmt.IfStatement.visit(IfStatement.java:43)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
      	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitForLoop(CodeVisitorSupport.java:94)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitForLoop(ClassCodeVisitorSupport.java:201)
      	at org.codehaus.groovy.control.LabelVerifier.visitForLoop(LabelVerifier.java:97)
      	at org.codehaus.groovy.ast.stmt.ForStatement.visit(ForStatement.java:49)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
      	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitClosureExpression(CodeVisitorSupport.java:227)
      	at org.codehaus.groovy.ast.expr.ClosureExpression.visit(ClosureExpression.java:49)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:231)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:336)
      	at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitMethodCallExpression(CodeVisitorSupport.java:184)
      	at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:70)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:122)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:196)
      	at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:42)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
      	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitClosureExpression(CodeVisitorSupport.java:227)
      	at org.codehaus.groovy.ast.expr.ClosureExpression.visit(ClosureExpression.java:49)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:231)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:336)
      	at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitStaticMethodCallExpression(CodeVisitorSupport.java:188)
      	at org.codehaus.groovy.ast.expr.StaticMethodCallExpression.visit(StaticMethodCallExpression.java:45)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:231)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:336)
      	at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitConstructorCallExpression(CodeVisitorSupport.java:192)
      	at org.codehaus.groovy.ast.expr.ConstructorCallExpression.visit(ConstructorCallExpression.java:46)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListExpression(CodeVisitorSupport.java:235)
      	at org.codehaus.groovy.ast.expr.ListExpression.visit(ListExpression.java:64)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:231)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:336)
      	at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitConstructorCallExpression(CodeVisitorSupport.java:192)
      	at org.codehaus.groovy.ast.expr.ConstructorCallExpression.visit(ConstructorCallExpression.java:46)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:231)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:336)
      	at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitConstructorCallExpression(CodeVisitorSupport.java:192)
      	at org.codehaus.groovy.ast.expr.ConstructorCallExpression.visit(ConstructorCallExpression.java:46)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitReturnStatement(CodeVisitorSupport.java:126)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitReturnStatement(ClassCodeVisitorSupport.java:211)
      	at org.codehaus.groovy.ast.stmt.ReturnStatement.visit(ReturnStatement.java:49)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
      	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitClosureExpression(CodeVisitorSupport.java:227)
      	at org.codehaus.groovy.ast.expr.ClosureExpression.visit(ClosureExpression.java:49)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:326)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:231)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:336)
      	at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitMethodCallExpression(CodeVisitorSupport.java:184)
      	at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:70)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:122)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:196)
      	at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:42)
      	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
      	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:104)
      	at org.codehaus.groovy.control.LabelVerifier.visitClassCodeContainer(LabelVerifier.java:66)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:115)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:126)
      	at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1081)
      	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:53)
      	at com.cloudbees.groovy.cps.CpsTransformer.call(CpsTransformer.java:130)
      	at com.cloudbees.groovy.cps.SandboxCpsTransformer.call(SandboxCpsTransformer.java:26)
      	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1087)
      Caused: BUG! exception in phase 'canonicalization' in source unit 'WorkflowScript' unexpected NullpointerException
      	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1092)
      	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:624)
      	at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:602)
      	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:579)
      	at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:323)
      	at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:293)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox$Scope.parse(GroovySandbox.java:163)
      	at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:190)
      	at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:175)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:568)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:518)
      	at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:336)
      	at hudson.model.ResourceController.execute(ResourceController.java:101)
      	at hudson.model.Executor.run(Executor.java:442)
      

      ****

      However this works in scripted pipeline or if extracted in a function:

      def test() {
          outerloop:
          for (int i = 0; i < 2; i++) {
              if (i > 0) {
                  echo "${i}"
              } else {
                  break outerloop
              }
          }
      }
      
      pipeline {
          agent any
          stages {
              stage('Main') {
                  steps {
                      script {
                          echo "OK"
                          test()
                          
                      }
                  }
              }
          }
      }
      

          [JENKINS-71617] Labels in implicitly returned closures cause a NullPointerException during Groovy compilation

          Worked with workflow-cps 2803.v1a_f77ffcc773 and fail when upgrading to 3520.va_8fc49e2f96f.

          Allan BURDAJEWICZ added a comment - Worked with workflow-cps 2803.v1a_f77ffcc773 and fail when upgrading to 3520.va_8fc49e2f96f .

          Jesse Glick added a comment -

          dnusbaum sound familiar? Probably the consequence of some security update or another, which the reporter could determine via bisection.

          Obviously the “workaround” is to not include scripts in Declarative Pipeline to begin with.

          Jesse Glick added a comment - dnusbaum sound familiar? Probably the consequence of some security update or another, which the reporter could determine via bisection. Obviously the “workaround” is to not include scripts in Declarative Pipeline to begin with.

          Devin Nusbaum added a comment -

          Does not ring a bell. 2803.v1a_f77ffcc773 already includes SECURITY-2824. 3520.va_8fc49e2f96f was the next release (big number bump because of https://github.com/jenkinsci/workflow-cps-plugin/pull/612, and the only CPS-related behavioral change in that release should be JENKINS-62064, but it is not obvious to me how that might affect this issue.

          So IDK why it would have been working in 2803.v1a_f77ffcc773. That said, this fails in regular Groovy, so I think the problem has to do with any labels inside of closures and is likely to not be specifically related to Pipeline. I will try to see if it has been reported/fixed upstream

          dnusbaum@MAC-dnusbaum % groovy -v
          [...]
          Groovy Version: 2.4.21 JVM: 11.0.17 Vendor: Azul Systems, Inc. OS: Mac OS X
          dnusbaum@MAC-dnusbaum % groovy -d -e "def cl = { ->
            def i = 0
            label:
            for (; i < 10; i++) {
              if (i > 2) {
                break label
              }
            }
            i
          }()"
          [...]
          Caught: BUG! exception in phase 'class generation' in source unit 'script_from_command_line' unexpected NullpointerException
          BUG! exception in phase 'class generation' in source unit 'script_from_command_line' unexpected NullpointerException
          	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1092)
          	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:624)
          	at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:602)
          	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:579)
          	at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:323)
          	at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:293)
          	at groovy.lang.GroovyShell.parseClass(GroovyShell.java:677)
          	at groovy.lang.GroovyShell.run(GroovyShell.java:506)
          	at groovy.lang.GroovyShell.run(GroovyShell.java:496)
          	at groovy.ui.GroovyMain.processOnce(GroovyMain.java:597)
          	at groovy.ui.GroovyMain.run(GroovyMain.java:329)
          	at groovy.ui.GroovyMain.process(GroovyMain.java:315)
          	at groovy.ui.GroovyMain.processArgs(GroovyMain.java:134)
          	at groovy.ui.GroovyMain.main(GroovyMain.java:114)
          	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
          	at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:116)
          	at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:138)
          Caused by: java.lang.NullPointerException
          	at org.codehaus.groovy.control.LabelVerifier.visitBreakStatement(LabelVerifier.java:126)
          	at org.codehaus.groovy.ast.stmt.BreakStatement.visit(BreakStatement.java:46)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
          	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitIfElse(CodeVisitorSupport.java:109)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitIfElse(ClassCodeVisitorSupport.java:206)
          	at org.codehaus.groovy.ast.stmt.IfStatement.visit(IfStatement.java:43)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
          	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitForLoop(CodeVisitorSupport.java:94)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitForLoop(ClassCodeVisitorSupport.java:201)
          	at org.codehaus.groovy.control.LabelVerifier.visitForLoop(LabelVerifier.java:97)
          	at org.codehaus.groovy.ast.stmt.ForStatement.visit(ForStatement.java:49)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
          	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitClosureExpression(CodeVisitorSupport.java:227)
          	at org.codehaus.groovy.ast.expr.ClosureExpression.visit(ClosureExpression.java:49)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitMethodCallExpression(CodeVisitorSupport.java:182)
          	at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:70)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBinaryExpression(CodeVisitorSupport.java:197)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitDeclarationExpression(CodeVisitorSupport.java:298)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitDeclarationExpression(ClassCodeVisitorSupport.java:110)
          	at org.codehaus.groovy.ast.expr.DeclarationExpression.visit(DeclarationExpression.java:89)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitReturnStatement(CodeVisitorSupport.java:126)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitReturnStatement(ClassCodeVisitorSupport.java:211)
          	at org.codehaus.groovy.ast.stmt.ReturnStatement.visit(ReturnStatement.java:49)
          	at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
          	at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:104)
          	at org.codehaus.groovy.control.LabelVerifier.visitClassCodeContainer(LabelVerifier.java:66)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:115)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:126)
          	at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1081)
          	at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:53)
          	at org.codehaus.groovy.control.CompilationUnit$17.call(CompilationUnit.java:819)
          	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1087)
          	... 19 more
          

          Devin Nusbaum added a comment - Does not ring a bell. 2803.v1a_f77ffcc773 already includes SECURITY-2824. 3520.va_8fc49e2f96f was the next release (big number bump because of https://github.com/jenkinsci/workflow-cps-plugin/pull/612 , and the only CPS-related behavioral change in that release should be JENKINS-62064 , but it is not obvious to me how that might affect this issue. So IDK why it would have been working in 2803.v1a_f77ffcc773. That said, this fails in regular Groovy, so I think the problem has to do with any labels inside of closures and is likely to not be specifically related to Pipeline. I will try to see if it has been reported/fixed upstream dnusbaum@MAC-dnusbaum % groovy -v [...] Groovy Version: 2.4.21 JVM: 11.0.17 Vendor: Azul Systems, Inc. OS: Mac OS X dnusbaum@MAC-dnusbaum % groovy -d -e "def cl = { -> def i = 0 label: for (; i < 10; i++) { if (i > 2) { break label } } i }()" [...] Caught: BUG! exception in phase 'class generation' in source unit 'script_from_command_line' unexpected NullpointerException BUG! exception in phase 'class generation' in source unit 'script_from_command_line' unexpected NullpointerException at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1092) at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:624) at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:602) at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:579) at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:323) at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:293) at groovy.lang.GroovyShell.parseClass(GroovyShell.java:677) at groovy.lang.GroovyShell.run(GroovyShell.java:506) at groovy.lang.GroovyShell.run(GroovyShell.java:496) at groovy.ui.GroovyMain.processOnce(GroovyMain.java:597) at groovy.ui.GroovyMain.run(GroovyMain.java:329) at groovy.ui.GroovyMain.process(GroovyMain.java:315) at groovy.ui.GroovyMain.processArgs(GroovyMain.java:134) at groovy.ui.GroovyMain.main(GroovyMain.java:114) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:116) at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:138) Caused by: java.lang.NullPointerException at org.codehaus.groovy.control.LabelVerifier.visitBreakStatement(LabelVerifier.java:126) at org.codehaus.groovy.ast.stmt.BreakStatement.visit(BreakStatement.java:46) at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166) at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71) at org.codehaus.groovy.ast.CodeVisitorSupport.visitIfElse(CodeVisitorSupport.java:109) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitIfElse(ClassCodeVisitorSupport.java:206) at org.codehaus.groovy.ast.stmt.IfStatement.visit(IfStatement.java:43) at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166) at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71) at org.codehaus.groovy.ast.CodeVisitorSupport.visitForLoop(CodeVisitorSupport.java:94) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitForLoop(ClassCodeVisitorSupport.java:201) at org.codehaus.groovy.control.LabelVerifier.visitForLoop(LabelVerifier.java:97) at org.codehaus.groovy.ast.stmt.ForStatement.visit(ForStatement.java:49) at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166) at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71) at org.codehaus.groovy.ast.CodeVisitorSupport.visitClosureExpression(CodeVisitorSupport.java:227) at org.codehaus.groovy.ast.expr.ClosureExpression.visit(ClosureExpression.java:49) at org.codehaus.groovy.ast.CodeVisitorSupport.visitMethodCallExpression(CodeVisitorSupport.java:182) at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:70) at org.codehaus.groovy.ast.CodeVisitorSupport.visitBinaryExpression(CodeVisitorSupport.java:197) at org.codehaus.groovy.ast.CodeVisitorSupport.visitDeclarationExpression(CodeVisitorSupport.java:298) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitDeclarationExpression(ClassCodeVisitorSupport.java:110) at org.codehaus.groovy.ast.expr.DeclarationExpression.visit(DeclarationExpression.java:89) at org.codehaus.groovy.ast.CodeVisitorSupport.visitReturnStatement(CodeVisitorSupport.java:126) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitReturnStatement(ClassCodeVisitorSupport.java:211) at org.codehaus.groovy.ast.stmt.ReturnStatement.visit(ReturnStatement.java:49) at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:88) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166) at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:104) at org.codehaus.groovy.control.LabelVerifier.visitClassCodeContainer(LabelVerifier.java:66) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:115) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:126) at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1081) at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:53) at org.codehaus.groovy.control.CompilationUnit$17.call(CompilationUnit.java:819) at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1087) ... 19 more

          Devin Nusbaum added a comment -

          I did not find this exact issue reported upstream. GROOVY-7463 has the same stack trace in its description, but against Groovy 2.4.3, and the reporter seems to not have been able to reproduce the compiler error in that case.

          I think the issue surfaced in https://github.com/apache/groovy/commit/12600a9b9c3db92383bbfef166d727e28702bd86. Note the changes to LabelVerifier in that commit, particularly how the method no longer checks for nullability of the individual labels, only the overall list. From some quick debugging, I think the root cause though is this combined with the lack of a null check in Statement.setStatementLabel, which adds a null label to statementLabels for all return statements with no label. This happens whenever you have an implicit return (explicit returns use the other constructor which avoids the bug) of an expression with a label inside of it, basically anytime you implicitly return a closure with a label inside of it.

          These "minor edits" in Groovy 4.x fixed the root cause. That commit was also backported to Groovy 3.x (see here; I am not sure why GitHub does identify the tags that contain that commit correctly), and I verified that my reproducer does not fail in Groovy 3.0.9.

          We could probably hack up a workaround in groovy-cps and groovy-sandbox to remove null labels from all statements, or at least return statements, since we visit them all anyway, but it would be messy.

          Devin Nusbaum added a comment - I did not find this exact issue reported upstream. GROOVY-7463  has the same stack trace in its description, but against Groovy 2.4.3, and the reporter seems to not have been able to reproduce the compiler error in that case. I think the issue surfaced in https://github.com/apache/groovy/commit/12600a9b9c3db92383bbfef166d727e28702bd86 . Note the changes to LabelVerifier in that commit, particularly how the method no longer checks for nullability of the individual labels, only the overall list. From some quick debugging, I think the root cause though is this combined with the lack of a null check in Statement.setStatementLabel , which adds a null label to statementLabels for all return statements with no label. This happens whenever you have an implicit return (explicit returns use the other constructor which avoids the bug) of an expression with a label inside of it, basically anytime you implicitly return a closure with a label inside of it. These "minor edits" in Groovy 4.x fixed the root cause. That commit was also backported to Groovy 3.x ( see here ; I am not sure why GitHub does identify the tags that contain that commit correctly), and I verified that my reproducer does not fail in Groovy 3.0.9. We could probably hack up a workaround in groovy-cps and groovy-sandbox to remove null labels from all statements, or at least return statements, since we visit them all anyway, but it would be messy.

            Unassigned Unassigned
            allan_burdajewicz Allan BURDAJEWICZ
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: