Skip to content

Commit cc8781f

Browse files
authored
Display Java runtime entries (#173)
* Display Java runtime entries Signed-off-by: Rome Li <[email protected]> * Resolve review comments Signed-off-by: Rome Li <[email protected]>
1 parent fe99a0a commit cc8781f

File tree

9 files changed

+252
-30
lines changed

9 files changed

+252
-30
lines changed

package-lock.json

Lines changed: 102 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@
6969
"@types/bytes": "^3.0.0",
7070
"@types/expand-tilde": "^2.0.0",
7171
"@types/jquery": "^3.3.29",
72+
"@types/lodash": "^4.14.137",
7273
"@types/node": "^8.10.46",
7374
"@types/path-exists": "^3.0.0",
75+
"@types/react": "^16.9.2",
76+
"@types/react-dom": "^16.9.0",
7477
"@types/request": "^2.48.1",
7578
"@types/request-promise-native": "^1.0.16",
7679
"@types/semver": "^5.5.0",
@@ -84,10 +87,13 @@
8487
"html-webpack-inline-source-plugin": "0.0.10",
8588
"html-webpack-plugin": "^3.2.0",
8689
"jquery": "^3.4.0",
90+
"lodash": "^4.17.15",
8791
"node-sass": "^4.11.0",
8892
"path-exists": "^3.0.0",
8993
"popper.js": "^1.15.0",
9094
"postcss-loader": "^2.1.5",
95+
"react": "^16.9.0",
96+
"react-dom": "^16.9.0",
9197
"request": "^2.88.0",
9298
"request-promise-native": "^1.0.7",
9399
"sass-loader": "^7.0.1",

src/java-runtime/assets/index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ <h1>Configure Java Runtime</h1>
2020
<div class="card-body">
2121
<h4 class="alert-heading">Java Development Kit Required</h4>
2222
<p>
23-
Java Development Kit (JDK) 8 or later is required for developing Java applications.
23+
Java Development Kit (JDK) 8 or later is required for developing Java applications. The path to the JDK is searched in the following order:
2424
</p>
25-
<p>
25+
<div id="javaRuntimeEntryPanel"></div>
26+
<p class="d-none">
2627
⚠️ No JDK installation was detected. Please follow the links below to download and install JDK:
2728
</p>
29+
<p class="d-none">
30+
<a href="#">Install extra JDKs</a>
31+
</p>
2832
<ul class="nav nav-tabs mb-3" id="jdkSourceTab" role="tablist">
2933
<li class="nav-item">
3034
<a class="nav-link active" id="adoptOpenJdkTab" data-toggle="tab" href="#adoptOpenJdkPanel" role="tab" aria-controls="adoptOpenJdkPanel" aria-selected="true" title="Reliable source of OpenJDK binaries for all platforms">AdoptOpenJDK</a>

src/java-runtime/assets/index.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,22 @@ import $ = require("jquery");
55
import "../../assets/vscode.scss";
66
import "bootstrap/js/src/tab";
77
import bytes = require("bytes");
8+
import { JavaRuntimeEntryPanel } from "./java.runtime.entries";
9+
import * as ReactDOM from "react-dom";
10+
import { JavaRuntimeEntry } from "../types";
811

912
window.addEventListener("message", event => {
10-
if (event.data.command === "showJavaRuntimePanel") {
11-
$("#javaRuntimePanel").removeClass("d-none");
12-
} else if (event.data.command === "applyJdkInfo") {
13+
if (event.data.command === "applyJdkInfo") {
1314
applyJdkInfo(event.data.jdkInfo);
15+
} else if (event.data.command === "showJavaRuntimeEntries") {
16+
showJavaRuntimeEntries(event.data.entries);
1417
}
1518
});
1619

20+
function showJavaRuntimeEntries(entries: JavaRuntimeEntry[]) {
21+
ReactDOM.render(JavaRuntimeEntryPanel(entries), document.getElementById("javaRuntimeEntryPanel"));
22+
}
23+
1724
function applyJdkInfo(jdkInfo: any) {
1825
let binary = jdkInfo.binaries[0];
1926
let downloadLink = binary.installer_link || binary.binary_link;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import * as React from "react";
5+
import { JavaRuntimeEntry } from "../types";
6+
7+
export const JavaRuntimeEntryPanel = (props: JavaRuntimeEntry[]) => {
8+
const current = props.findIndex(entry => entry.isValid || false);
9+
const entries = props.map((entry, index) =>
10+
<tr>
11+
<th scope="row">{index + 1}</th>
12+
<td>
13+
{!entry.path && <em>*Empty*</em>}
14+
{entry.path}
15+
{index === current && <span className="badge badge-pill badge-primary">Current</span>}
16+
{entry.path && !entry.isValid && <span className="badge badge-pill badge-secondary" title={entry.hint}>Invalid</span>}
17+
</td>
18+
<td>
19+
{entry.name}
20+
</td>
21+
<td>
22+
{!entry.actionUri && entry.type}
23+
{entry.actionUri && <a href={entry.actionUri}>{entry.type}</a>}
24+
</td>
25+
</tr>
26+
);
27+
28+
return (
29+
<table className="table table-borderless table-hover table-sm">
30+
<thead>
31+
<tr>
32+
<th scope="col">Order</th>
33+
<th scope="col">Path</th>
34+
<th scope="col">Source</th>
35+
<th scope="col">Type</th>
36+
</tr>
37+
</thead>
38+
<tbody>
39+
{entries}
40+
</tbody>
41+
</table>
42+
);
43+
};

src/java-runtime/index.ts

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import * as request from "request-promise-native";
1010
import findJavaHome = require("find-java-home");
1111
import architecture = require("arch");
1212
import { loadTextFromFile, getExtensionContext } from "../utils";
13+
import { JavaRuntimeEntry, JavaRuntimeEntryTypes } from "./types";
14+
import * as _ from "lodash";
15+
16+
const MIN_JDK_VERSION: number = 8;
1317

1418
let javaRuntimeView: vscode.WebviewPanel | undefined;
1519

@@ -54,8 +58,18 @@ async function initializeJavaRuntimeView(context: vscode.ExtensionContext, webvi
5458
});
5559
}
5660

61+
function showJavaRuntimeEntries(entries: JavaRuntimeEntry[]) {
62+
webviewPanel.webview.postMessage({
63+
command: "showJavaRuntimeEntries",
64+
entries: entries
65+
});
66+
}
67+
5768
let jdkInfo = await suggestOpenJdk();
5869
applyJdkInfo(jdkInfo);
70+
71+
let entries = await findJavaRuntimeEntries();
72+
showJavaRuntimeEntries(entries);
5973
}
6074

