From cc3a7add5e27d23f4df6fd8c8d6138dcf94fa56a Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Tue, 10 Oct 2017 19:10:33 -0400 Subject: [PATCH] [PT-#151762870] boot-java launch support for VSCode --- vscode-extensions/commons-vscode/src/index.ts | 4 +- .../commons-vscode/src/launch-util.ts | 47 ++++++++++--------- .../vscode-boot-java/lib/Main.ts | 14 +++++- .../vscode-boot-properties/lib/Main.ts | 2 +- vscode-extensions/vscode-bosh/lib/Main.ts | 2 +- .../vscode-concourse/lib/Main.ts | 2 +- .../vscode-manifest-yaml/lib/Main.ts | 2 +- 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/vscode-extensions/commons-vscode/src/index.ts b/vscode-extensions/commons-vscode/src/index.ts index 4b4e4858a..daebf3a56 100644 --- a/vscode-extensions/commons-vscode/src/index.ts +++ b/vscode-extensions/commons-vscode/src/index.ts @@ -1,3 +1,3 @@ -import {activate, ActivatorOptions} from './launch-util'; +import {activate, findJvmFile, ActivatorOptions} from './launch-util'; -export {activate, ActivatorOptions}; +export {activate, findJvmFile, ActivatorOptions}; diff --git a/vscode-extensions/commons-vscode/src/launch-util.ts b/vscode-extensions/commons-vscode/src/launch-util.ts index 315500148..70bba5317 100644 --- a/vscode-extensions/commons-vscode/src/launch-util.ts +++ b/vscode-extensions/commons-vscode/src/launch-util.ts @@ -29,8 +29,9 @@ export interface ActivatorOptions { TRACE?: boolean; extensionId: string; clientOptions: LanguageClientOptions; - fatJarFile: string; + launcher: (context: VSCode.ExtensionContext) => string; jvmHeap?: string; + classpath?: (context: VSCode.ExtensionContext) => string[]; } export function activate(options: ActivatorOptions, context: VSCode.ExtensionContext): Promise { @@ -40,7 +41,6 @@ export function activate(options: ActivatorOptions, context: VSCode.ExtensionCon return connectToLS(context, options); } else { let clientOptions = options.clientOptions; - let fatJarFile = Path.resolve(context.extensionPath, options.fatJarFile); var log_output = VSCode.window.createOutputChannel(options.extensionId + "-debug-log"); log("Activating '" + options.extensionId + "' extension"); @@ -57,7 +57,7 @@ export function activate(options: ActivatorOptions, context: VSCode.ExtensionCon } } - let javaExecutablePath = findJavaExecutable('java'); + let javaExecutablePath = findJvmFile('bin', correctBinname('java')); if (javaExecutablePath == null) { VSCode.window.showErrorMessage("Couldn't locate java in $JAVA_HOME or $PATH"); @@ -84,15 +84,25 @@ export function activate(options: ActivatorOptions, context: VSCode.ExtensionCon writer: socket }); }).listen(port, () => { - let options = { + let processLaunchoptions = { cwd: VSCode.workspace.rootPath }; let child: ChildProcess.ChildProcess; - let args = [ - '-Dserver.port=' + port, - '-jar', - fatJarFile, + const args = [ + '-Dserver.port=' + port ]; + if (options.classpath) { + const classpath = options.classpath(context); + if (classpath) { + args.push('-cp'); + args.push(classpath.join(':')); + } + } + const launcher = options.launcher(context); + if (launcher.endsWith('.jar')) { + args.push('-jar'); + } + args.push(options.launcher(context)); if (jvmHeap) { args.unshift("-Xmx"+jvmHeap); } @@ -102,7 +112,7 @@ export function activate(options: ActivatorOptions, context: VSCode.ExtensionCon log("CMD = " + javaExecutablePath + ' ' + args.join(' ')); // Start the child java process - child = ChildProcess.execFile(javaExecutablePath, args, options); + child = ChildProcess.execFile(javaExecutablePath, args, processLaunchoptions); child.stdout.on('data', (data) => { log("" + data); }); @@ -187,16 +197,14 @@ function isJava8(javaExecutablePath: string): Promise { }); } -function findJavaExecutable(binname: string) { - binname = correctBinname(binname); - +export function findJvmFile(folderPath: string, file: string): string { // First search each JAVA_HOME bin folder if (process.env['JAVA_HOME']) { let workspaces = process.env['JAVA_HOME'].split(Path.delimiter); for (let i = 0; i < workspaces.length; i++) { - let binpath = Path.join(workspaces[i], 'bin', binname); - if (FS.existsSync(binpath)) { - return binpath; + let filePath = Path.join(workspaces[i], folderPath, file); + if (FS.existsSync(filePath)) { + return filePath; } } } @@ -205,15 +213,12 @@ function findJavaExecutable(binname: string) { if (process.env['PATH']) { let pathparts = process.env['PATH'].split(Path.delimiter); for (let i = 0; i < pathparts.length; i++) { - let binpath = Path.join(pathparts[i], binname); - if (FS.existsSync(binpath)) { - return binpath; + let filePath = Path.join(pathparts[i], file); + if (FS.existsSync(filePath)) { + return filePath; } } } - - // Else return the binary name directly (this will likely always fail downstream) - return null; } function correctBinname(binname: string) { diff --git a/vscode-extensions/vscode-boot-java/lib/Main.ts b/vscode-extensions/vscode-boot-java/lib/Main.ts index 904e2eaf1..e82a0cf11 100644 --- a/vscode-extensions/vscode-boot-java/lib/Main.ts +++ b/vscode-extensions/vscode-boot-java/lib/Main.ts @@ -21,7 +21,19 @@ export function activate(context: VSCode.ExtensionContext) { DEBUG: false, CONNECT_TO_LS: false, extensionId: 'vscode-boot-java', - fatJarFile: 'jars/language-server.jar', + launcher: (context: VSCode.ExtensionContext) => 'org.springframework.boot.loader.JarLauncher', + classpath: (context: VSCode.ExtensionContext) => { + const classpath = [ + Path.resolve(context.extensionPath, 'jars/language-server.jar') + ]; + const toolsJar = commons.findJvmFile('lib', 'tools.jar'); + if (toolsJar) { + classpath.push(toolsJar); + } else { + VSCode.window.showWarningMessage('JAVA_HOME environment variable points either to JRE or JDK missing "lib/tools.jar" hence Boot Hints are unavailable'); + } + return classpath; + }, clientOptions: { documentSelector: ['java'], synchronize: { diff --git a/vscode-extensions/vscode-boot-properties/lib/Main.ts b/vscode-extensions/vscode-boot-properties/lib/Main.ts index cb9192413..4440809a0 100644 --- a/vscode-extensions/vscode-boot-properties/lib/Main.ts +++ b/vscode-extensions/vscode-boot-properties/lib/Main.ts @@ -18,7 +18,7 @@ export function activate(context: VSCode.ExtensionContext) { DEBUG: false, CONNECT_TO_LS: false, extensionId: 'vscode-boot-properties', - fatJarFile: 'jars/language-server.jar', + launcher: (context: VSCode.ExtensionContext) => Path.resolve(context.extensionPath, 'jars/language-server.jar'), clientOptions: { // HACK!!! documentSelector only takes string|string[] where string is language id, but DocumentFilter object is passed instead // Reasons: diff --git a/vscode-extensions/vscode-bosh/lib/Main.ts b/vscode-extensions/vscode-bosh/lib/Main.ts index 088954897..b17e76b2f 100644 --- a/vscode-extensions/vscode-bosh/lib/Main.ts +++ b/vscode-extensions/vscode-bosh/lib/Main.ts @@ -31,7 +31,7 @@ export function activate(context: VSCode.ExtensionContext) { DEBUG : false, CONNECT_TO_LS: false, extensionId: 'vscode-bosh', - fatJarFile: 'jars/language-server.jar', + launcher: (context: VSCode.ExtensionContext) => Path.resolve(context.extensionPath, 'jars/language-server.jar'), jvmHeap: "48m", clientOptions: { documentSelector: [ diff --git a/vscode-extensions/vscode-concourse/lib/Main.ts b/vscode-extensions/vscode-concourse/lib/Main.ts index 67b75429d..d027ac7b8 100644 --- a/vscode-extensions/vscode-concourse/lib/Main.ts +++ b/vscode-extensions/vscode-concourse/lib/Main.ts @@ -34,7 +34,7 @@ export function activate(context: VSCode.ExtensionContext) { DEBUG : false, CONNECT_TO_LS: false, extensionId: 'vscode-concourse', - fatJarFile: 'jars/language-server.jar', + launcher: (context: VSCode.ExtensionContext) => Path.resolve(context.extensionPath, 'jars/language-server.jar'), jvmHeap: "48m", clientOptions: { documentSelector: [ PIPELINE_LANGUAGE_ID, TASK_LANGUAGE_ID ] diff --git a/vscode-extensions/vscode-manifest-yaml/lib/Main.ts b/vscode-extensions/vscode-manifest-yaml/lib/Main.ts index f5837d707..e2a28c4f5 100644 --- a/vscode-extensions/vscode-manifest-yaml/lib/Main.ts +++ b/vscode-extensions/vscode-manifest-yaml/lib/Main.ts @@ -31,7 +31,7 @@ export function activate(context: VSCode.ExtensionContext) { DEBUG : false, CONNECT_TO_LS: false, extensionId: 'vscode-manifest-yaml', - fatJarFile: 'jars/language-server.jar', + launcher: (context: VSCode.ExtensionContext) => Path.resolve(context.extensionPath, 'jars/language-server.jar'), jvmHeap: '64m', clientOptions: { documentSelector: ["manifest-yaml"]