From jdb-debugger
Debugs Java applications using JDB CLI: attach to running JVMs with JDWP, launch new ones under debugger, set breakpoints, step code, inspect variables/threads, diagnose exceptions.
npx claudepluginhub brunoborges/jdb-agentic-debugger --plugin jdb-agentic-debuggerThis skill is limited to using the following tools:
Debug Java applications interactively using the JDK's built-in command-line debugger.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Debug Java applications interactively using the JDK's built-in command-line debugger.
bp.txt, cmds.txt, wrapper scripts, etc.).
Use the inline CLI flags (--bp, --cmd, --auto-inspect, --timeout) provided by the skill scripts.scripts/. Never write
custom JDB wrapper scripts, FIFO-based launchers, or shell scripts to drive JDB.wsl bash scripts/<script>.shThe scripts in this skill are Bash scripts. On Windows, invoke them via WSL:
wsl bash scripts/jdb-launch.sh com.example.MyApp --sourcepath src/main/java
If your compiled classes are on the Windows filesystem, WSL accesses them via /mnt/c/:
wsl bash scripts/jdb-launch.sh com.example.MyApp --classpath /mnt/c/Users/you/project/out
Ensure JDK is installed in WSL:
# Ubuntu/Debian WSL
sudo apt update && sudo apt install -y default-jdk
# Verify
which jdb && jdb -version
Scripts run natively. Ensure JDK is installed and jdb is on PATH:
export PATH=$JAVA_HOME/bin:$PATH
User wants to debug Java app →
├─ App is already running with JDWP agent?
│ ├─ Yes → Attach: scripts/jdb-attach.sh --port <port>
│ └─ No → Can you restart with JDWP?
│ ├─ Yes → Launch with: scripts/jdb-launch.sh <mainclass> [args]
│ └─ No → Suggest adding JDWP agent to JVM flags (see below)
│
├─ What does the user need?
│ ├─ Set breakpoints & step through code → Interactive JDB session
│ ├─ Collect thread dumps / diagnostics → scripts/jdb-diagnostics.sh
│ └─ Catch a specific exception → Use `catch` command in JDB
│
└─ Done debugging → Detach cleanly with `quit` or Ctrl+C
bash scripts/jdb-launch.sh com.example.MyApp --sourcepath src/main/java
First, ensure the target JVM was started with the JDWP agent:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar myapp.jar
Then attach:
bash scripts/jdb-attach.sh --host localhost --port 5005
bash scripts/jdb-diagnostics.sh --port 5005
If the target JVM was not started with JDWP, suggest the user restart with:
# For direct Java launch
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -cp myapp.jar com.example.Main
# For Maven Spring Boot
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
# For Gradle
./gradlew bootRun --jvmArgs="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
# As environment variable
export JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
Once inside a JDB session (launched or attached), use these commands interactively:
stop at com.example.MyClass:42 # Break at line 42
stop in com.example.MyClass.myMethod # Break at method entry
stop in com.example.MyClass.<init> # Break at constructor
stop in com.example.MyClass.<clinit> # Break at static initializer
For overloaded methods, specify parameter types:
stop in com.example.MyClass.process(int,java.lang.String)
run # Start the application (if launched, not attached)
cont # Continue execution after hitting a breakpoint
step # Step into the next line (enters method calls)
next # Step over to the next line (skips method internals)
step up # Run until the current method returns
locals # Show all local variables in the current frame
print myVariable # Print value of a variable or expression
print myObj.getX() # Evaluate a method call
dump myObject # Show all fields of an object
eval 2 + 2 # Evaluate an arbitrary expression
where # Show the current thread's call stack
where all # Show call stacks for all threads
up # Move up one frame in the stack
down # Move down one frame in the stack
up 3 # Move up 3 frames
threads # List all threads and their states
thread main # Switch to the "main" thread
thread 0x1a3 # Switch to thread by ID
suspend 0x1a3 # Suspend a specific thread
resume 0x1a3 # Resume a specific thread
catch java.lang.NullPointerException # Break on NPE
catch java.lang.Exception # Break on any Exception
catch all # Break on all throwables
ignore java.lang.NullPointerException # Stop catching NPE
classes # List all loaded classes
class com.example.MyClass # Show details of a class
methods com.example.MyClass # List all methods of a class
fields com.example.MyClass # List all fields of a class
clear # List all breakpoints
clear com.example.MyClass:42 # Remove breakpoint at line 42
clear com.example.MyClass.myMethod # Remove method breakpoint
list # List source around current line
list 50 # List source around line 50
use /path/to/sources # Set source path
sourcepath # Show current source path
classpath # Show current classpath
quit # Exit JDB (detaches from JVM)
exit # Same as quit
Use inline --bp flags and --auto-inspect — no files needed:
bash scripts/jdb-breakpoints.sh \
--mainclass com.example.MyClass \
--bp "catch java.lang.NullPointerException" \
--bp "stop at com.example.MyClass:42" \
--bp "stop in com.example.MyClass.processMessage" \
--auto-inspect 20
The --auto-inspect 20 flag automatically generates run + 20 cycles of
where, locals, cont + quit. The output contains the full JDB session
including stack traces, local variables, and exception details — ready for analysis.
For applications that may hang or deadlock, add --timeout <seconds> to kill the
JDB session after the specified time:
bash scripts/jdb-breakpoints.sh \
--mainclass com.example.MyClass \
--bp "catch java.lang.NullPointerException" \
--auto-inspect 10 --timeout 60
For custom commands, use --cmd flags instead of --auto-inspect:
bash scripts/jdb-breakpoints.sh \
--mainclass com.example.MyClass \
--bp "catch java.lang.NullPointerException" \
--cmd "run" --cmd "where" --cmd "locals" --cmd "print myVar" --cmd "cont" \
--cmd "where" --cmd "locals" --cmd "cont" --cmd "quit"
# 1. Set breakpoint at method entry
stop in com.example.Service.processOrder
# 2. Continue until breakpoint is hit
cont
# 3. Inspect arguments and step through
locals
next
print result
next
print result
# 1. List all threads
threads
# 2. Check each blocked thread's stack
where all
# 3. Look for threads in MONITOR state holding different locks
thread <blocked-thread-id>
where
# 1. Set breakpoint
stop at com.example.DataProcessor:128
# 2. Continue to breakpoint
cont
# 3. Inspect everything
locals
print config.getTimeout()
dump dataMap
--bp, --cmd, --auto-inspect, and --timeout
flags. The scripts handle all temp files internally in /tmp/ and clean up after themselves.--timeout for potentially hanging apps. Apps that deadlock or loop indefinitely
will block JDB forever. Add --timeout 60 (or appropriate value) so the session is
automatically killed. The output will include a TIMEOUT: marker when triggered.-g for full debug info. Without it, locals will show
"Local variable information not available". Always compile with:
javac -g -d out src/main/java/com/example/MyClass.java-sourcepath or use command so list can show source code.thread to switch.suspend=y, the JVM pauses until JDB connects. Use suspend=n for non-blocking attachment.print and eval can call methods on live objects — use with caution in production.JDB_BP_DELAY (default: 2s), JDB_RUN_DELAY (3s), JDB_CMD_DELAY (0.5s), JDB_CONT_DELAY (1s).