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

> Debug Jenkins code effectively. Build the WAR with Maven, launch with JDWP flags on port 5005, and attach your IDE to step through core classes for efficient troubleshooting.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: how-to-guide
- Published: 2026-08-01

---

**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`](https://github.com/jenkinsci/jenkins/blob/main/CONTRIBUTING.md) (lines 24-34).

Run this command for a fast build that skips tests:

```bash
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`](https://github.com/jenkinsci/jenkins/blob/main/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`](https://github.com/jenkinsci/jenkins/blob/main/war/pom.xml):

```bash
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:

```bash
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`](https://github.com/jenkinsci/jenkins/blob/main/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.

## Navigate the Core Architecture While Debugging

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`](https://github.com/jenkinsci/jenkins/blob/main/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.

```java
// 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`](https://github.com/jenkinsci/jenkins/blob/main/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:

```groovy
// 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:

```bash
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`](https://github.com/jenkinsci/jenkins/blob/main/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`](https://github.com/jenkinsci/jenkins/blob/main/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`](https://github.com/jenkinsci/jenkins/blob/main/AbstractProject.java) define the base functionality for jobs and builds. The WAR packaging logic lives in [`war/pom.xml`](https://github.com/jenkinsci/jenkins/blob/main/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`](https://github.com/jenkinsci/jenkins/blob/main/CONTRIBUTING.md) file.