How to Debug Jenkins Code: A Complete Guide for Core Development

To debug Jenkins code, build the WAR with Maven, launch it with JDWP remote debugging flags on port 5005, and attach your IDE to step through the hudson.* core classes.

Debugging Jenkins requires understanding its Java-based architecture packaged as a WAR file. The jenkinsci/jenkins repository contains the core automation server code, and you can debug it locally by attaching to a JVM running with remote debug options. This guide covers the complete workflow from building the source to setting breakpoints in core classes like AbstractProject.

Build the Jenkins WAR for Debugging

Start by building the WAR artifact that contains the servlet container and core model classes. The build process is Maven-driven and documented in the project's CONTRIBUTING.md (lines 24-34).

Run this command for a fast build that skips tests:

mvn -am -pl war,bom -Pquick-build clean install

This generates war/target/jenkins.war, which packages the hudson.* classes and plugin loading layer. The -Pquick-build profile significantly reduces build time while producing a debuggable artifact.

Launch Jenkins with Remote Debugging Enabled

Enable the Java Debug Wire Protocol (JDWP) by setting MAVEN_OPTS before starting Jenkins. This opens port 5005 for debugger attachment as specified in CONTRIBUTING.md (lines 39-42).

Using Maven Jetty Plugin

The recommended approach runs Jenkins in-process using the Jetty plugin defined in war/pom.xml:

export MAVEN_OPTS='-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005'
mvn -pl war jetty:run

Running the WAR Directly

Alternatively, run the built WAR with the debug flags:

java $MAVEN_OPTS -jar war/target/jenkins.war

The suspend=n parameter allows Jenkins to start immediately without waiting for a debugger connection, while address=5005 specifies the port where your IDE will attach.

Attach Your IDE to the Running JVM

Once Jenkins is running with debug flags, configure your IDE to connect to localhost:5005.

IntelliJ IDEA Configuration

Navigate to Run → Edit Configurations, click the + button, and select Remote. Keep the default host as localhost and port as 5005. Name the configuration "Jenkins Remote Debug" and apply the changes.

Note: If you encounter issues with the @{jenkins.addOpens} flag, clear the Pass to JUnit process argLine setting in your run configuration. This workaround addresses a known IntelliJ parsing bug documented in CONTRIBUTING.md (lines 11-18).

Eclipse Configuration

Go to Run → Debug Configurations, select Remote Java Application, and create a new configuration. Set the connection properties to host localhost and port 5005, then click Debug to attach.

Understanding the codebase structure helps you set meaningful breakpoints in the jenkinsci/jenkins repository.

Core Model Classes

The main Jenkins objects live under the hudson.* package hierarchy. Set breakpoints in core/src/main/java/hudson/model/AbstractProject.java to debug job scheduling and build logic. This abstract class serves as the base for freestyle projects, pipelines, and other job types.

// Example breakpoint location in AbstractProject.java
public abstract class AbstractProject<T extends Job<T,?>> extends ItemGroupMixIn 
    implements Actionable, ModelObject, ExtensionPoint, ItemGroup<T> {
    // Core job logic executes here
}

Web Layer and Servlet Container

The war module starts the servlet container via the Jetty plugin configuration in war/pom.xml. When debugging through Maven, you're running the WAR in-process, which provides seamless stepping between the web layer and core model without remote server complexity.

Alternative Debugging Techniques

Beyond traditional breakpoints, Jenkins offers runtime inspection tools.

Script Console for Runtime Inspection

Access http://localhost:8080/script to execute Groovy snippets while the server runs. This inspects internal state without restarting the debugger:

// Inspect all builds for a specific job
println Jenkins.instance.getItemByFullName('my-job').getBuilds()

Logging Configuration

Enable fine-grained logging via java.util.logging by creating a logging.properties file or using the System Log UI at /log/levels. This captures debug output from specific packages without attaching a debugger.

Debugging Jenkins Plugins

To step into plugin code alongside core, add the plugin to your local Maven build:

cd /path/to/plugin
mvn -DskipTests clean install

Include the plugin's source on your classpath, then use the same remote debug port (5005). The debugger seamlessly steps between core classes in war/target/jenkins.war and plugin source code.

Troubleshooting Common Debugging Issues

Class-loading conflicts occur when using the Jetty in-process mode with certain Maven plugins. Avoid running maven-plugin goals while debugging, as documented in CONTRIBUTING.md (lines 51-53), since Jetty disables some class loader separations.

Build failures in CI environments can be reproduced locally by examining the Jenkinsfile, which defines the pipeline stages for building, testing, and packaging the WAR. Understanding these stages helps you replicate exact CI conditions during debugging sessions.

Summary

  • Build the WAR using mvn -am -pl war,bom -Pquick-build clean install to generate war/target/jenkins.war
  • Launch with MAVEN_OPTS containing JDWP flags on port 5005, either via mvn -pl war jetty:run or java -jar
  • Attach IntelliJ or Eclipse via Remote Debug configuration to localhost:5005
  • Breakpoint core classes like hudson.model.AbstractProject in core/src/main/java/hudson/model/AbstractProject.java
  • Inspect runtime state using the Script Console at /script for quick state checks without breakpoints
  • Debug plugins by installing them locally and keeping the same remote debug port active

Frequently Asked Questions

How do I enable remote debugging in Jenkins?

Export MAVEN_OPTS with the JDWP flags before starting Jenkins: export MAVEN_OPTS='-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005'. Then run mvn -pl war jetty:run or execute the WAR directly with java $MAVEN_OPTS -jar war/target/jenkins.war. This opens port 5005 for IDE attachment.

Where are the main Jenkins classes located in the source code?

The core model classes reside in core/src/main/java/hudson/ within the jenkinsci/jenkins repository. Key files like AbstractProject.java define the base functionality for jobs and builds. The WAR packaging logic lives in war/pom.xml, which configures the Jetty servlet container.

Can I debug Jenkins without building the entire project?

No, you must build the WAR first using Maven to package the core classes and dependencies. Use the -Pquick-build profile for a faster build that skips tests: mvn -am -pl war,bom -Pquick-build clean install. This produces a runnable war/target/jenkins.war for debugging.

Why does IntelliJ fail to parse the Maven arguments when debugging Jenkins?

IntelliJ may struggle with the @{jenkins.addOpens} flag in certain versions. Clear the Pass to JUnit process argLine setting in your run configuration to resolve this parsing issue. This workaround is documented in the project's CONTRIBUTING.md file.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →