Find Java version from release file (#922)
This commit is contained in:
parent
78bd1f5f42
commit
4c0df75129
|
@ -12,7 +12,7 @@ import { buildWorkspace } from "./build";
|
|||
import { populateStepFilters, substituteFilterVariables } from "./classFilter";
|
||||
import * as commands from "./commands";
|
||||
import * as lsPlugin from "./languageServerPlugin";
|
||||
import { addMoreHelpfulVMArgs, detectLaunchCommandStyle, validateRuntime } from "./launchCommand";
|
||||
import { addMoreHelpfulVMArgs, getJavaVersion, getShortenApproachForCLI, validateRuntimeCompatibility } from "./launchCommand";
|
||||
import { logger, Type } from "./logger";
|
||||
import { mainClassPicker } from "./mainClassPicker";
|
||||
import { resolveJavaProcess } from "./processPicker";
|
||||
|
@ -271,17 +271,18 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
|
|||
// Populate the class filters to the debug configuration.
|
||||
await populateStepFilters(config);
|
||||
|
||||
const targetJavaVersion: number = await getJavaVersion(config.javaExec);
|
||||
// Auto add '--enable-preview' vmArgs if the java project enables COMPILER_PB_ENABLE_PREVIEW_FEATURES flag.
|
||||
if (await lsPlugin.detectPreviewFlag(config.mainClass, config.projectName)) {
|
||||
config.vmArgs = (config.vmArgs || "") + " --enable-preview";
|
||||
validateRuntime(config);
|
||||
validateRuntimeCompatibility(targetJavaVersion);
|
||||
}
|
||||
|
||||
// Add more helpful vmArgs.
|
||||
await addMoreHelpfulVMArgs(config);
|
||||
await addMoreHelpfulVMArgs(config, targetJavaVersion);
|
||||
|
||||
if (!config.shortenCommandLine || config.shortenCommandLine === "auto") {
|
||||
config.shortenCommandLine = await detectLaunchCommandStyle(config);
|
||||
config.shortenCommandLine = await getShortenApproachForCLI(config, targetJavaVersion);
|
||||
}
|
||||
|
||||
if (process.platform === "win32" && config.console !== "internalConsole") {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
import * as cp from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as _ from "lodash";
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
|
@ -17,19 +18,25 @@ enum shortenApproach {
|
|||
|
||||
const HELPFUL_NPE_VMARGS = "-XX:+ShowCodeDetailsInExceptionMessages";
|
||||
|
||||
export async function detectLaunchCommandStyle(config: vscode.DebugConfiguration): Promise<shortenApproach> {
|
||||
const javaExec: string = config.javaExec || path.join(await getJavaHome(), "bin", "java");
|
||||
const javaVersion = await checkJavaVersion(javaExec);
|
||||
const recommendedShortenApproach = javaVersion <= 8 ? shortenApproach.jarmanifest : shortenApproach.argfile;
|
||||
/**
|
||||
* Returns the recommended approach to shorten the command line length.
|
||||
* @param config the launch configuration
|
||||
* @param runtimeVersion the target runtime version
|
||||
*/
|
||||
export async function getShortenApproachForCLI(config: vscode.DebugConfiguration, runtimeVersion: number): Promise<shortenApproach> {
|
||||
const recommendedShortenApproach = runtimeVersion <= 8 ? shortenApproach.jarmanifest : shortenApproach.argfile;
|
||||
return (await shouldShortenIfNecessary(config)) ? recommendedShortenApproach : shortenApproach.none;
|
||||
}
|
||||
|
||||
export async function validateRuntime(config: vscode.DebugConfiguration) {
|
||||
/**
|
||||
* Validates whether the specified runtime version could be supported by the Java tooling.
|
||||
* @param runtimeVersion the target runtime version
|
||||
*/
|
||||
export async function validateRuntimeCompatibility(runtimeVersion: number) {
|
||||
try {
|
||||
const platformSettings = await fetchPlatformSettings();
|
||||
if (platformSettings && platformSettings.latestSupportedJavaVersion) {
|
||||
const latestSupportedVersion = flattenMajorVersion(platformSettings.latestSupportedJavaVersion);
|
||||
const runtimeVersion = await checkJavaVersion(config.javaExec || path.join(await getJavaHome(), "bin", "java"));
|
||||
if (latestSupportedVersion < runtimeVersion) {
|
||||
showWarningMessageWithTroubleshooting({
|
||||
message: "The compiled classes are not compatible with the runtime JDK. To mitigate the issue, please refer to \"Learn More\".",
|
||||
|
@ -42,11 +49,14 @@ export async function validateRuntime(config: vscode.DebugConfiguration) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function addMoreHelpfulVMArgs(config: vscode.DebugConfiguration) {
|
||||
/**
|
||||
* Add some helpful VM arguments to the launch configuration based on the target runtime version.
|
||||
* @param config the launch configuration
|
||||
* @param runtimeVersion the target runtime version
|
||||
*/
|
||||
export async function addMoreHelpfulVMArgs(config: vscode.DebugConfiguration, runtimeVersion: number) {
|
||||
try {
|
||||
const javaExec = config.javaExec || path.join(await getJavaHome(), "bin", "java");
|
||||
const version = await checkJavaVersion(javaExec);
|
||||
if (version >= 14) {
|
||||
if (runtimeVersion >= 14) {
|
||||
// JEP-358: https://openjdk.java.net/jeps/358
|
||||
if (config.vmArgs && config.vmArgs.indexOf(HELPFUL_NPE_VMARGS) >= 0) {
|
||||
return;
|
||||
|
@ -59,23 +69,63 @@ export async function addMoreHelpfulVMArgs(config: vscode.DebugConfiguration) {
|
|||
}
|
||||
}
|
||||
|
||||
function checkJavaVersion(javaExec: string): Promise<number> {
|
||||
return new Promise((resolve, _reject) => {
|
||||
cp.execFile(javaExec, ["-version"], {}, (_error, _stdout, stderr) => {
|
||||
const javaVersion = parseMajorVersion(stderr);
|
||||
resolve(javaVersion);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Returns the target runtime version. If the javaExec is not specified, then return the current Java version
|
||||
* that the Java tooling used.
|
||||
* @param javaExec the path of the Java executable
|
||||
*/
|
||||
export async function getJavaVersion(javaExec: string): Promise<number> {
|
||||
javaExec = javaExec || path.join(await getJavaHome(), "bin", "java");
|
||||
let javaVersion = await checkVersionInReleaseFile(path.resolve(javaExec, "..", ".."));
|
||||
if (!javaVersion) {
|
||||
javaVersion = await checkVersionByCLI(javaExec);
|
||||
}
|
||||
return javaVersion;
|
||||
}
|
||||
|
||||
function parseMajorVersion(content: string): number {
|
||||
const regexp = /version "(.*)"/g;
|
||||
const match = regexp.exec(content);
|
||||
if (!match) {
|
||||
async function checkVersionInReleaseFile(javaHome: string): Promise<number> {
|
||||
if (!javaHome) {
|
||||
return 0;
|
||||
}
|
||||
const releaseFile = path.join(javaHome, "release");
|
||||
if (!await fs.existsSync(releaseFile)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flattenMajorVersion(match[1]);
|
||||
try {
|
||||
const content = fs.readFileSync(releaseFile);
|
||||
const regexp = /^JAVA_VERSION="(.*)"/gm;
|
||||
const match = regexp.exec(content.toString());
|
||||
if (!match) {
|
||||
return 0;
|
||||
}
|
||||
const majorVersion = flattenMajorVersion(match[1]);
|
||||
return majorVersion;
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version by parsing `JAVA_HOME/bin/java -version`
|
||||
*/
|
||||
async function checkVersionByCLI(javaExec: string): Promise<number> {
|
||||
if (!javaExec) {
|
||||
return 0;
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
cp.execFile(javaExec, ["-version"], {}, (_error, _stdout, stderr) => {
|
||||
const regexp = /version "(.*)"/g;
|
||||
const match = regexp.exec(stderr);
|
||||
if (!match) {
|
||||
return resolve(0);
|
||||
}
|
||||
const javaVersion = flattenMajorVersion(match[1]);
|
||||
resolve(javaVersion);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function flattenMajorVersion(version: string): number {
|
||||
|
|
Loading…
Reference in New Issue