Skip to content

Java Debug Server

issuelens[bot] edited this page Oct 29, 2026 · 10 revisions

Java Debug Server

microsoft/java-debug implements server-side Java debugging. The page distinguishes that server from the VS Code debugger extension: this component exposes JDT Language Server (JDTLS) delegate commands and runs the protocol server; it does not describe VS Code debug UI or launch.json editing.

JDTLS delegate commands

The plugin contributes JavaDebugDelegateCommandHandler to JDTLS's org.eclipse.jdt.ls.core.delegateCommandHandler extension point. Its registered commands include starting a debug session, resolving classpaths and main classes, validating launch configuration, updating debug settings, and resolving source/class-filter information. The handler starts the singleton JavaDebugServer for vscode.java.startDebugSession and returns its port; the other commands are handled by the server-side delegate implementations.

Protocol-server path

JavaDebugServer creates a server socket, accepts connections, and creates a ProtocolServer for each connection with a JDT-backed provider context. ProtocolServer creates a DebugAdapter and dispatches protocol requests through it. DebugAdapter registers common initialization/launch handlers and debug-mode handlers for attach, breakpoints, stepping, stack/scopes/variables, evaluation, hot-code replace, completions, exception information, data breakpoints, and related requests; its no-debug mode has a narrower handler set.

DAP terminate request

The server advertises supportsTerminateRequest and registers its terminate handler for both debug and no-debug modes. Termination is intentionally a no-op for attached sessions. For a launched debug session, it uses the shared all-thread resume path to clear transient stopped/evaluation/exception/frame state, resume the VM, and emit a continued event before terminating the debug session. It does not first detach or mark the VM terminated, so shutdown-hook code can remain debuggable. For a no-debug launch, it destroys the tracked process, or resolves and destroys the process from the stored PID.

