Repository navigation
[JENKINS-37984] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during class generation: Method code too large! error in pipeline Script #1210
Description
| 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. 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
Originally reported by
anudeeplalam, imported from: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during class generation: Method code too large! error in pipeline Script
- status: Open
- priority: Blocker
- component(s): workflow-cps-plugin
- resolution: Unresolved
- votes: 89
- watchers: 111
- imported: 2025-12-07
Raw content of original issue
Note from the MaintainersThere 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

Activity
jenkins-infra-bot commentedon Sep 6, 2016
Remote link associated with this issue:
jenkins-infra-bot commentedon Oct 13, 2016
pmcnab:
Raw content of original comment:
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.
jenkins-infra-bot commentedon Oct 13, 2016
Raw content of original comment:
Surprised that breaking it up into separate methods did not help. Other than that, I have no suggestions offhand.
jenkins-infra-bot commentedon Oct 13, 2016
pmcnab:
Raw content of original 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.
jenkins-infra-bot commentedon Oct 13, 2016
pmcnab:
Raw content of original comment:
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:
What I changed it to was:
jenkins-infra-bot commentedon Oct 13, 2016
Raw content of original comment:
Sounds like a good candidate for a self-answer.
jenkins-infra-bot commentedon Oct 14, 2016
pmcnab:
Raw content of original 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
jenkins-infra-bot commentedon Oct 14, 2016
Raw content of original comment:
Sure, that is why this is still open.
jenkins-infra-bot commentedon Feb 7, 2017
phillan:
Raw content of original comment:
problem seems to be linked with the size all the script but I remarked it's linked also according number and size of stages.
A workaround consists to declare a function called in some big stages.
before :
stage ('build') {
....
if (.....) {
} else {
}
.....
}
workaround
def build() {
....
if (.....) {
} else {
}
.....
}
stage ('build') {
build()
}
jenkins-infra-bot commentedon Sep 14, 2017
Raw content of original comment:
So this is happening because of how CPS transformation works - everything's getting wrapped in a single method behind the scenes, and that's ending up being too large. The best answer we've got is to move things out into shared libraries.
jenkins-infra-bot commentedon Apr 5, 2018
Raw content of original comment:
Any workarounds? My scenario is quite specific, we threat Jenkinsfile as some sort of a JIT. No one working with it directly, it rather being generated automatically based on something else. It is essential for the debugging purposes to have a big picture perspective on how the resulting Jenkinsfile going to look like, and there is no benefits into splitting it or moving to the shared library (again this is not for humans and not made by humans).
We need a way to increase this limit.
jenkins-infra-bot commentedon Apr 5, 2018
Raw content of original comment:
i use as "work a round" a script blok, for me it was a lot of work to change it but the result was smaller code witch is always good
stages {
stage('parallel stages') {
steps {
script {
in my case i have 200-300 parallel stages
i generate the parallel stages with a single function and i execute more as 200-300 stages in parallel, this is very dynamic as this amount of stages depends on user input. So i use now script block to generate all the stages and execute the stages instead of using declarative Pipeline.
jenkins-infra-bot commentedon Apr 5, 2018
Raw content of original comment:
The thing is I actually don't want to hide this code to the library. My library already does it's thing, I have a custom DSL syntax that my library goes through and generates resulting Jenkinsfile. And I follow TDD, so I got tests, and my tests basically checking the resulting Jenkinsfile vs given my own DSL. Hiding parts of Jenkinsfile into the library going to ruin the whole idea of testing for my project. Again the Jenkinsfile for me is kind of JIT, it's not a code to being read or created by human.
jenkins-infra-bot commentedon Jul 14, 2018
thelamer:
Raw content of original comment:
I am running into this, example file:
https://pastebin.com/raw/fnKnYiMq
If I rip out some env declaration blocks like:
script{ env.CI_IMAGE = env.DEV_DOCKERHUB_IMAGE env.CI_TAGS = env.EXT_RELEASE + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA env.CI_META_TAG = env.EXT_RELEASE + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA }It will compile up and run, I already tried to move every script section out to functions, but still get Method to Large.
This is only ~800 lines and even if you compiled this text 10x over it would not be at the 64k java limit.
I am trying to understand how the workflow is interpreted that could result in this limit being hit.
jenkins-infra-bot commentedon Aug 11, 2018
slavik334:
Raw content of original comment:
+1
it is a real headache
about 800-900 lines of code
could you please enforce fixing this issue?
168 remaining items
jenkins-infra-bot commentedon Jul 15, 2025
Raw content of original comment:
Can we get a more transparant fix for when using @Library _? Maybe @Field can be implictly included into it.
Because it's such a common use case and is extensively documented, I would say that would be the best.
jenkins-infra-bot commentedon Dec 7, 2025
[Original
is_duplicated_byfrom Jira: JENKINS-50033]jenkins-infra-bot commentedon Dec 7, 2025
[Original
is_duplicated_byfrom Jira: JENKINS-72290]jenkins-infra-bot commentedon Dec 7, 2025
[Original
relates_tofrom Jira: JENKINS-56500]jenkins-infra-bot commentedon Dec 7, 2025
[Original
relates_tofrom Jira: JENKINS-64846]jenkins-infra-bot commentedon Dec 7, 2025
[Original
relates_tofrom Jira: JENKINS-61389]OmryAr commentedon Sep 17, 2026
(Edited — my original version reported that the profiler under-read method size by ~1 KB and that I couldn't explain why. I found the cause; it was my bug, not a limitation. The fix and the corrected figures are below, and the gotcha turns out to be the most useful thing here.)
A few people in this thread have asked how to see this coming rather than discover it at parse time ("From my own experience, creating new stages, adding post-stages, and options seems to have a much larger effect on getting closer to the limit than adding more steps. However, it wish I could measure it."). Here are two things that work, both read-only and both runnable from Manage Jenkins → Script Console without running the pipeline or touching an agent. Script at the bottom.
Measured on
pipeline-model-definition2.2118 andworkflow-cps3536.1. An exact verdict
Parse the script through the real
CpsGroovyShell, which is the same pathCpsFlowExecution.parseScriptuses, soMethodTooLargeExceptionreproduces exactly as it would in a build:One gotcha in reading the result: a
NullPointerExceptioninCpsScript.$initializemeans the script compiled fine. It comes fromprepareScript(), which runs only afterGroovyShell.parse()has generated the class, and it fires purely because we hand the factory a nullCpsFlowExecution. AMultipleCompilationErrorsExceptionis the real failure.2. Per-method bytecode sizes — and the trap
Recompile and read
code_lengthout of each method'sCodeattribute. Two things have to be right, and the first one cost me a wrong answer:Do not hand-build the
CompilerConfiguration. Reflect the live one out of a throwawayCpsGroovyShelland compile with that object. My first version constructed a config and applied theGroovyShellDecorators to it by hand, which looks equivalent and is not: the real config also carries aRejectASTTransformsCustomizerand a secondImportCustomizer. Extra star-imports change name resolution, which changes generated bytecode. The effect was a consistent ~1 KB under-read — enough that the profiler reported 64,397 B against the 65,535 limit for a revision the controller flatly rejects. With the live config reflected, the profiler reproduces that rejection and the numbers agree with reality.The symptom to watch for: if the verdict in §1 says a script does not compile while the profile shows headroom, your configuration is not the real one.
The declarative transform needs the right
CodeSource.GroovyShellDecoratorImplonly performs model parsing when theCompileUnit'sCodeSourcelocation is exactlyfile:/groovy/shelland theClassNodeis a script — what Jenkins produces when compiling a Jenkinsfile from a string. Pass anything else and thepipeline{}block is left untransformed, so the numbers come out far too small to mean anything; passnulland it NPEs atGroovyShellDecoratorImpl.java:54. Reusing the reflected config gets this right for free, since the decorator is already installed on it.Worked example, referred to below. A 630-line declarative pipeline that compiles — but only just:
One
___cps___method at 99.9% of the limit with 83 bytes of headroom, while every other___cps___method is under 4%. That is the shape of this issue: it is never diffuse, it is always one method. Worth stressing what 83 bytes means in practice — a single addedechowith a couple of string concatenations is enough to tip a pipeline in that state from working to not compiling, which is exactly how these failures tend to arrive looking causeless.What actually reduces the oversized method
The part I found most useful, because one plausible move does nothing at all:
pipeline{}→ shared libraryvars/*.groovypipeline{}→ top-leveldefin the same file___cps___method, own 64 KB budget)def→ shared librarySo a helper already sitting in a top-level
defis not what is costing you; only code written insidepipeline{}is. You can see this in the table: each top-leveldefcontributes its own small___cps___method (plus a stub carrying the original name), which is why they cannot be what overflows.On that same pipeline, moving the inline logic into the shared library took the big method from 65,452 B to 60,362 B (92.1%) — from 83 bytes of headroom to 5,173.
This matches the resolution the CloudBees KB article suggests, and it is also why "I broke it up into methods and it still failed" reports in this thread can be consistent with the advice — if the code stayed inside the
pipeline{}braces, splitting it into closures or stages does not move it out of the one method.Secondary ceilings worth knowing about
$createCallSiteArray_1grows with the number of distinct call sites in the file. In the table above it is the second-largest method at 55% of the limit, so it is a second wall in the same class.groovy-cpsemits one builder argument per statement in a block, so a block with more than 255 consecutive statements fails withThe max number of supported arguments is 255, but found Ninstead of the size error. I hit this while trying to build a synthetic reproducer and it sent me down the wrong path for a while.___cps___NNNNNin the error message is a JVM-global counter (JENKINS-39719 madeCpsTransformer.iotaglobally unique), so the number identifies nothing and is not comparable between builds or even between runs of this script.Script — paste into the Script Console, set
PIPELINE_SOURCE, runHappy to turn any of this into a docs PR if maintainers think it belongs somewhere more discoverable than a comment on a nine-year-old issue.