There is partial fix for this in pipeline-model-definition-plugin v1.4.0 and later, significantly improved in v1.8.2.  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.  

      When working with a declarative pipeline script, we run into an error "Method Code too large".

      This seems to happen when the code between 'pipeline{}' is more than a specific size. 

       

      I'm creating this issue for this component following the suggestion of Jesse Glick at the issue 37984

      I've attached a declarative pipeline script that reproduces the issue. 

       

       

          [JENKINS-56500] Declarative pipeline restricted in code size

          Allan added a comment - - edited

          I am running into this problem with one of the declarative pipeline jobs which has a single root element. I have added the property org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.SCRIPT_SPLITTING_TRANSFORMATION=true as the JVM startup parameter and rerun the job after restarting the webapp. I'm still getting MethodTooLargeException unfortunately.

          Initial intuition led me to believe the build.xml file in the Jenkins job folder for this job will be different because of the new parameter. I checked the build.xml file but file is the same as the previous build which doesn't have the SCRIPT_SPLITTING_TRANSFORMATION parameter configured.

          I can confirm the parameter is indeed passed into the JVM when starting Jenkins. Is there a way I can verify the job is now doing "splitting transformation"?

           

          EDIT: On second look, the actual exception is 

          General error during class generation: Method too large: WorkflowScript.___cps___2 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction;
          
          groovyjarjarasm.asm.MethodTooLargeException: Method too large: WorkflowScript.___cps___2 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction;
          ... more stacktrace here after ...

          Perhaps not exactly the same issue.

          Allan added a comment - - edited I am running into this problem with one of the declarative pipeline jobs which has a single root element. I have added the property org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.SCRIPT_SPLITTING_TRANSFORMATION=true as the JVM startup parameter and rerun the job after restarting the webapp. I'm still getting  MethodTooLargeException unfortunately. Initial intuition led me to believe the build.xml file in the Jenkins job folder for this job will be different because of the new parameter. I checked the build.xml file but file is the same as the previous build which doesn't have the SCRIPT_SPLITTING_TRANSFORMATION parameter configured. I can confirm the parameter is indeed passed into the JVM when starting Jenkins. Is there a way I can verify the job is now doing "splitting transformation"?   EDIT : On second look, the actual exception is  General error during class generation: Method too large: WorkflowScript.___cps___2 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction; groovyjarjarasm.asm.MethodTooLargeException: Method too large: WorkflowScript.___cps___2 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction; ... more stacktrace here after ... Perhaps not exactly the same issue.

          Marko added a comment - - edited

          Is it a given that I'm going to get this error when I convert my scripted pipeline to a declarative one if I have around 800 lines of code within the `pipeline` root element or it only happens under certain additional conditions?

          If the bug is a given then I'm thinking I should postpone this conversion task and stick with the scripted pipeline (as much as I hate not being able to restart from a stage) until this gets fixed.

          And if the bug happens to everyone, I'm also wondering why hasn't this been resolved, given that it was opened in 2019?

          Marko added a comment - - edited Is it a given that I'm going to get this error when I convert my scripted pipeline to a declarative one if I have around 800 lines of code within the `pipeline` root element or it only happens under certain additional conditions? If the bug is a given then I'm thinking I should postpone this conversion task and stick with the scripted pipeline (as much as I hate not being able to restart from a stage) until this gets fixed. And if the bug happens to everyone, I'm also wondering why hasn't this been resolved, given that it was opened in 2019?

          Marko added a comment -

          OK, I'm reporting back my experience converting a scripted pipeline (900 LoC) into a declarative one (1k LoC).

          First, let me just say that I love the neat structure and the whole experience of working with declarative pipelines. The conversion felt like tidying up.

          I hit the issue when I added the last two stages.

          org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
          General error during class generation: Method too large: WorkflowScript.__cps__9839 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction;

          But after adding  

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

           to my Manage Jenkins > Script Console (just paste the snippet above and click `Run` and then start a new build)
          the issue went away.

          Just for the sake of completeness, I also had to add the same setting to `javaOpts` in my Jenkins' helm chart (I'm using k8s + JCasC), so I don't have to manually set it in the Script Console on all newly installed Jenkins instances:

          javaOpts: "...other options -Dorg.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.SCRIPT_SPLITTING_TRANSFORMATION=true"

           

          Marko added a comment - OK, I'm reporting back my experience converting a scripted pipeline (900 LoC) into a declarative one (1k LoC). First, let me just say that I love the neat structure and the whole experience of working with declarative pipelines. The conversion felt like tidying up. I hit the issue when I added the last two stages. org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during class generation: Method too large: WorkflowScript.__cps__9839 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction; But after adding   org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.SCRIPT_SPLITTING_TRANSFORMATION= true  to my Manage Jenkins > Script Console (just paste the snippet above and click `Run` and then start a new build) the issue went away. Just for the sake of completeness, I also had to add the same setting to `javaOpts` in my Jenkins' helm chart (I'm using k8s + JCasC), so I don't have to manually set it in the Script Console on all newly installed Jenkins instances: javaOpts: "...other options -Dorg.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.SCRIPT_SPLITTING_TRANSFORMATION= true "  

          Allan added a comment -

          Hi mbost. I am still unable to get it to work even though I ran the script in Script Console. Adding "-vmargs" before the JVM parameter renders Jenkins service not startable at all.

          Just curious, my project type is a multibranch pipeline project. Is yours a multibranch pipeline project as well? Perhaps if yours is not, that might explain why it is not working for me.

          Allan added a comment - Hi mbost . I am still unable to get it to work even though I ran the script in Script Console . Adding "-vmargs" before the JVM parameter renders Jenkins service not startable at all. Just curious, my project type is a multibranch pipeline project. Is yours a multibranch pipeline project as well? Perhaps if yours is not, that might explain why it is not working for me.

          Marko added a comment -

          Hi allancth.

          No, it's not that, I'm also using a Multibranch pipeline project.

          The next thing I would've had to try, had it not worked, would've been to extract some pieces into a shared library, as much as I despise the complexity of it (it having to be a whole new repo, not a file in my current project), so you might try the same.

          Marko added a comment - Hi allancth . No, it's not that, I'm also using a Multibranch pipeline project. The next thing I would've had to try, had it not worked, would've been to extract some pieces into a shared library, as much as I despise the complexity of it (it having to be a whole new repo, not a file in my current project), so you might try the same.

          Allan added a comment -

          Thanks mbost for the response.

          The workaround I have now is to split the MethodTooLarge Jenkinsfile into several separate jobs. Actually I think for scalability I need to model the build jobs to the individual modules but that's too much to handle right now.

          I will try to get the some of the pieces into a shared library but for a quick workaround I can also move some into a shell script. I need to find out the benefits of putting some parts of the workflow into a shared library - what can be done in the shared library that a shell script can't.

          Allan added a comment - Thanks mbost for the response. The workaround I have now is to split the MethodTooLarge Jenkinsfile into several separate jobs. Actually I think for scalability I need to model the build jobs to the individual modules but that's too much to handle right now. I will try to get the some of the pieces into a shared library but for a quick workaround I can also move some into a shell script. I need to find out the benefits of putting some parts of the workflow into a shared library - what can be done in the shared library that a shell script can't.

          Cristian added a comment -

          SCRIPT_SPLITTING_TRANSFORMATION helps, but it seems to me that there is additionally a specific problem with the matrix step. For the second time, I have been able to solve the issue in one of my projects by changing a matrix step into a script step using the parallel step.

           

          We build for tens of platforms, so it arguably an unusually big matrix. But there is only one axis, and it's tens of targets, not hundreds. The code inside the matrix doesn't even need to be specially complicated, it's mainly the amount of parallel branches that triggers the issue for us.

          Cristian added a comment - SCRIPT_SPLITTING_TRANSFORMATION helps, but it seems to me that there is additionally a specific problem with the matrix step. For the second time, I have been able to solve the issue in one of my projects by changing a matrix step into a script step using the parallel step.   We build for tens of platforms, so it arguably an unusually big matrix. But there is only one axis, and it's tens of targets, not hundreds. The code inside the matrix doesn't even need to be specially complicated, it's mainly the amount of parallel branches that triggers the issue for us.

          efo plo added a comment - - edited

          FYI, we worked around this issue long ago by adding a scripted step inside a declarative pipeline.
          This looks like this:

                  stage('Testing') {
                      steps {
                          script {
                              def testers = getParallelTesters() // returns *hundreds* of parallel stages
                              parallel testers
                          }
                      }
                      post {
                          // ...
                      }
                  }
          

          where

          def getParallelTesters() {
              def testers = [:].asSynchronized()
              testers["Test 1"] = { return test1() } 
              // ....
              testers["Test 999"] = { return test999() }
              return testers
          }
          

          where smaller functions return a closure wrapping stage and node as needed.

          This gives us the same huge pipeline while limiting the size of declarative pipeline to a minimum.

          efo plo added a comment - - edited FYI, we worked around this issue long ago by adding a scripted step inside a declarative pipeline. This looks like this: stage( 'Testing' ) { steps { script { def testers = getParallelTesters() // returns *hundreds* of parallel stages parallel testers } } post { // ... } } where def getParallelTesters() { def testers = [:].asSynchronized() testers[ "Test 1" ] = { return test1() } // .... testers[ "Test 999" ] = { return test999() } return testers } where smaller functions return a closure wrapping stage and node as needed. This gives us the same huge pipeline while limiting the size of declarative pipeline to a minimum.

          Cristian added a comment -

          Yes, I did the same.

          But that looks like the obvious way a matrix step would be implemented, no? Which raises the question of why the matrix step generates a "Method too large" to start with.

          Cristian added a comment - Yes, I did the same. But that looks like the obvious way a matrix step would be implemented, no? Which raises the question of why the matrix step generates a "Method too large" to start with.

          Aleksandr added a comment -

          Good day, colleagues!

          We have the same issue, and I could confirm that it is related to the number of values in the matrix. 
          Currently we have the next one

                          axes {
                              axis { 
                                  name    'geo' 
                                  values  'pl', 'ee', 'lt', 'lv', 'sa', 'ua', 'bg', 'ro', 'hr', 'gr', 'cy', 'rs', 'kz', 'si', 'ba', 'hu'
                              }
                          } 

           But when we try to add one more value we are getting the next error:

          org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
          General error during class generation: Method too large: WorkflowScript.___cps___156545 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction;
          
          groovyjarjarasm.asm.MethodTooLargeException: Method too large: WorkflowScript.___cps___156545 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction;
          	at groovyjarjarasm.asm.MethodWriter.computeMethodInfoSize(MethodWriter.java:2087)
          	at groovyjarjarasm.asm.ClassWriter.toByteArray(ClassWriter.java:447)
          	at org.codehaus.groovy.control.CompilationUnit$17.call(CompilationUnit.java:850)
          	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1087)
          	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)
          
          1 error
          
          	at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
          	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1107)
          	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) 

          Stages block is very simple, even few one line steps.

          Aleksandr added a comment - Good day, colleagues! We have the same issue, and I could confirm that it is related to the number of values in the matrix.  Currently we have the next one                 axes {                     axis {                          name     'geo'                           values   'pl' , 'ee' , 'lt' , 'lv' , 'sa' , 'ua' , 'bg' , 'ro' , 'hr' , 'gr' , 'cy' , 'rs' , 'kz' , 'si' , 'ba' , 'hu'                     }                 }  But when we try to add one more value we are getting the next error: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during class generation: Method too large: WorkflowScript.___cps___156545 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction; groovyjarjarasm.asm.MethodTooLargeException: Method too large: WorkflowScript.___cps___156545 ()Lcom/cloudbees/groovy/cps/impl/CpsFunction; at groovyjarjarasm.asm.MethodWriter.computeMethodInfoSize(MethodWriter.java:2087) at groovyjarjarasm.asm.ClassWriter.toByteArray(ClassWriter.java:447) at org.codehaus.groovy.control.CompilationUnit$17.call(CompilationUnit.java:850) at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1087) 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) 1 error at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309) at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1107) 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) Stages block is very simple, even few one line steps.

            Unassigned Unassigned
            wim Wim Gaethofs
            Votes:
            18 Vote for this issue
            Watchers:
            30 Start watching this issue

              Created:
              Updated: