From e55e8beb5dc44e9c661c1944f1d3b62ec09ddce1 Mon Sep 17 00:00:00 2001 From: Marshal Hayes <17213165+marshalhayes@users.noreply.github.com> Date: Wed, 15 Oct 2025 21:04:01 -0500 Subject: [PATCH 1/6] Start Java debug extension support --- extension/src/capabilities.ts | 9 +++++++++ extension/src/dcp/types.ts | 10 ++++++++++ extension/src/debugger/debuggerExtensions.ts | 7 ++++++- extension/src/debugger/languages/java.ts | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 extension/src/debugger/languages/java.ts diff --git a/extension/src/capabilities.ts b/extension/src/capabilities.ts index 878e847807b..36f047630dd 100644 --- a/extension/src/capabilities.ts +++ b/extension/src/capabilities.ts @@ -19,6 +19,10 @@ export function isPythonInstalled() { return isExtensionInstalled("ms-python.python"); } +export function isJavaInstalled() { + return isExtensionInstalled("vscjava.vscode-java-pack"); +} + export function getSupportedCapabilities(): string[] { const capabilities = ['prompting', 'baseline.v1', 'secret-prompts.v1']; @@ -37,6 +41,11 @@ export function getSupportedCapabilities(): string[] { capabilities.push("ms-python.python"); } + if (isJavaInstalled()) { + capabilities.push("java"); + capabilities.push("vscjava.vscode-java-pack"); + } + return capabilities; } diff --git a/extension/src/dcp/types.ts b/extension/src/dcp/types.ts index 77a3bbb0cc8..27c135be109 100644 --- a/extension/src/dcp/types.ts +++ b/extension/src/dcp/types.ts @@ -38,6 +38,16 @@ export function isPythonLaunchConfiguration(obj: any): obj is PythonLaunchConfig return obj && obj.type === 'python'; } +export interface JavaLaunchConfiguration extends ExecutableLaunchConfiguration { + type: "java"; + main_class_path?: string; + project_path?: string; +} + +export function isJavaLaunchConfiguration(obj: any): obj is JavaLaunchConfiguration { + return obj && obj.type === 'java'; +} + export interface EnvVar { name: string; value: string; diff --git a/extension/src/debugger/debuggerExtensions.ts b/extension/src/debugger/debuggerExtensions.ts index b0396341d73..943e3515a43 100644 --- a/extension/src/debugger/debuggerExtensions.ts +++ b/extension/src/debugger/debuggerExtensions.ts @@ -4,8 +4,9 @@ import { debugProject } from "../loc/strings"; import { mergeEnvs } from "../utils/environment"; import { extensionLogOutputChannel } from "../utils/logging"; import { projectDebuggerExtension } from "./languages/dotnet"; -import { isCsharpInstalled, isPythonInstalled } from "../capabilities"; +import { isCsharpInstalled, isJavaInstalled, isPythonInstalled } from "../capabilities"; import { pythonDebuggerExtension } from "./languages/python"; +import { javaDebuggerExtension } from "./languages/java"; // Represents a resource-specific debugger extension for when the default session configuration is not sufficient to launch the resource. export interface ResourceDebuggerExtension { @@ -70,6 +71,10 @@ export function getResourceDebuggerExtensions(): ResourceDebuggerExtension[] { extensions.push(pythonDebuggerExtension); } + if (isJavaInstalled()) { + extensions.push(javaDebuggerExtension); + } + return extensions; } diff --git a/extension/src/debugger/languages/java.ts b/extension/src/debugger/languages/java.ts new file mode 100644 index 00000000000..8d538a78be3 --- /dev/null +++ b/extension/src/debugger/languages/java.ts @@ -0,0 +1,17 @@ +import { isJavaLaunchConfiguration } from "../../dcp/types"; +import { invalidLaunchConfiguration } from "../../loc/strings"; +import { ResourceDebuggerExtension } from "../debuggerExtensions"; + +export const javaDebuggerExtension: ResourceDebuggerExtension = { + resourceType: 'java', + debugAdapter: 'java', + extensionId: 'vscjava.vscode-java-pack', + displayName: 'Java', + getProjectFile: (launchConfig) => { + if (isJavaLaunchConfiguration(launchConfig) && launchConfig.project_path) { + return launchConfig.project_path; + } + + throw new Error(invalidLaunchConfiguration(JSON.stringify(launchConfig))); + } +}; From 09a787ed9e7c6cdcdb546c1dc76fe39c4ceacdd4 Mon Sep 17 00:00:00 2001 From: Marshal Hayes <17213165+marshalhayes@users.noreply.github.com> Date: Thu, 16 Oct 2025 20:32:56 -0500 Subject: [PATCH 2/6] Fallback to project_path if main_class_path is not provided --- extension/src/debugger/languages/java.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extension/src/debugger/languages/java.ts b/extension/src/debugger/languages/java.ts index 8d538a78be3..19c27523795 100644 --- a/extension/src/debugger/languages/java.ts +++ b/extension/src/debugger/languages/java.ts @@ -8,8 +8,11 @@ export const javaDebuggerExtension: ResourceDebuggerExtension = { extensionId: 'vscjava.vscode-java-pack', displayName: 'Java', getProjectFile: (launchConfig) => { - if (isJavaLaunchConfiguration(launchConfig) && launchConfig.project_path) { - return launchConfig.project_path; + if (isJavaLaunchConfiguration(launchConfig)) { + const programPath = launchConfig.main_class_path || launchConfig.project_path; + if (programPath) { + return programPath; + } } throw new Error(invalidLaunchConfiguration(JSON.stringify(launchConfig))); From 13c00b5fbb140f61d80780ab668c3b50ae329180 Mon Sep 17 00:00:00 2001 From: Marshal Hayes <17213165+marshalhayes@users.noreply.github.com> Date: Thu, 16 Oct 2025 21:12:20 -0500 Subject: [PATCH 3/6] Add basic tests for Java debugger extension --- extension/src/test/javaDebugger.test.ts | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 extension/src/test/javaDebugger.test.ts diff --git a/extension/src/test/javaDebugger.test.ts b/extension/src/test/javaDebugger.test.ts new file mode 100644 index 00000000000..2b4c0937702 --- /dev/null +++ b/extension/src/test/javaDebugger.test.ts @@ -0,0 +1,65 @@ +import * as assert from 'assert'; +import { javaDebuggerExtension } from '../debugger/languages/java'; +import { JavaLaunchConfiguration } from '../dcp/types'; + +suite('Java Debugger Extension Tests', () => { + test('getProjectFile returns main_class_path when provided', () => { + const mainClassPath = '/path/to/MainClass.java'; + const launchConfig: JavaLaunchConfiguration = { + type: 'java', + main_class_path: mainClassPath, + project_path: '/path/to/project' + }; + + const result = javaDebuggerExtension.getProjectFile(launchConfig); + + assert.strictEqual(result, mainClassPath); + }); + + test('getProjectFile returns project_path when main_class_path is not provided', () => { + const projectPath = '/path/to/project'; + const launchConfig: JavaLaunchConfiguration = { + type: 'java', + project_path: projectPath + }; + + const result = javaDebuggerExtension.getProjectFile(launchConfig); + + assert.strictEqual(result, projectPath); + }); + + test('getProjectFile throws error when neither main_class_path nor project_path is provided', () => { + const launchConfig: JavaLaunchConfiguration = { + type: 'java' + }; + + assert.throws( + () => javaDebuggerExtension.getProjectFile(launchConfig) + ); + }); + + test('getProjectFile prefers main_class_path over project_path when both are provided', () => { + const mainClassPath = '/path/to/MainClass.java'; + const projectPath = '/path/to/project'; + const launchConfig: JavaLaunchConfiguration = { + type: 'java', + main_class_path: mainClassPath, + project_path: projectPath + }; + + const result = javaDebuggerExtension.getProjectFile(launchConfig); + + assert.strictEqual(result, mainClassPath); + }); + + test('getProjectFile throws error when launch configuration is not Java type', () => { + const launchConfig = { + type: 'python', + program_path: '/path/to/program.py' + }; + + assert.throws( + () => javaDebuggerExtension.getProjectFile(launchConfig as any) + ); + }); +}); From 68668ab56e4ffec060fdbac3ab667412f3568eed Mon Sep 17 00:00:00 2001 From: Marshal Hayes <17213165+marshalhayes@users.noreply.github.com> Date: Thu, 16 Oct 2025 21:32:59 -0500 Subject: [PATCH 4/6] Add Java to README.md, and include links to debugger extension docs --- extension/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/extension/README.md b/extension/README.md index c17161cdf1c..8e8d93ead21 100644 --- a/extension/README.md +++ b/extension/README.md @@ -46,6 +46,7 @@ To run and debug your Aspire application, add an entry to the workspace `launch. |---------|-------------| | C# | project | | Python | python | +| Java | java | The debuggers property stores common debug configuration properties for different types of Aspire services. C#-based services have common debugging properties under `project`. Python-based services have their common properties under `python`. @@ -71,6 +72,12 @@ There is also a special entry for the apphost (`apphost`). For example: } ``` +Available configuration options for each debugger type can be found in the corresponding extension's documentation: + +- [C# debugger options](https://code.visualstudio.com/docs/csharp/debugging#_configuration-options) +- [Python debugger options](https://code.visualstudio.com/docs/python/debugging#_set-configuration-options) +- [Java debugger options](https://code.visualstudio.com/docs/java/java-debugging#_configuration-options) + ## Requirements - The [Aspire CLI](https://learn.microsoft.com/en-us/dotnet/aspire/cli/install) must be installed and available on the path. From 50b435f49b37a65a26d7ca846c58e00d208ba44e Mon Sep 17 00:00:00 2001 From: Marshal Hayes <17213165+marshalhayes@users.noreply.github.com> Date: Sun, 19 Oct 2025 11:12:49 -0500 Subject: [PATCH 5/6] Add .java as a supported file type, and explain why both main_class_path and project_path are included --- extension/src/dcp/types.ts | 4 ++-- extension/src/debugger/languages/java.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/extension/src/dcp/types.ts b/extension/src/dcp/types.ts index 27c135be109..9343773a4c0 100644 --- a/extension/src/dcp/types.ts +++ b/extension/src/dcp/types.ts @@ -40,8 +40,8 @@ export function isPythonLaunchConfiguration(obj: any): obj is PythonLaunchConfig export interface JavaLaunchConfiguration extends ExecutableLaunchConfiguration { type: "java"; - main_class_path?: string; - project_path?: string; + main_class_path?: string; // path to the Java program + project_path?: string; // leftover from 9.5 usage of project path } export function isJavaLaunchConfiguration(obj: any): obj is JavaLaunchConfiguration { diff --git a/extension/src/debugger/languages/java.ts b/extension/src/debugger/languages/java.ts index 19c27523795..d2f5ed429f5 100644 --- a/extension/src/debugger/languages/java.ts +++ b/extension/src/debugger/languages/java.ts @@ -7,6 +7,7 @@ export const javaDebuggerExtension: ResourceDebuggerExtension = { debugAdapter: 'java', extensionId: 'vscjava.vscode-java-pack', displayName: 'Java', + getSupportedFileTypes: () => ['.java'], getProjectFile: (launchConfig) => { if (isJavaLaunchConfiguration(launchConfig)) { const programPath = launchConfig.main_class_path || launchConfig.project_path; From 199138850373a4767d67ce04dbd1ce3b190209f6 Mon Sep 17 00:00:00 2001 From: Marshal Hayes <17213165+marshalhayes@users.noreply.github.com> Date: Sun, 19 Oct 2025 15:01:51 -0500 Subject: [PATCH 6/6] Expand upon Java support in extension README.md --- extension/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extension/README.md b/extension/README.md index 8e8d93ead21..b0a61bbdadd 100644 --- a/extension/README.md +++ b/extension/README.md @@ -50,6 +50,8 @@ To run and debug your Aspire application, add an entry to the workspace `launch. The debuggers property stores common debug configuration properties for different types of Aspire services. C#-based services have common debugging properties under `project`. Python-based services have their common properties under `python`. +Java-based services have their common properties under `java`. + There is also a special entry for the apphost (`apphost`). For example: ```json