6175
export class JavaRuntimeViewSerializer implements vscode.WebviewPanelSerializer {
@@ -111,26 +125,38 @@ async function getJavaVersion(javaHome: string | undefined): Promise<number> {
111125
});
112126
}
113127

114-
async function findPossibleJdkInstallations(): Promise<{[location : string] : string | undefined}> {
115-
return new Promise<{[location : string] : string | undefined}>((resolve, reject) => {
116-
const javaHomeEntries: {[location : string] : string | undefined} = {
117-
"java.home": vscode.workspace.getConfiguration().get("java.home", undefined),
118-
"JDK_HOME": process.env["JDK_HOME"],
119-
"JAVA_HOME": process.env["JAVA_HOME"],
120-
"java.other": undefined
121-
};
122-
123-
findJavaHome({allowJre: false}, (err, home) => {
128+
async function findPossibleJdkInstallations(): Promise<JavaRuntimeEntry[]> {
129+
return new Promise<JavaRuntimeEntry[]>(resolve => {
130+
const entries: JavaRuntimeEntry[] = [{
131+
name: "java.home",
132+
path: vscode.workspace.getConfiguration().get("java.home", undefined),
133+
type: JavaRuntimeEntryTypes.UserSetting,
134+
actionUri: "command:workbench.action.openSettings?%22java.home%22"
135+
}, {
136+
name: "JDK_HOME",
137+
path: process.env["JDK_HOME"],
138+
type: JavaRuntimeEntryTypes.EnvironmentVariable
139+
}, {
140+
name: "JAVA_HOME",
141+
path: process.env["JAVA_HOME"],
142+
type: JavaRuntimeEntryTypes.EnvironmentVariable
143+
}];
144+
145+
findJavaHome((err, home: string) => {
124146
if (!err) {
125-
javaHomeEntries.other = home;
147+
entries.push({
148+
name: "Other",
149+
path: home,
150+
type: JavaRuntimeEntryTypes.Other
151+
});
126152
}
127153

128-
resolve(javaHomeEntries);
154+
resolve(entries);
129155
});
130156
});
131157
}
132158

133-
async function validateJdkInstallation(javaHome: string | undefined) {
159+
async function checkJdkInstallation(javaHome: string | undefined) {
134160
if (!javaHome) {
135161
return false;
136162
}
@@ -140,17 +166,29 @@ async function validateJdkInstallation(javaHome: string | undefined) {
140166
}
141167

142168
export async function validateJavaRuntime() {
143-
const jdkEntries = await findPossibleJdkInstallations();
144-
for (const key in jdkEntries) {
145-
if (jdkEntries.hasOwnProperty(key)) {
146-
const entry = jdkEntries[key];
147-
if (await validateJdkInstallation(entry) && await getJavaVersion(entry) >= 8) {
148-
return true;
149-
}
169+
const entries = await findJavaRuntimeEntries();
170+
return _.some(entries, entry => entry.isValid);
171+
}
172+
173+
export async function findJavaRuntimeEntries(): Promise<JavaRuntimeEntry[]> {
174+
const entries = await findPossibleJdkInstallations();
175+
return Promise.all(_.map(entries, async entry => {
176+
if (!await checkJdkInstallation(entry.path)) {
177+
entry.isValid = false;
178+
entry.hint = "This path does not point to a JDK.";
179+
return entry;
150180
}
151-
}
152181

153-
return false;
182+
const version = await getJavaVersion(entry.path);
183+
if (version < MIN_JDK_VERSION) {
184+
entry.isValid = false;
185+
entry.hint = `JDK 8+ is required while the path points to ${version}`;
186+
return entry;
187+
}
188+
189+
entry.isValid = true;
190+
return entry;
191+
}));
154192
}
155193

156194
export async function suggestOpenJdk(jdkVersion: string = "openjdk11", impl: string = "hotspot") {

0 commit comments

Comments
 (0)