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

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during class generation: Method code too large! error in pipeline Script

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Blocker Blocker
    • workflow-cps-plugin
    • None

      Note from the Maintainers

      There is partial fix for this for Declarative pipelines in pipeline-model-definition-plugin v1.4.0 and later, significantly improved in v1.8.4.  Due to the extent to which it change how pipelines are executed it is turned off by default.  It can be turned on by setting a JVM property (either on the command-line or in Jenkins script console):

      org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.SCRIPT_SPLITTING_TRANSFORMATION=true 

      As noted, this still works best with a Jenkinsfile with pipeline directive as the only root item in the file.
      Since v1.8.2 this workaround reports an informative error for pipelines using `def` variables before the pipeline directive. Add a @Field annotation to those declaration.
      This workaround generally does NOT work if the pipeline directive inside a shared library method. If this is a scenario you want, please come join the pipeline authoring SIG and we can discuss.

      Please give it a try and provide feedback. 

      Hi,

      We are getting below error in Pipeline which has some 495 lines of groovy code. Initially we assumed that one of our methods has an issue but once we remove any 30-40 lines of Pipeline groovy, this issue is not coming.

      Can you please suggest a quick workaround. It's a blocker for us.

      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
      General error during class generation: Method code too large!
      
      java.lang.RuntimeException: Method code too large!
      	at groovyjarjarasm.asm.MethodWriter.a(Unknown Source)
      	at groovyjarjarasm.asm.ClassWriter.toByteArray(Unknown Source)
      	at org.codehaus.groovy.control.CompilationUnit$16.call(CompilationUnit.java:815)
      	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1053)
      	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:591)
      	at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:569)
      	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:546)
      	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.reparse(CpsGroovyShell.java:67)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:410)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:373)
      	at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:213)
      	at hudson.model.ResourceController.execute(ResourceController.java:98)
      	at hudson.model.Executor.run(Executor.java:410)
      
      1 error
      
      	at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
      	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1073)
      	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:591)
      	at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:569)
      	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:546)
      	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.reparse(CpsGroovyShell.java:67)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:410)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:373)
      	at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:213)
      	at hudson.model.ResourceController.execute(ResourceController.java:98)
      	at hudson.model.Executor.run(Executor.java:410)
      Finished: FAILURE
      

        1. errorIncomaptiblewithlocalvar.txt
          8 kB
        2. java.png
          java.png
          294 kB
        3. JenkinsCodeTooLarge.groovy
          45 kB
        4. Script_Splitting.groovy
          44 kB
        5. Script_Splittingx10.groovy
          519 kB

          [JENKINS-37984] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during class generation: Method code too large! error in pipeline Script

          Anudeep Lalam created issue -

          Pete McNab added a comment - - edited

          I've run into the same problem. I have a large (200+kb) pipeline script that is generated from our legacy build specification language.

          My generated code is broken up into stages, with each stage running a potentially large parallel pipeline operation, where each platform of a given target is built.

          After some googling about the underlying cause, I attempted to break it up by having each stage be defined as a method and calling the method rather than just having all the code in one giant block, but it didn't help.

          As this will impact a lot of people trying to migrate to the Jenkins pipeline, and may make them throw up their hands due to the error being vague and unhelpful (which I realize is not the fault of Jenkins, but the underlying Java/Groovy architecture), it might be good to have some specific guides on how to deal with this.

          Pete McNab added a comment - - edited I've run into the same problem. I have a large (200+kb) pipeline script that is generated from our legacy build specification language. My generated code is broken up into stages, with each stage running a potentially large parallel pipeline operation, where each platform of a given target is built. After some googling about the underlying cause, I attempted to break it up by having each stage be defined as a method and calling the method rather than just having all the code in one giant block, but it didn't help. As this will impact a lot of people trying to migrate to the Jenkins pipeline, and may make them throw up their hands due to the error being vague and unhelpful (which I realize is not the fault of Jenkins, but the underlying Java/Groovy architecture), it might be good to have some specific guides on how to deal with this.

          Jesse Glick added a comment -

          Surprised that breaking it up into separate methods did not help. Other than that, I have no suggestions offhand.

          Jesse Glick added a comment - Surprised that breaking it up into separate methods did not help. Other than that, I have no suggestions offhand.
          Jesse Glick made changes -
          Epic Link New: JENKINS-35390 [ 171183 ]
          Jesse Glick made changes -
          Component/s New: workflow-cps-plugin [ 21713 ]
          Component/s Original: pipeline [ 21692 ]
          Assignee Original: Jesse Glick [ jglick ]

          Pete McNab added a comment -

          Yeah it's kind of puzzling – as part of my testing I had reduced the number of stages significantly.

          So a version that worked had 4 stages with no methods and it was about 1720 lines.

          With the full set of stages (27), the number of lines is about 5300 lines. Breaking it up into methods had no method larger than about 450 lines, but it wouldn't run.

          I also went in and removed the 4 stages that had worked, which put the entire script down to ~3600 lines broken out into methods, and that wouldn't run either.

          Pete McNab added a comment - Yeah it's kind of puzzling – as part of my testing I had reduced the number of stages significantly. So a version that worked had 4 stages with no methods and it was about 1720 lines. With the full set of stages (27), the number of lines is about 5300 lines. Breaking it up into methods had no method larger than about 450 lines, but it wouldn't run. I also went in and removed the 4 stages that had worked, which put the entire script down to ~3600 lines broken out into methods, and that wouldn't run either.

          Pete McNab added a comment - - edited

          Whoops. Well cancel what I said. When I generated the code with what I intended to be methods I was actually defining closures attached to a variable. When I did it properly as methods it's ok with it.

          So more specifically, for those of you who find this, what I used to have was:

          stage foo
          parallel([
           ... giant list of maps ...
          ])
          

          What I changed it to was:

          stage foo
          def build_foo() {
            parallel([
               ...giant list of maps...
            ])}
          build_foo()
          

          Pete McNab added a comment - - edited Whoops. Well cancel what I said. When I generated the code with what I intended to be methods I was actually defining closures attached to a variable. When I did it properly as methods it's ok with it. So more specifically, for those of you who find this, what I used to have was: stage foo parallel([ ... giant list of maps ... ]) What I changed it to was: stage foo def build_foo() { parallel([ ...giant list of maps... ])} build_foo()

          Jesse Glick added a comment -

          Sounds like a good candidate for a self-answer.

          Jesse Glick added a comment - Sounds like a good candidate for a self-answer .

          Pete McNab added a comment -

          I made one – I still think this case should be touched on in the Pipeline docs. I don't think searching Jira or StackOverflow is a substitute for documentation

          Pete McNab added a comment - I made one – I still think this case should be touched on in the Pipeline docs. I don't think searching Jira or StackOverflow is a substitute for documentation

          Jesse Glick added a comment -

          Sure, that is why this is still open.

          Jesse Glick added a comment - Sure, that is why this is still open.
          Jesse Glick made changes -
          Priority Original: Blocker [ 1 ] New: Major [ 3 ]

            Unassigned Unassigned
            anudeeplalam Anudeep Lalam
            Votes:
            87 Vote for this issue
            Watchers:
            103 Start watching this issue

              Created:
              Updated: