From 72f49480d693df8959ea17be95cfc6c3cce6f5b5 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Tue, 27 Feb 2018 16:44:33 -0800 Subject: [PATCH] Integrate shared jvm-utils into atom-extensions --- atom-extensions/atom-bosh/lib/main.js | 2 +- atom-extensions/atom-bosh/package.json | 2 +- .../atom-cf-manifest-yaml/package.json | 2 +- .../lib/java-process-language-client.js | 132 +++++++----------- atom-extensions/atom-commons/package.json | 9 +- atom-extensions/atom-concourse/build.sh | 9 ++ atom-extensions/atom-concourse/lib/main.js | 2 +- atom-extensions/atom-concourse/package.json | 2 +- .../atom-concourse/properties.json | 2 +- .../atom-spring-boot/DEVELOPER-NOTES.md | 4 +- atom-extensions/atom-spring-boot/build.sh | 9 ++ atom-extensions/atom-spring-boot/lib/main.js | 51 ++++--- atom-extensions/atom-spring-boot/package.json | 3 +- 13 files changed, 111 insertions(+), 118 deletions(-) create mode 100755 atom-extensions/atom-concourse/build.sh create mode 100755 atom-extensions/atom-spring-boot/build.sh diff --git a/atom-extensions/atom-bosh/lib/main.js b/atom-extensions/atom-bosh/lib/main.js index 96dee5e07..bff29e2b9 100644 --- a/atom-extensions/atom-bosh/lib/main.js +++ b/atom-extensions/atom-bosh/lib/main.js @@ -37,7 +37,7 @@ class BoshYamlClient extends JavaProcessLanguageClient { super.activate(); } - launchVmArgs(version) { + launchVmArgs(jvm) { return Promise.resolve([ '-Dorg.slf4j.simpleLogger.logFile=bosh-yaml.log', '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug', diff --git a/atom-extensions/atom-bosh/package.json b/atom-extensions/atom-bosh/package.json index b249702e5..67eed2b1f 100644 --- a/atom-extensions/atom-bosh/package.json +++ b/atom-extensions/atom-bosh/package.json @@ -19,7 +19,7 @@ "dependencies": { "atom-package-deps": "^4.6.0", "download": "^6.2.5", - "pivotal-atom-languageclient-commons": "0.0.19" + "@pivotal-tools/atom-languageclient-commons": "0.0.1" }, "configSchema": { "bosh": { diff --git a/atom-extensions/atom-cf-manifest-yaml/package.json b/atom-extensions/atom-cf-manifest-yaml/package.json index f5643a71e..4025e23b8 100644 --- a/atom-extensions/atom-cf-manifest-yaml/package.json +++ b/atom-extensions/atom-cf-manifest-yaml/package.json @@ -19,7 +19,7 @@ "dependencies": { "atom-package-deps": "^4.6.0", "download": "^6.2.5", - "pivotal-atom-languageclient-commons": "0.0.19" + "@pivotal-tools/atom-languageclient-commons": "0.0.1" }, "devDependencies": { "coffeelint": "^1.10.1" diff --git a/atom-extensions/atom-commons/lib/java-process-language-client.js b/atom-extensions/atom-commons/lib/java-process-language-client.js index 4c00a6b36..2714aaf74 100644 --- a/atom-extensions/atom-commons/lib/java-process-language-client.js +++ b/atom-extensions/atom-commons/lib/java-process-language-client.js @@ -10,6 +10,7 @@ const {AutoLanguageClient, DownloadFile} = require('atom-languageclient'); const { Disposable } = require('atom'); import { StsAdapter } from './sts-adapter'; +import {findJdk, findJvm} from '@pivotal-tools/jvm-launch-utils'; export class JavaProcessLanguageClient extends AutoLanguageClient { @@ -23,6 +24,25 @@ export class JavaProcessLanguageClient extends AutoLanguageClient { this.serverLauncherJar = serverLauncherJar; } + getServerJar() { + return path.resolve(this.serverHome, this.serverLauncherJar); + } + + showErrorMessage(detail, desc) { + const notification = atom.notifications.addError('Cannot start Language Server', { + dismissable: true, + detail: detail, + description: desc, + buttons: [{ + text: 'OK', + onDidClick: () => { + notification.dismiss() + }, + }] + }); + return Promise.reject(new Error(detail)); + } + getInitializeParams(projectPath, process) { const initParams = super.getInitializeParams(projectPath, process); initParams.capabilities = { @@ -55,7 +75,6 @@ export class JavaProcessLanguageClient extends AutoLanguageClient { this.server.listen(port, 'localhost', () => { this.launchProcess(port).then(p => childProcess = p); }); - }); }); } @@ -84,34 +103,43 @@ export class JavaProcessLanguageClient extends AutoLanguageClient { server.connection._onNotification({method: 'sts/highlight'}, params => stsAdapter.onHighlight(params)); } + preferJdk() { + return false; + } + + findJvm() { + return this.preferJdk() ? findJdk() : findJvm(); + } launchProcess(port) { - const command = this.findJavaFile('bin', this.correctBinname('java')); - - return this.javaVesrion(command).then(version => { - if (version) { - return this.launchVmArgs(version).then(args => { - args.push(`-Dserver.port=${port}`); - return this.getOrInstallLauncher().then(launcher => this.doLaunchProcess(command, launcher, port, args)); - }); - } else { - this.logger.error('Java executable is not Java 8 or higher'); - const notification = atom.notifications.addError('Cannot start Language Server', { - dismissable: true, - detail: 'No compatible Java Runtime Environment found', - description: 'The Java Runtime Environment is either below version "1.8" or is missing from the system', - buttons: [{ - text: 'OK', - onDidClick: () => { - notification.dismiss() - }, - }], - }); + return this.findJvm() + .catch(error => { + return this.showErrorMessage("Error trying to find JVM", ""+error); + }) + .then(jvm => { + if (!jvm) { + return this.showErrorMessage("Couldn't locate java in $JAVA_HOME or $PATH"); } + let version = jvm.getMajorVersion(); + if (version<8) { + return this.showErrorMessage( + 'No compatible Java Runtime Environment found', + 'The Java Runtime Environment is either below version "1.8" or is missing from the system' + ); + } + return this.launchVmArgs(jvm).then(args => { + args.push(`-Dserver.port=${port}`); + return this.doLaunchProcess( + jvm.getJavaExecutable(), + this.getOrInstallLauncher(), + port, + args + ); + }); }); } - launchVmArgs(version) { + launchVmArgs(jvm) { return Promise.resolve([]); } @@ -131,20 +159,17 @@ export class JavaProcessLanguageClient extends AutoLanguageClient { } getOrInstallLauncher() { - const fullLauncherJar = path.join(this.serverHome, this.serverLauncherJar); - return this.fileExists(fullLauncherJar).then(doesExist => - doesExist ? fullLauncherJar : this.installServer().then(() => fullLauncherJar) - ); + return this.getServerJar(); } installServer () { - const localFileName = path.join(this.serverHome, this.serverLauncherJar); + const localFileName = this.getServerJar(); this.logger.log(`Downloading ${this.serverDownloadUrl} to ${localFileName}`); return this.fileExists(this.serverHome) .then(doesExist => { if (!doesExist) fs.mkdir(this.serverHome) }) .then(() => this.remoteFileSize(this.serverDownloadUrl)) .then((size) => DownloadFile(this.serverDownloadUrl, localFileName, (bytesDone, percent) => this.handleDownlaodPercentChange(bytesDone, size, percent), size)) - .then(() => this.fileExists(path.join(this.serverHome, this.serverLauncherJar))) + .then(() => this.fileExists(this.getServerJar())) .then(doesExist => { if (!doesExist) throw Error(`Failed to install the ${this.getServerName()} language server`) }) .then(() => this.handleServerInstalled()) .then(() => Promise.resolve(true)); @@ -182,55 +207,6 @@ export class JavaProcessLanguageClient extends AutoLanguageClient { }) } - findJavaFile(folders, file) { - - // First search each JAVA_HOME folder - if (process.env['JAVA_HOME']) { - let workspaces = process.env['JAVA_HOME'].split(path.delimiter); - for (let i = 0; i < workspaces.length; i++) { - let filepath = path.join(workspaces[i], folders, file); - if (fs.existsSync(filepath)) { - return filepath; - } - } - } - - // Then search PATH parts - if (process.env['PATH']) { - let pathparts = process.env['PATH'].split(path.delimiter); - for (let i = 0; i < pathparts.length; i++) { - 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; - } - - correctBinname(binname) { - if (process.platform === 'win32') - return binname + '.exe'; - else - return binname; - } - - javaVesrion(javaExecutablePath) { - return new Promise((resolve, reject) => { - cp.execFile(javaExecutablePath, ['-version'], {}, (error, stdout, stderr) => { - if (stderr.indexOf('1.8') >= 0) { - resolve(8); - } else if (stderr.indexOf('java version "9') >= 0) { - resolve(9); - } else { - resolve(0); - } - }); - }); - } - // Late wire-up of listeners after initialize method has been sent postInitialization(server) { server.disposable.add(new Disposable(() => { diff --git a/atom-extensions/atom-commons/package.json b/atom-extensions/atom-commons/package.json index 3526d0b1d..5bd0f110b 100644 --- a/atom-extensions/atom-commons/package.json +++ b/atom-extensions/atom-commons/package.json @@ -1,6 +1,6 @@ { - "name": "pivotal-atom-languageclient-commons", - "version": "0.0.19", + "name": "@pivotal-tools/atom-languageclient-commons", + "version": "0.0.1", "description": "Atom language client commons for STS4 language servers", "repository": "https://github.com/spring-projects/sts4", "license": "MIT", @@ -8,11 +8,12 @@ "atom": ">=1.17.0" }, "dependencies": { + "@pivotal-tools/jvm-launch-utils": "0.0.9", "atom-languageclient": "0.8.0", "decompress": "^4.2.0", "portfinder": "^1.0.13", - "remote-file-size": "^3.0.3", - "postinstall-build": "5.0.1" + "postinstall-build": "5.0.1", + "remote-file-size": "^3.0.3" }, "main": "./build/lib/index", "files": [ diff --git a/atom-extensions/atom-concourse/build.sh b/atom-extensions/atom-concourse/build.sh new file mode 100755 index 000000000..725ee72fa --- /dev/null +++ b/atom-extensions/atom-concourse/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +set -x +workdir=`pwd` +cd ../atom-commons +npm install +cd $workdir +npm install +apm link . diff --git a/atom-extensions/atom-concourse/lib/main.js b/atom-extensions/atom-concourse/lib/main.js index 6683de72c..ae861aa80 100644 --- a/atom-extensions/atom-concourse/lib/main.js +++ b/atom-extensions/atom-concourse/lib/main.js @@ -33,7 +33,7 @@ class ConcourseCiYamlClient extends JavaProcessLanguageClient { super.activate(); } - launchVmArgs(version) { + launchVmArgs(jvm) { return Promise.resolve([ '-Dorg.slf4j.simpleLogger.logFile=concourse-ci-yaml.log', '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug', diff --git a/atom-extensions/atom-concourse/package.json b/atom-extensions/atom-concourse/package.json index a7ca2876b..581cca277 100644 --- a/atom-extensions/atom-concourse/package.json +++ b/atom-extensions/atom-concourse/package.json @@ -19,7 +19,7 @@ "dependencies": { "atom-package-deps": "^4.6.0", "download": "^6.2.5", - "pivotal-atom-languageclient-commons": "0.0.19" + "@pivotal-tools/atom-languageclient-commons": "0.0.1" }, "devDependencies": { "coffeelint": "^1.10.1" diff --git a/atom-extensions/atom-concourse/properties.json b/atom-extensions/atom-concourse/properties.json index d22252060..bbf65bc61 100644 --- a/atom-extensions/atom-concourse/properties.json +++ b/atom-extensions/atom-concourse/properties.json @@ -1,3 +1,3 @@ { - "jarUrl": "https://s3-us-west-1.amazonaws.com/s3-test.spring.io/sts4/fatjars/snapshots/concourse-language-server-0.0.10-201711061741.jar" + "jarUrl": "https://s3-us-west-1.amazonaws.com/s3-test.spring.io/sts4/fatjars/snapshots/concourse-language-server-0.1.5-201802272051.jar" } diff --git a/atom-extensions/atom-spring-boot/DEVELOPER-NOTES.md b/atom-extensions/atom-spring-boot/DEVELOPER-NOTES.md index 12bf86ac7..283a8596f 100644 --- a/atom-extensions/atom-spring-boot/DEVELOPER-NOTES.md +++ b/atom-extensions/atom-spring-boot/DEVELOPER-NOTES.md @@ -35,9 +35,9 @@ Open Atom or execute `Refresh Window` in the opened instance (Packages -> Comman **Client Side Debugging**: Open Atom's `Developer Tools` view - View -> Developer -> Toggle Developer Tools -**Server Side Debugging**: Change `launchVmArgs(version)` implementation in `lib/main.js` to be: +**Server Side Debugging**: Change `launchVmArgs(jvm)` implementation in `lib/main.js` to be: ``` - launchVmArgs(version) { + launchVmArgs(jvm) { return Promise.resolve([ '-Xdebug', '-agentlib:jdwp=transport=dt_socket,server=y,address=7999,suspend=n', diff --git a/atom-extensions/atom-spring-boot/build.sh b/atom-extensions/atom-spring-boot/build.sh new file mode 100755 index 000000000..725ee72fa --- /dev/null +++ b/atom-extensions/atom-spring-boot/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +set -x +workdir=`pwd` +cd ../atom-commons +npm install +cd $workdir +npm install +apm link . diff --git a/atom-extensions/atom-spring-boot/lib/main.js b/atom-extensions/atom-spring-boot/lib/main.js index be9e2527d..5a5b69355 100644 --- a/atom-extensions/atom-spring-boot/lib/main.js +++ b/atom-extensions/atom-spring-boot/lib/main.js @@ -47,35 +47,32 @@ class SpringBootLanguageClient extends JavaProcessLanguageClient { } getOrInstallLauncher() { - return Promise.resolve('org.springframework.boot.loader.JarLauncher'); + return 'org.springframework.boot.loader.JarLauncher'; } - launchVmArgs(version) { - return super.getOrInstallLauncher().then(lsJar => { - const toolsJar = this.findJavaFile('lib', 'tools.jar'); - if (version < 9 && !toolsJar) { - // Notify the user that tool.jar is not found - const notification = atom.notifications.addWarning(`"Boot-Java" Package Functionality Limited`, { - dismissable: true, - detail: 'No tools.jar found', - description: 'JAVA_HOME environment variable points either to JRE or JDK missing "lib/tools.jar" hence Boot Hints are unavailable', - buttons: [{ - text: 'OK', - onDidClick: () => { - notification.dismiss() - }, - }], - }); - } - return [ - // '-Xdebug', - // '-agentlib:jdwp=transport=dt_socket,server=y,address=7999,suspend=n', - '-Dorg.slf4j.simpleLogger.logFile=boot-java.log', - '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug', - '-cp', - `${toolsJar ? `${toolsJar}${path.delimiter}` : ''}${lsJar}` - ]; - }); + preferJdk() { + return true; + } + + launchVmArgs(jvm) { + let vmargs = [ + // '-Xdebug', + // '-agentlib:jdwp=transport=dt_socket,server=y,address=7999,suspend=n', + '-Dorg.slf4j.simpleLogger.logFile=boot-java.log', + '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug', + ]; + if (!jvm.isJdk()) { + this.showErrorMessage( + '"Boot-Java" Package Functionality Limited', + 'JAVA_HOME or PATH environment variable seems to point to a JRE. A JDK is required, hence Boot Hints are unavailable.' + ); + } + let toolsJar = jvm.getToolsJar(); + vmargs.push( + "-cp", + `${toolsJar ? `${toolsJar}${path.delimiter}` : ''}${this.getServerJar()}` + ); + return Promise.resolve(vmargs); } createStsAdapter() { diff --git a/atom-extensions/atom-spring-boot/package.json b/atom-extensions/atom-spring-boot/package.json index 315414427..811425b6e 100644 --- a/atom-extensions/atom-spring-boot/package.json +++ b/atom-extensions/atom-spring-boot/package.json @@ -25,9 +25,10 @@ } }, "dependencies": { + "atom-languageclient": "0.8.0", "atom-package-deps": "^4.6.0", "download": "^6.2.5", - "pivotal-atom-languageclient-commons": "0.0.19" + "@pivotal-tools/atom-languageclient-commons": "0.0.1" }, "devDependencies": { "coffeelint": "^1.10.1"