Loading...

Jenkins Declarative Pipeline throws Method Code Too Large Exception

Continuous Integration
May 2, 2019
3 minutes to read
Share this post:

I use the declarative Jenkins pipeline in my current project, but after 2 years of development we hit a barrier I wasn’t aware of. Jenkins puts the whole declarative pipeline into a single method and at a certain size the JVM fails with java.lang.RuntimeException: Method code too large!. Digging deeper it turns out that no method is allowed to exceed 64k . So I needed to find a solution for this problem.

The exact stacktrace I was presented with looked like this:

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)
	[...]

And I actually achieved it with a Jenkinsfile with roughly 1000 lines. The lines are no direct implication how large the resulting bytecode of the method will be, but it should make the point clear that this limit is not that far off in the context of a build pipeline.

There are already tickets in Jenkins’ Jira but there is no resolution on the horizon yet.

I see three solutions for the problem but all of them have their own implications:

Use Shared Libraries

I already have a shared library in place for some complicated steps that we need to perform like getting the result of our Sonarqube analyses into the matching pull request in Bitbucket, but I have a major problem with this approach.

Shared Libraries, like the name suggests, should be shared and since they need to live in a separate repository you have a significant maintenance effort for strongly coupled features that are just for your very own project. So generally I dislike using them in their current form because of the extra maintenance effort.

Also, this approach won’t scale endlessly since you can still reach the point that every stage is a one-liner, and you can’t shorten them further.

ProCon
No extra maintenance overheadUndocumented and this solution might not work anymore at some point
All functionality reflected in the JenkinsfileStill limited, especially in a pipeline with many steps

Migrate to Scripted Pipeline

As a last resort we can migrate to a scripted pipeline. With that we’ll have every freedom. But we’ll also loose the reason why we decided for the declarative pipeline in the first place. Having a dedicated DSL makes it easy to understand how the pipeline works and less error-prone in extending.

ProCon
No limitation at allMajor refactoring necessary
More error-prone
Probably more code needed to achieve the same functionality

Conclusion

Since the exception occurred while developing a completely different feature I decided to use the workaround with an extra method at the end of the file for now. But its definite that we need to have a long term solution. So unless we find another solution we’ll aim to migrate to the scripted pipeline. But by doing so we’ll need to make sure that we implement a proper life cycle for our pipeline to avoid falling into a maintenance hell.

Have you heard of Marcus' Backend Newsletter?

New ideas. Twice a week!
Top