diff --git a/vscode-extensions/commons-vscode/.vscode/tasks.json b/vscode-extensions/commons-vscode/.vscode/tasks.json index 49501fa1f..5845fa343 100644 --- a/vscode-extensions/commons-vscode/.vscode/tasks.json +++ b/vscode-extensions/commons-vscode/.vscode/tasks.json @@ -6,7 +6,7 @@ "showOutput": "always", "tasks": [ { - "taskName": "build", + "taskName": "compile", "isBuildCommand": true }, { diff --git a/vscode-extensions/commons-vscode/package.json b/vscode-extensions/commons-vscode/package.json index 2a70aa375..51b3a6e0b 100644 --- a/vscode-extensions/commons-vscode/package.json +++ b/vscode-extensions/commons-vscode/package.json @@ -25,6 +25,7 @@ "prepack": "node ./node_modules/vscode/bin/install && tsc -p ./" }, "dependencies": { + "@pivotal-tools/jvm-launch-utils": "0.0.9", "portfinder": "^0.4.0" }, "devDependencies": { diff --git a/vscode-extensions/commons-vscode/src/index.ts b/vscode-extensions/commons-vscode/src/index.ts index f2676f6f3..d3d3748c3 100644 --- a/vscode-extensions/commons-vscode/src/index.ts +++ b/vscode-extensions/commons-vscode/src/index.ts @@ -1,4 +1,4 @@ import {activate, ActivatorOptions} from './launch-util'; -import {JVM} from './jvm-util'; +import {JVM} from '@pivotal-tools/jvm-launch-utils'; export {activate, JVM, ActivatorOptions}; diff --git a/vscode-extensions/commons-vscode/src/jvm-util.ts b/vscode-extensions/commons-vscode/src/jvm-util.ts deleted file mode 100644 index 4c4736ad2..000000000 --- a/vscode-extensions/commons-vscode/src/jvm-util.ts +++ /dev/null @@ -1,251 +0,0 @@ -import * as FS from 'fs'; -import * as Path from 'path'; -import * as ChildProcess from 'child_process'; -import { basename } from 'path'; - -'use strict'; - -export interface JVM { - /** - * 8 = Java 1.8.x, 9 = Java 9.x, etc - */ - getMajorVersion() : number - - /** - * Path to the Java executable - */ - getJavaExecutable() : string - - /** - * Path to the corresponding 'java home' for the executable. - */ - getJavaHome() : string - - /** - * Detect whether this JVM is a JDK - */ - isJdk() : boolean - - /** - * Find tools.jar for this JVM. - * - * Note that if the JVM is a JRE; or a Java 9 or above JDK; - * then this will return null. - */ - getToolsJar() : string | null -} - -/** - * Find a JVM by looking in the JAVA_HOME and PATH environment variables. - * - * Optionally, a specific javaHome can be passed in. This shortcuts the - * search logic and uses that javaHome as is. - * - * The returned JVM may or may not be a JDK. Methods are provided to obtain corresponding - * toolsjar and to check whether the JVM is a JDK. - */ -export function findJvm(javaHome?: string) : Promise { - let javaExe = findJavaExe(javaHome); - if (javaExe) { - return getJavaInfo(javaExe).then(javaProps => new JVMImpl( - javaProps.get("java.home"), - javaExe, - getMajorVersion(javaProps) - )); - } - return Promise.resolve(null); -} - -/** - * Like findJvm, but additionally, if the found JVM is not a JDK tries to - * find a companion JDK that may be installed alongside it. - */ -export function findJdk(javaHome?: string) : Promise { - return findJvm(javaHome).then(jvm => { - if (!jvm.isJdk()) { - console.log("found jvm is not a JDK"); - - //Try to find a 'sibling' JDK. - //Mainly for windows where it is common to have side-by-side install of a jre and jdk, instead of a - //nested jre install inside of a jdk. - - //E.g. - //C:\ProgramFiles\Java\jdk1.8.0_161 - //C:\ProgramFiles\Java\jre1.8.0_161 - - let javaExe = jvm.getJavaExecutable(); - console.log("javaExe = ", javaExe); - // javaExe example: C:\ProgramFiles\Java\jre1.8.0_161\bin\java.exe - let jhome = jvm.getJavaHome(); - console.log("jhome = ", jhome); - let basename : string = Path.basename(jhome); - console.log("basename = ", basename); - let altBasename : string = basename.replace("jre", "jdk"); - console.log("altBasename = ", altBasename); - if (altBasename!==basename) { - let altHome = Path.join(Path.dirname(jhome), altBasename); - console.log("altHome = ", altHome); - if (FS.existsSync(altHome)) { - let altExe = Path.resolve(altHome, "bin", correctBinname("java")); - console.log("altExe = ", altExe); - return new JVMImpl(altHome, altExe, jvm.getMajorVersion()); - } - } - } - return jvm; - }); -} - -/** - * Find a 'java' exe by looking in the JAVA_HOME and PATH environment variables. - *

- * Optionally, a specific javaHome can be passed in. This shortcuts the - * search logic and uses that javaHome as is, not looking anywhere else. - */ -function findJavaExe(javaHome?: string) : string | null { - //Try java home first - if (!javaHome) { - javaHome = process.env["JAVA_HOME"]; - } - if (javaHome) { - //Resolve symlinks - javaHome = FS.realpathSync(javaHome); - } - let binName = correctBinname("java"); - if (javaHome) { - let javaExe = Path.resolve(javaHome, "bin", binName); - if (FS.existsSync(javaExe)) { - return javaExe; - } - } - - for (var searchPath of process.env['PATH'].split(Path.delimiter)) { - let javaExe = Path.resolve(searchPath, binName); - if (FS.existsSync(javaExe)) { - //Resolve symlinks - return FS.realpathSync(javaExe); - } - } - return null; -} - -type Getter = () => T; - -function memoize(getter : Getter) : Getter { - let computed : boolean = false; - let value : T | null = null; - return () => { - if (!computed) { - value = getter(); - computed = true; - } - return value; - }; -} - -const TOOLS_JAR_PATHS : string[][] = [ - ["lib", "tools.jar"], - ["..", "lib", "tools.jar"] -]; - -class JVMImpl implements JVM { - javaHome : string - javaExe : string - version : number - toolsJar: () => string | null; - constructor(javaHome : string, javaExe : string, version : number) { - this.javaHome = javaHome; - this.javaExe = javaExe; - this.version = version; - this.toolsJar = memoize(() => this.findToolsJar()); - } - - getJavaHome() : string { - return this.javaHome; - } - - findToolsJar() : string | null { - if (this.version>=9) { - return null; - } - let javaHome = this.getJavaHome(); - for (var tjp of TOOLS_JAR_PATHS) { - let toolsJar = Path.resolve(javaHome, ...tjp); - if (FS.existsSync(toolsJar)) { - return toolsJar; - } - } - //Not found. - return null; - } - - getMajorVersion() { - return this.version; - } - getJavaExecutable(): string { - return this.javaExe; - } - isJdk(): boolean { - //Consider memoizing? - if (this.version<9) { - return this.getToolsJar()!=null; - } else { - return FS.existsSync(Path.resolve(this.getJavaHome(), "jmods", "jdk.management.jmod")); - } - } - getToolsJar(): string { - return this.toolsJar(); - } -} - -function getJavaInfo(javaExe : string) : Promise> { - //console.log("Fetching java properties for "+javaExe); - return new Promise((resolve, reject) => { - ChildProcess.execFile(javaExe, ['-XshowSettings:properties'], {}, (error, stdout, stderr) => { - let lines = stderr.split(/\r?\n/); - let propNames = [ 'java.version', 'java.home' ]; - let props = new Map(); - for (var l of lines) { - //console.log("Line: "+l); - for (var p of propNames) { - let offset = l.indexOf(p); - if (offset>=0) { - //Make sure it looks like a proper 'assignment' to the property and not an - // accidental match. - //console.log("Propname found: "+p); - let assign = " " +p + " = "; - offset = l.indexOf(assign); - if (offset>=0) { - //console.log("Assignment found: "+p); - offset = offset + assign.length; - let value = l.substring(offset); - //console.log("value = "+value); - props.set(p, value); - if (props.size >= propNames.length) { - //We found everything we care about, so we can stop now. - //console.log("result = ", props); - return resolve(props); - } - } - } - } - } - //Not found everything we expected. - return reject("Unexpected output from `java -XshowSettings:properties`. Didn't find all expected properties: "+propNames); - }); - }); -} - -function getMajorVersion(javaProperties : Map) : number { - let versionString = javaProperties.get('java.version'); - let pieces = versionString.split("."); - let major = parseInt(pieces[0]); - return major==1 ? parseInt(pieces[1]) : major; -} - -function correctBinname(binname: string) { - if (process.platform === 'win32') - return binname + '.exe'; - else - return binname; -} \ No newline at end of file diff --git a/vscode-extensions/commons-vscode/src/launch-util.ts b/vscode-extensions/commons-vscode/src/launch-util.ts index c0cfdfb0a..9b0df7534 100644 --- a/vscode-extensions/commons-vscode/src/launch-util.ts +++ b/vscode-extensions/commons-vscode/src/launch-util.ts @@ -18,7 +18,7 @@ import {WorkspaceEdit, Position} from 'vscode-languageserver-types'; import {HighlightService, HighlightParams} from './highlight-service'; import { log } from 'util'; import { tmpdir } from 'os'; -import { JVM, findJvm, findJdk } from './jvm-util'; +import { JVM, findJvm, findJdk } from '@pivotal-tools/jvm-launch-utils'; let p2c = P2C.createConverter();