From e718b81d40b0a358175a40f87c9932f9ef211b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=A4der?= Date: Wed, 17 Sep 2025 10:18:39 +0200 Subject: [PATCH 1/4] Add command to add JDK to settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Mäder --- package.json | 5 +++++ package.nls.json | 3 ++- src/extension.ts | 2 ++ src/javaRuntimes.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/javaRuntimes.ts diff --git a/package.json b/package.json index 5238c1c1c3..0f8662066d 100644 --- a/package.json +++ b/package.json @@ -1794,6 +1794,11 @@ "category": "Java", "title": "Open Java Dashboard", "icon": "$(dashboard)" + }, + { + "command": "java.runtimes.add", + "title": "%java.runtimes.add%", + "category": "Java" } ], "keybindings": [ diff --git a/package.nls.json b/package.nls.json index 33307fcaae..2ac32d40a2 100644 --- a/package.nls.json +++ b/package.nls.json @@ -29,5 +29,6 @@ "java.action.filesExplorerPasteAction": "Paste Clipboard Text Into a File", "java.action.doCleanup": "Performs Cleanup Actions", "java.change.searchScope": "Change Search Scope", - "java.action.showExtendedOutline": "Open Extended Outline" + "java.action.showExtendedOutline": "Open Extended Outline", + "java.runtimes.add": "Add Java Runtime" } diff --git a/src/extension.ts b/src/extension.ts index c12cf7f15e..f3a7f5c735 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -44,6 +44,7 @@ import { StandardLanguageClient } from './standardLanguageClient'; import { SyntaxLanguageClient } from './syntaxLanguageClient'; import { Telemetry } from './telemetry'; import { cleanJavaLSConfiguration, convertToGlob, deleteClientLog, deleteDirectory, ensureExists, getBuildFilePatterns, getExclusionGlob, getInclusionPatternsFromNegatedExclusion, getJavaConfig, getJavaConfiguration, getVersion, hasBuildToolConflicts, resolveActualCause } from './utils'; +import { JavaRuntimes } from './javaRuntimes'; const syntaxClient: SyntaxLanguageClient = new SyntaxLanguageClient(); const standardClient: StandardLanguageClient = new StandardLanguageClient(); @@ -136,6 +137,7 @@ export async function activate(context: ExtensionContext): Promise Dashboard.initialize(context); await loadSupportedJreNames(context); + await JavaRuntimes.initialize(context); context.subscriptions.push(commands.registerCommand(Commands.FILESEXPLORER_ONPASTE, async () => { const originalClipboard = await env.clipboard.readText(); // Hack in order to get path to selected folder if applicable (see https://github.com/microsoft/vscode/issues/3553#issuecomment-1098562676) diff --git a/src/javaRuntimes.ts b/src/javaRuntimes.ts new file mode 100644 index 0000000000..9a7947e036 --- /dev/null +++ b/src/javaRuntimes.ts @@ -0,0 +1,42 @@ +import { getRuntime } from "jdk-utils"; +import * as vscode from "vscode"; +import { getSupportedJreNames } from "./jdkUtils"; + + +export namespace JavaRuntimes { + export async function initialize(context: vscode.ExtensionContext): Promise { + context.subscriptions.push(vscode.commands.registerCommand('java.runtimes.add', async () => { + const directory = await vscode.window.showOpenDialog({ + canSelectFiles: false, + canSelectFolders: true, + canSelectMany: false, + title: 'Select JDK Directory', + }); + if (directory) { + const runtime = await getRuntime(directory[0].fsPath); + if (runtime) { + const config = vscode.workspace.getConfiguration('java.configuration').get('runtimes'); + if (Array.isArray(config)) { + if (config.some(r => r.path === directory[0].fsPath)) { + vscode.window.showErrorMessage(`JDK Directory ${directory[0].fsPath} already configured`); + } else { + const name = await vscode.window.showQuickPick(getSupportedJreNames(), { + title: 'Select Java Runtime', + }); + if (name) { + config.push({ + name: name, + path: directory[0].fsPath, + }); + } + vscode.workspace.getConfiguration('java.configuration').update('runtimes', config, vscode.ConfigurationTarget.Global); + vscode.window.showInformationMessage(`JDK Directory ${directory[0].fsPath} added`); + } + } + } else { + vscode.window.showErrorMessage(`Invalid JDK Directory ${directory[0].fsPath}`); + } + } + })); + } +} \ No newline at end of file From c54c6ec46ac3985cc5ff6505850f49ba6d05ac26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=A4der?= Date: Wed, 17 Sep 2025 16:57:33 +0200 Subject: [PATCH 2/4] Add java.runtimes.add command to test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Mäder --- test/standard-mode-suite/extension.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/standard-mode-suite/extension.test.ts b/test/standard-mode-suite/extension.test.ts index 807c11ed8b..2b381e7456 100644 --- a/test/standard-mode-suite/extension.test.ts +++ b/test/standard-mode-suite/extension.test.ts @@ -128,7 +128,8 @@ suite('Java Language Extension - Standard', () => { Commands.FILESEXPLORER_ONPASTE, Commands.RESOLVE_PASTED_TEXT, Commands.CHANGE_JAVA_SEARCH_SCOPE, - Commands.OPEN_JAVA_DASHBOARD + Commands.OPEN_JAVA_DASHBOARD, + "java.runtimes.add" ].sort(); const foundJavaCommands = commands.filter((value) => { return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.'); From d557c1e277ac2cdfeb742c98fc970502c04cae03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=A4der?= Date: Wed, 17 Sep 2025 17:13:20 +0200 Subject: [PATCH 3/4] Add new command to lighweght test suite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Mäder --- test/lightweight-mode-suite/extension.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/lightweight-mode-suite/extension.test.ts b/test/lightweight-mode-suite/extension.test.ts index 924c34919b..db01bc15bd 100644 --- a/test/lightweight-mode-suite/extension.test.ts +++ b/test/lightweight-mode-suite/extension.test.ts @@ -29,7 +29,8 @@ suite('Java Language Extension - LightWeight', () => { Commands.RESTART_LANGUAGE_SERVER, Commands.FILESEXPLORER_ONPASTE, Commands.CHANGE_JAVA_SEARCH_SCOPE, - Commands.OPEN_JAVA_DASHBOARD + Commands.OPEN_JAVA_DASHBOARD, + "java.runtimes.add" ].sort(); const foundJavaCommands = commands.filter((value) => { return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.'); From cbe1b37466dcec7cbaa1066648da654ed2a4bdc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=A4der?= Date: Fri, 7 Nov 2025 13:37:11 +0100 Subject: [PATCH 4/4] Addressed review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Mäder --- package.json | 3 -- src/commands.ts | 5 +++ src/javaRuntimes.ts | 39 ++++++++++++++----- test/lightweight-mode-suite/extension.test.ts | 2 +- test/standard-mode-suite/extension.test.ts | 2 +- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 0f8662066d..120a543487 100644 --- a/package.json +++ b/package.json @@ -930,9 +930,6 @@ "name": { "type": "string", "enum": [ - "J2SE-1.5", - "JavaSE-1.6", - "JavaSE-1.7", "JavaSE-1.8", "JavaSE-9", "JavaSE-10", diff --git a/src/commands.ts b/src/commands.ts index 11048b3f5f..be87ca4317 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -380,6 +380,11 @@ export namespace Commands { * Open Java Dashboard */ export const OPEN_JAVA_DASHBOARD = 'java.dashboard.open'; + + /** + * Add Java Runtime + */ + export const ADD_JAVA_RUNTIME = 'java.runtimes.add'; } /** diff --git a/src/javaRuntimes.ts b/src/javaRuntimes.ts index 9a7947e036..c55d18d4da 100644 --- a/src/javaRuntimes.ts +++ b/src/javaRuntimes.ts @@ -1,26 +1,45 @@ -import { getRuntime } from "jdk-utils"; +import { getRuntime, IJavaRuntime } from "jdk-utils"; import * as vscode from "vscode"; import { getSupportedJreNames } from "./jdkUtils"; +import { Commands } from "./commands"; +import * as path from "path"; export namespace JavaRuntimes { + function compatible(runtime: IJavaRuntime, jreName: string): boolean { + if (!runtime.version) { + return true; + } + const majorVersion = runtime.version.major; + if (majorVersion === 8) { + return jreName === 'JavaSE-1.8'; + } + const versionStrings = /[0-9]+/g.exec(jreName); + if (versionStrings && versionStrings.length > 0) { + return majorVersion >= parseInt(versionStrings[0]); + } + return false; + } + export async function initialize(context: vscode.ExtensionContext): Promise { - context.subscriptions.push(vscode.commands.registerCommand('java.runtimes.add', async () => { + context.subscriptions.push(vscode.commands.registerCommand(Commands.ADD_JAVA_RUNTIME, async () => { + const lastSelectedDirectory: vscode.Uri | undefined = context.workspaceState.get('java.runtimes.lastSelectedDirectory'); const directory = await vscode.window.showOpenDialog({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, title: 'Select JDK Directory', + defaultUri: lastSelectedDirectory, }); if (directory) { - const runtime = await getRuntime(directory[0].fsPath); + context.workspaceState.update('java.runtimes.lastSelectedDirectory', vscode.Uri.file(path.dirname(directory[0].fsPath))); + const runtime = await getRuntime(directory[0].fsPath, {withVersion: true}); if (runtime) { const config = vscode.workspace.getConfiguration('java.configuration').get('runtimes'); if (Array.isArray(config)) { - if (config.some(r => r.path === directory[0].fsPath)) { - vscode.window.showErrorMessage(`JDK Directory ${directory[0].fsPath} already configured`); - } else { - const name = await vscode.window.showQuickPick(getSupportedJreNames(), { + const candidates = getSupportedJreNames().filter(name => !config.some(r => r.name === name) && compatible(runtime, name)); + if (candidates.length > 0) { + const name = await vscode.window.showQuickPick(candidates, { title: 'Select Java Runtime', }); if (name) { @@ -28,9 +47,11 @@ export namespace JavaRuntimes { name: name, path: directory[0].fsPath, }); + vscode.workspace.getConfiguration('java.configuration').update('runtimes', config, vscode.ConfigurationTarget.Global); + vscode.window.showInformationMessage(`JDK Directory ${directory[0].fsPath} added`); } - vscode.workspace.getConfiguration('java.configuration').update('runtimes', config, vscode.ConfigurationTarget.Global); - vscode.window.showInformationMessage(`JDK Directory ${directory[0].fsPath} added`); + } else { + vscode.window.showErrorMessage('No compatible environment available'); } } } else { diff --git a/test/lightweight-mode-suite/extension.test.ts b/test/lightweight-mode-suite/extension.test.ts index db01bc15bd..1c3f8e08ac 100644 --- a/test/lightweight-mode-suite/extension.test.ts +++ b/test/lightweight-mode-suite/extension.test.ts @@ -30,7 +30,7 @@ suite('Java Language Extension - LightWeight', () => { Commands.FILESEXPLORER_ONPASTE, Commands.CHANGE_JAVA_SEARCH_SCOPE, Commands.OPEN_JAVA_DASHBOARD, - "java.runtimes.add" + Commands.ADD_JAVA_RUNTIME ].sort(); const foundJavaCommands = commands.filter((value) => { return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.'); diff --git a/test/standard-mode-suite/extension.test.ts b/test/standard-mode-suite/extension.test.ts index 2b381e7456..a1237467b1 100644 --- a/test/standard-mode-suite/extension.test.ts +++ b/test/standard-mode-suite/extension.test.ts @@ -129,7 +129,7 @@ suite('Java Language Extension - Standard', () => { Commands.RESOLVE_PASTED_TEXT, Commands.CHANGE_JAVA_SEARCH_SCOPE, Commands.OPEN_JAVA_DASHBOARD, - "java.runtimes.add" + Commands.ADD_JAVA_RUNTIME ].sort(); const foundJavaCommands = commands.filter((value) => { return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');