Merged
Conversation
Implements comprehensive Java debugging support using jdb (Java Debugger) as the underlying debug engine, with full DAP (Debug Adapter Protocol) integration. The Java adapter follows the established adapter pattern: - **JdbDapServer**: DAP protocol server that translates DAP requests to jdb commands - **JdbWrapper**: High-level wrapper around the jdb process - **JdbParser**: Parses jdb command-line output into structured data - **JavaAdapterPolicy**: Configures spawn behavior for Java debug sessions - **JavaAdapterFactory**: Creates and initializes Java debug adapters - Starts new JVM with jdb attached - Supports `stopOnEntry` via breakpoint at main method - Automatically extracts fully qualified class names from source files - Compiles .java files if .class files not found - Connects to running JVM with JDWP agent enabled - Uses unified attach API (host/port in create_debug_session) - Proper DAP sequencing with attach-specific flow - Breakpoints (set, clear, verify) - Step operations (step over, step into, step out) - Stack traces with source locations - Variable inspection (locals, scopes) - Expression evaluation - Continue/pause execution - Thread management - Accepts absolute paths for Java source files - Extracts package declarations to build FQN - Handles both packaged and default package classes When `stopOnEntry: true` is specified in launch mode: 1. Extract FQN from Java source (package + class name) 2. Set breakpoint at main: `stop in com.example.MyClass.main` 3. Execute `run` command to start JVM 4. Emit 'entry' stop reason when breakpoint hits Added JavaAdapterPolicy to `selectAdapterPolicy()` in dap-proxy-worker.ts. Previously, Java sessions were using DefaultAdapterPolicy which lacked proper spawn configuration, causing "Proxy exited during initialization" errors. Modified `run()` in JdbWrapper to use `sendCommandDirect()` instead of `executeCommand()`. The run command doesn't return a prompt until the program stops, so we send it asynchronously and listen for stopped events. - ✅ Complete Java debugging flow (breakpoint, stack, vars, step, continue) - ✅ Multiple breakpoints -⚠️ Expression evaluation with stopOnEntry (times out in full suite) - ✅ Source context retrieval -⚠️ Step into operations (times out in full suite) Note: The two tests that timeout in the full suite pass consistently when run individually, suggesting resource contention or cleanup issues when running many E2E tests in sequence. Will be addressed in future work. - ✅ Attach to running Java process - ✅ Set breakpoint after attaching - ✅ Detach without terminating process - ✅ Session lifecycle management - Added to pnpm workspace packages - Included in build:packages script - Integrated with CI/CD pipeline - src/index.ts - Adapter factory export - src/jdb-dap-server.ts - DAP server implementation - src/factory.ts - JavaAdapterFactory - src/utils/jdb-wrapper.ts - jdb process manager - src/utils/jdb-parser.ts - Output parser - tests/ - Comprehensive test suite - src/proxy/dap-proxy-worker.ts - Added JavaAdapterPolicy selection - packages/shared/src/interfaces/adapter-policy.ts - Exported JavaAdapterPolicy - tests/e2e/ - Added Java smoke and attach tests - package.json - Added build scripts and workspace config - Java 8+ installed - jdb available in PATH (included with JDK) - For attach mode: Target JVM started with JDWP agent Example: `java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005` - jdb includes Java internal frames in stack traces (by design) - Requires absolute paths for file references - stopOnEntry only works for main method entry point - Expression evaluation requires VM to be running (jdb limitation) - Two E2E tests timeout in full suite but pass individually (resource contention) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Enable the Java/jdb debug adapter to be loaded at runtime by adding it to the optionalDependencies in package.json. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract mainClass from program path in transformLaunchConfig instead
of hardcoding 'Main'. This fixes "Could not find or load main class"
errors in launch mode.
- Fix attach tests to use 127.0.0.1 instead of 'localhost' to avoid
IPv6 resolution issues when the Java process binds to IPv4 only.
- Improve attach test stability by:
- Waiting for "Listening for transport" message before proceeding
- Adding 2 second delay after session close to allow JDWP to accept
new connections (JDWP only allows one debugger at a time)
- Accepting 'initializing' as valid state since attach is async
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Different debug adapters send the 'initialized' event at different points in the DAP sequence: - Java/jdb: sends 'initialized' after initialize response, before attach - Python/debugpy: sends 'initialized' AFTER receiving the launch request This fix: - For attach mode: wait for 'initialized' before sending attach - For launch mode: send launch first, then handle 'initialized' later Also updates unit tests to properly mock EventEmitter-based DAP client and emit 'initialized' events in test stubs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update package version from 0.16.0 to 0.17.0 to match other adapters - Use AdapterError/AdapterErrorCode instead of generic Error - Fix stateChanged event to emit two params instead of object - Add missing JSDoc comments on exported interfaces Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The pre-push hook would fail when Docker was installed but buildx was missing. Now checks for buildx availability before attempting to build, allowing the push to proceed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pre-push hook auto-detects Docker buildx and sets SKIP_DOCKER_TESTS - Pre-push hook sources cargo env for Rust test availability - Docker smoke tests respect SKIP_DOCKER_TESTS via describe.skipIf - docker-build-if-needed.js checks buildx before attempting build Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b58a2b7 to
b3267f8
Compare
Verbose output from vitest (thousands of lines) was flooding the pipe buffer between git and the hook process, causing SIGPIPE (exit 141) which git treated as a hook failure even when all tests passed. Now redirects lint/build/test output to a temp log file and only prints a concise summary to stdout. On failure, shows relevant error lines and preserves the log for inspection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roofpig95008
commented
Feb 7, 2026
Author
roofpig95008
left a comment
There was a problem hiding this comment.
Clean these up before submitting PR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📋 Description
Adds Java/JDB debugging support to mcp-debugger as a new language adapter. This enables AI agents to step-through
debug Java applications using the standard jdb debugger included with the JDK, following the same adapter architecture
used by Python, JavaScript, and Rust adapters.
The implementation includes:
🔄 Type of Change
✅ Checklist
🧪 Testing
All 134 test suites pass (1517 tests), with 5 suites skipped (Docker/stress tests requiring infrastructure not
available in all environments).
Full test suite
npm test
Unit tests only
npm run test:unit
Java adapter unit tests specifically
npx vitest run packages/adapter-java/tests/
E2E Java smoke tests (requires JDK 8+)
npx vitest run tests/e2e/mcp-server-smoke-java.test.ts
E2E Java attach tests (requires JDK 8+)
npx vitest run tests/e2e/mcp-server-java-attach.test.ts
Test Configuration:
📸 Screenshots (if applicable)
N/A — backend adapter with no UI components.
🔗 Related Issues
📝 Additional Notes
injection, AdapterError/AdapterErrorCode error types, and two-parameter stateChanged event emission.
env sourcing) and Docker test skip support via SKIP_DOCKER_TESTS.
Reviewer: @debugmcp