Skip to main content
  1. Posts/

Three Ways to Solve the Jenkins Declarative Pipeline "Method code too large" Exception

·558 words·3 mins· ·
Xianpeng Shen
Author
Xianpeng Shen
Table of Contents

This is the second time I’ve encountered this problem while using Jenkins declarative pipelines. The first time I encountered this problem was in a Pipeline with about 600 lines of code, and I encountered the following error:

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 that time, I also used Jenkins Shared Libraries, but the code organization was not very good, and many steps had not yet been separated as individual methods. To solve this problem, after a refactoring, I changed the original 600+ lines of Pipeline to the current 300+ lines. Unfortunately, as I continued to add features, I encountered this problem again recently.

The reason for this problem is that Jenkins puts the entire declarative pipeline into a single method, and at a certain size, the JVM fails due to java.lang.RuntimeException: Method code too large!. It seems that I have a method exceeding 64k.

There is already a ticket for this issue on Jenkins JIRA, but it has not been resolved yet. There are currently three solutions to this problem, but they each have their own advantages and disadvantages.

Method 1: Move Steps into Methods Outside the Pipeline
#

Since mid-2017, you can declare a method at the end of the pipeline and then call it in the declarative pipeline. This allows us to achieve the same effect as shared libraries, but avoids the maintenance overhead.

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                whateverFunction()
            }
        }
    }
}

void whateverFunction() {
    sh 'ls /'
}
AdvantagesDisadvantages
No extra maintenance costIt’s unknown if this solution will always be effective
All functionality is reflected in the JenkinsfileWhen a method is used in multiple Jenkinsfiles, this method will still write a lot of repetitive code

Method 2: Migrate from Declarative to Scripted Pipeline
#

Finally, we can migrate to a scripted pipeline. With it, we have complete freedom. But this will also lose the reason why we initially decided to use declarative pipelines. With a dedicated DSL, it’s easy to understand how the pipeline works.

AdvantagesDisadvantages
No limitationsRequires significant refactoring
More prone to errors
May require more code to achieve the same functionality

Method 3: Use Shared Libraries
#

I currently use Jenkins Shared Libraries, with a shared library to execute some complex steps. Shared libraries seem to be widely used, especially in maintaining large and complex projects.

My final solution was to further reduce the code in the Pipeline. I also used the solution in Method 1, moving some steps outside the Pipeline {} block, especially those steps that are called repeatedly.

AdvantagesDisadvantages
Reduces a lot of duplicate codeAny modification will affect all references; it must be thoroughly tested before merging changes into referenced branches
Can be used in chunksDifficult to understand what a step does if unfamiliar
The generated Jenkinsfile will be easier to read

Conclusion
#

Method 1: For single-repository integration, it can be implemented quickly, and most people can get started quickly. Method 2: Scripted pipelines offer few limitations and are suitable for advanced users familiar with Java and Groovy, and those with more complex needs. Method 3: For enterprise-level projects with many repositories that require extensive integration and a desire to learn about shared libraries, this method is recommended.

Related

Resolving the "Could not read from remote repository" Issue
·597 words·3 mins
Resolving the “Could not read from remote repository” error encountered when cloning code using Git, analyzing the causes, and providing solutions.
How to Slim Down Your Git Repository
·1133 words·6 mins
How to remove unnecessary files and history from a Git repository to reduce its size, providing two methods using BFG Repo Cleaner or git filter-branch.
A Free C/C++ Static Code Analysis Tool—Cppcheck—Integrated with Jenkins
·926 words·2 mins
This article introduces the installation, usage, and integration of Cppcheck with Jenkins to improve C/C++ code quality and static analysis capabilities.
Git History Statistics Generator
·712 words·4 mins
GitStats, a Git history statistics generation tool written in Python, can generate detailed code submission statistical reports to help developers analyze project activity and contributor information.