Evidence: TerminateRequestHandler, InitializeRequestHandler, ThreadsRequestHandler, and DebuggeeProcessHelper, verified at merged/source-tip commit 90fdfe8e7a8ec4502b73c13b43f6f98a2f236064 (PR #645; source identity microsoft/java-debug#645:90fdfe8e7a8ec4502b73c13b43f6f98a2f236064). Checked-in unit coverage includes capability advertisement, attach no-op, no-debug process destruction, and resume/cleanup ordering; the checked-in JDI scenario covers a shutdown-hook breakpoint on non-Windows platforms. These tests were inspected, not executed; this is not a release or deployment claim.

Repository team-memory workflow

The checked-in Queue IssueLens Team Memory (opt-in) workflow triggers only on pushes to main. Its team-memory job requires ISSUELENS_TEAM_MEMORY_ENABLED == 'true', repository microsoft/java-debug, a ref matching the repository's current default branch, a push event, github.workflow_sha == github.sha, and false created, deleted, and forced flags. The explicit main trigger does not automatically follow a default-branch rename. The job runs on ubuntu-latest with a 10-minute timeout; workflow-level permissions are empty, with no job-level permissions override. [Workflow evidence below.]

Dispatch authentication uses actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 (v3.3.0), reading vars.ISSUELENS_DISPATCH_APP_CLIENT_ID and secrets.ISSUELENS_DISPATCH_APP_PRIVATE_KEY. It scopes the requested token to owner microsoft, repository vscode-java-pack, with Contents-read and Actions-write permissions. The queue step receives steps.dispatch-token.outputs.token, not github.token. PR #644 updates only this action pin in the team-memory workflow; its token inputs, requested scope, and queue step remain unchanged. PR #640 previously restored this App-token wiring and removed the source-job Contents-read/Actions-write override introduced by #639. Its stated rationale is that source-repository GITHUB_TOKEN permissions do not grant cross-repository Actions-write access. The checked-in references establish configuration dependencies, not that variables, secrets, or App access have been configured.

The queue step invokes microsoft/IssueLens/.github/actions/queue-team-memory@a81d2d96167fc0e69ac631c2edc85f858e693289, targeting microsoft/vscode-java-pack, workflow team-memory-coordinator.yml, ref main. Its JSON input contains exactly five string fields: source_repository (github.repository), source_run_id (github.run_id), source_run_attempt (github.run_attempt), push_before (github.event.before), and push_after (github.sha). This source workflow contains neither workflow_dispatch nor a concurrency declaration or direct agent invocation. See Java Pack's coordinator and manual-recovery documentation for the separately documented coordinator boundary; its implementation was not revalidated here.

Current workflow evidence: microsoft/java-debug/.github/workflows/team-memory-post-merge.yml, on, permissions, and jobs.team-memory, verified at merged/source-tip commit 733899f4b762fa0439edb9cd79c83403948faa20; PR #644, source identity microsoft/java-debug#644:733899f4b762fa0439edb9cd79c83403948faa20. The complete two-file inventory was inspected and PR identities rechecked after paging. The same PR updates the CI workflow's actions/setup-java pin from v6.0.1 to v6.1.0 for its existing Linux, Windows, and macOS JDK 21 jobs; it does not change their JDK distribution, Maven verify commands, or Checkstyle commands. See the build workflow at that source revision. This records checked-in workflow configuration, not action internals, executed tests, successful token minting/dispatch, delivery guarantees, release, or deployment. PR #640 remains the provenance for the authentication reversal.

Historical provenance: the former Update IssueLens Team Memory configuration documented from PR #637, source identity microsoft/java-debug#637:1ed7ca84d30808adb5510dbdb406d88a8a99c858, used source-local manual PR dispatch, per-push/per-PR concurrency, a 30-minute timeout, and direct issuelens invocation. Its workflow at full source commit 1ed7ca84d30808adb5510dbdb406d88a8a99c858 is retained as superseded evidence, not current operation.

Repository issue-triage action

The separate Run IssueLens Agent workflow's jobs.triage step invokes microsoft/IssueLens/.github/actions/issuelens@c431d42dddf4e6bf20329b0ac96dbd8a4bf04006 with request-type: issue-loop. PR #646 replaces the mutable @main reference with this full immutable commit; the action path, inputs, triggers, permissions, concurrency, and 20-minute job timeout remain unchanged. This does not modify the team-memory workflow or Java debug-server implementation. The checked-in pin records dependency configuration, not independently verified shared-action internals, executed validation, a successful triage run, release, or deployment.

Evidence: microsoft/java-debug/.github/workflows/issuelens-run.yml, jobs.triage, verified at merged/source-tip commit 89e59b7cb8f3c543bafbf4691f30e3f87d9acccc; PR #646, source identity microsoft/java-debug#646:89e59b7cb8f3c543bafbf4691f30e3f87d9acccc. The complete one-file manifest and patch were inspected, before/after and final source were verified, and PR metadata was rechecked after paging.

Provenance

This component entry was added while onboarding microsoft/java-debug after PR #635. The behavior above was verified against source commit 7a625c6ff35f95e92ce232fcf6f0af64b9ce715b:

Folder-scoped main-class resolution with linked sources

ResolveMainClassHandler.resolveMainClassUnderPaths includes Java projects whose descriptions live outside the requested folder when their linked sources are inside it. For a nonempty folder filter, projects must still have a non-null project location and an existing Java project. Scope selection accepts containment of the project location, the invisible project's workspace-link folder, or a source-folder location. hasSourceFolderContainedIn examines raw-classpath CPE_SOURCE entries, resolves each workspace path with ResourcesPlugin.getWorkspace().getRoot().findMember, and checks the resource's non-null filesystem location. The search remains source-only.

Scope inclusion does not automatically accept every main class from a project with linked source roots in several workspace folders. In acceptSearchMatch, the existing project-location and invisible-project checks remain; otherwise isMatchContainedIn requires the match resource's location to be inside the requested paths. Thus matches admitted only through the new source-folder route are filtered by their own location, while asking with a project's own location retains the existing project-wide acceptance behavior. An empty path filter remains unrestricted across Java projects.

For diagnosis of missing folder-scoped main classes, distinguish the project location from linked source locations and the individual match location. If reading the raw classpath throws JavaModelException, the source-folder helper logs a warning beginning Failed to read the classpath of project and returns false. This is server-side resolution behavior, not a change to VS Code UI or project import ownership.

Evidence: microsoft/java-debug/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java, symbols resolveMainClassUnderPaths, acceptSearchMatch, hasSourceFolderContainedIn, isMatchContainedIn, and isContainedInInvisibleProject; verified at merged source commit bcae605a6240f11b447163a614e215721c11b107 (PR #633; source identity microsoft/java-debug#633:bcae605a6240f11b447163a614e215721c11b107). This revision is also the batch's push_after and supplied source_tip_sha. The complete PR changes only this implementation file, with no test changes. These findings are source-inspected, not a claim of executed tests, release availability, or deployment.

Breakpoint resolution for encoded source files

For file-backed Java sources, JdtSourceLookUpProvider.asCompilationUnit decodes the source before JDT AST parsing and breakpoint class-name/location resolution. Workspace resources use Eclipse IFile.readString(), so file- or project-configured encodings apply and Unicode byte-order marks are removed. External files recognize UTF-8, UTF-16LE, and UTF-16BE BOMs; an external file without a recognized BOM retains the language-server JVM's default-charset fallback. A read failure logs Failed to read source file: <path> and supplies empty source, so encoding or read diagnostics belong to this server/JDT source-lookup path rather than VS Code breakpoint UI.

Evidence: JdtSourceLookUpProvider, symbols asCompilationUnit and readFile, verified at merged/source-tip commit a658059daa820c9d532407eba3c1ae7697d4ef2b (PR #647; source identity microsoft/java-debug#647:a658059daa820c9d532407eba3c1ae7697d4ef2b). JdtSourceLookUpProviderTest contains 14 parameterized workspace/external cases covering BOM-aware UTF-8/UTF-16, configured file/project UTF-8/UTF-16/ISO-8859-1, external default-charset fallback, and resolved breakpoint class names. The same revision configures Tycho plugin-test execution in the plugin POM and adds m2e/Buildship units to the target platform. The complete four-file PR inventory and final source were inspected; tests were not executed during wiki maintenance, and this is not a release or deployment claim.

Clone this wiki locally