English | 中文
Give your AI eyes inside a running JVM. A lightweight diagnostic agent that attaches to a live Java process and lets an AI assistant (or you) observe real runtime behavior — read field values, capture method params/returns/exceptions, trace call timing, decompile the actually running bytecode, and hot-swap code to verify a fix — without restarting the process.
Ships as a Claude Code skill so the AI drives the whole diagnosis: you describe the symptom, it attaches, investigates, and hands you a verified root cause.
⚠️ Status: pre-release. The agent ships as a prebuilt binary (skill/bin/stub-agent.jar); the agent's own source isn't published yet. Fine-grained security controls (scoped permissions, remote auth) are on the roadmap — use on local / test JVMs you own, not production. See Security.
AI is already good at writing and reading code. But when a bug only shows up at runtime, code alone can't tell you what value that object actually holds right now. The old loop — add a log, restart, reproduce, look again — burns hours, and a human has to drive every step.
stub-debug gives the AI a way to look inside the running JVM:
- Read the real runtime value of any object / Spring bean field — no log lines
- Capture a single call's params, return, exception — no breakpoints
- See method timing trees, caller stacks, threads / memory / GC — find the slow or stuck spot
- Decompile a loaded class — confirm what's actually deployed
- Hot-swap a method to test a hypothesis, then roll back in one call
attach exits as soon as the agent loads; the process keeps running. Idle-unload when done — nothing lingers.
# 1. Point these at YOUR target process. JDK must match the target's Java version.
JAR=$(pwd)/skill/bin/stub-agent.jar
JDK=/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home # e.g. Java 8 target
PID=$("$JDK/bin/jps" -l | grep YourMainClass | awk '{print $1}')
# 2. Attach (loads the agent, then exits — process is NOT restarted)
"$JDK/bin/java" -jar "$JAR" "$PID" "token=stubLocalDebug,port=18565"
# 3. Health check — HTTP server now runs inside the target JVM
curl -s -H "Authorization: Bearer stubLocalDebug" http://127.0.0.1:18565/infoThen hit any capability over HTTP (all POST, all Bearer-authed):
AUTH="Authorization: Bearer stubLocalDebug"; B=http://127.0.0.1:18565
# Read a Spring bean's runtime field value — the fastest "is the config right?" check
curl -s -H "$AUTH" -X POST $B/spring -d '{"type":"com.example.OrderService","path":".config.region"}'
# Thread hotspots / deadlocks
curl -s -H "$AUTH" -X POST $B/thread -d '{"topCpu":5}'
# Decompile the actually-running class
curl -s -H "$AUTH" -X POST $B/sc -d '{"classPattern":"*OrderService*"}' # get classLoaderHash
curl -s -H "$AUTH" -X POST $B/jad -d '{"fqcn":"com.example.OrderService","classLoaderHash":414493378}'Instrumentation (watch/trace/stack) is submit → trigger the call → poll → cancel — the probe only captures calls made after it's installed:
curl -s -H "$AUTH" -X POST $B/watch/submit -d '{"jobId":"j1","class":"com.example.OrderService","method":"batchQuery","watchParams":true,"watchReturn":true}'
# … now trigger the request …
curl -s -H "$AUTH" -X POST $B/watch/poll -d '{"jobId":"j1"}'
curl -s -H "$AUTH" -X POST $B/watch/cancel -d '{"jobId":"j1"}'When you're done, unload (restores all instrumentation; the JVM keeps running):
curl -s -H "$AUTH" -X POST $B/shutdownInstall the skill so the AI drives diagnosis end-to-end:
# copy the skill into your Claude Code skills dir
cp -r skill ~/.claude/skills/stub-debugThen just tell Claude the symptom:
"
git pushreturns 403Push to create is not enabled, take a look."
It attaches, reads runtime state, cross-checks, and reports the root cause — no commands from you. See the Chinese README for a full walkthrough.
Symptom. While building a git-proxy feature, git push fails with 403 Push to create is not enabled. The code, the config, and the DB records all look fine.
Without stub-debug, the AI can only read source and guess — "trailing slash in baseUrl? wrong groupId?" — then add a log, restart, reproduce. Half a day per round, and it still has to ask you to go dig through mongo and Gitea to confirm.
With stub-debug, use claude code skill
No log line added, no restart. The AI read a live field value and pinned a data-vs-remote mismatch that source code alone could never reveal.
Arthas is a powerful, battle-tested tool and now ships an (experimental) MCP module. stub-debug isn't a replacement — it's a lighter, opinionated build for one scenario: AI-driven, unattended diagnosis on JVMs you own, with a bias toward:
- Zero middle layer — attach one jar, get structured HTTP/JSON the AI can parse and orchestrate directly.
- Self-healing — idle auto-unload + per-job TTL + hot-swap backup, so probes never linger even if the caller drops mid-session.
- Scoped by design (roadmap) — read-only / instrument / mutate tiers, so line-of-fire use can be gated.
For general interactive diagnosis, reach for Arthas. For "let the AI look and clean up after itself," this is the smaller tool.
This is a debugging agent: it can read arbitrary runtime state and hot-swap bytecode. It has no fine-grained access control yet.
- Local / test JVMs you own — fine. The process is yours; attaching adds no extra exposure. Unload when done.
- Production — not yet. Reading runtime data and redefining classes against prod without tiered controls is risky.
Roadmap: read-only (open) / instrument (auto-restore, TTL) / mutate (confirm + audit + rollback) tiers, plus remote-reachable auth (Bearer + CIDR allow-list). Keep the port bound to localhost until then.
- JDK version must match the target (attach uses
jdk.attach; Java 8 needstools.jar). Using JDK 21 to attach a Java 8 process fails. - Instrumentation order: submit → trigger → poll. Reversed, you capture nothing.
- Observe first; get confirmation before
redefine, alwaysrestoreafter. - Unload with
/shutdown, neverkillthe process (kill leaves probes un-restored).
MIT. The prebuilt stub-agent.jar bundles third-party components (ASM — BSD-3-Clause; CFR decompiler — MIT); their notices are retained and apply to those components.


