Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvements for resolving java home #1465

Merged
merged 10 commits into from
Feb 28, 2024
47 changes: 29 additions & 18 deletions packages/metals-languageclient/src/getJavaHome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { toPromise } from "./util";
import fs from "fs";
import path from "path";
import { spawn } from "promisify-child-process";
import { OutputChannel } from "./interfaces/OutputChannel";

export type JavaVersion = "11" | "17" | "21";

Expand All @@ -26,44 +27,54 @@ export type JavaVersion = "11" | "17" | "21";
* @param javaVersion metals.javaVersion value as read from the configuration or default
*/
export async function getJavaHome(
javaVersion: JavaVersion
javaVersion: JavaVersion,
outputChannel: OutputChannel
): Promise<string | undefined> {
const fromEnvValue = await fromEnv(javaVersion);
const fromEnvValue = await fromEnv(javaVersion, outputChannel);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance to forward coursier downloading information?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are forwarding courier downloading info.

return fromEnvValue ? fromEnvValue : await locate(javaVersion);
}

const versionRegex = /\d+\.\d+\.\d+/;
async function validateJavaVersion(
javaHome: string,
javaVersion: JavaVersion
javaVersion: JavaVersion,
outputChannel: OutputChannel
): Promise<boolean> {
const javaBins = [
path.join(javaHome, "bin", "java"),
path.join(javaHome, "bin", "java.exe"),
path.join(javaHome, "bin", "jre", "java"),
path.join(javaHome, "bin", "jre", "java.exe"),
].filter(fs.existsSync);

if (javaBins.length != 0) {
const javaBin = javaBins[0];
const javaVersionOut = await spawn(javaBin, ["-version"], {
const javaBin = path.join(javaHome, "bin", "java");
try {
const javaVersionOut = spawn(javaBin, ["-version"], {
encoding: "utf8",
});
const javaInfoStr = javaVersionOut.stderr as string;

javaVersionOut.stderr?.on("data", (out: Buffer) => {
outputChannel.appendLine(`${javaBin} -version:`);
const msg = out.toString().trim();
outputChannel.appendLine(msg);
});

const javaInfoStr = (await javaVersionOut).stderr as string;
const matches = javaInfoStr.match(versionRegex);
if (matches) {
return matches[0].slice(0, 2) == javaVersion;
return +matches[0].slice(0, 2) >= +javaVersion;
}
} catch (error) {
outputChannel.appendLine(`failed while running ${javaBin} -version`);
outputChannel.appendLine(`${error}`);
}
return false;
}

export async function fromEnv(
javaVersion: JavaVersion
javaVersion: JavaVersion,
outputChannel: OutputChannel
): Promise<string | undefined> {
const javaHome = process.env["JAVA_HOME"];
if (javaHome) {
const isValid = await validateJavaVersion(javaHome, javaVersion);
const isValid = await validateJavaVersion(
javaHome,
javaVersion,
outputChannel
);
if (isValid) return javaHome;
}

Expand All @@ -73,7 +84,7 @@ export async function fromEnv(
function locate(javaVersion: JavaVersion): Promise<undefined | string> {
return toPromise(
pipe(
locateJavaHome({ version: `~${javaVersion}` }),
locateJavaHome({ version: `>=${javaVersion}` }),
chain((javaHomes) => {
if (!javaHomes || javaHomes.length === 0) {
return TE.right(undefined);
Expand Down
10 changes: 7 additions & 3 deletions packages/metals-languageclient/src/setupCoursier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export async function setupCoursier(
const resolveJavaHomeWithCoursier = async (coursier: string) => {
await run(
coursier,
["java", "--jvm", javaVersion, "--setup"],
["java", "--jvm", javaVersion, "-version"],
handleOutput
);

Expand All @@ -71,7 +71,7 @@ export async function setupCoursier(
const coursier = await resolveCoursier();
output.appendLine(`Using coursier located at ${coursier}`);

var javaHome = await getJavaHome(javaVersion);
var javaHome = await getJavaHome(javaVersion, output);

if (!javaHome) {
output.appendLine(
Expand Down Expand Up @@ -100,7 +100,11 @@ export async function validateCoursier(
};

const validateDefault = async () => {
if (defaultCoursier && fs.statSync(defaultCoursier).isFile()) {
if (
defaultCoursier &&
fs.existsSync(defaultCoursier) &&
fs.statSync(defaultCoursier).isFile()
) {
return validate(defaultCoursier);
} else {
return undefined;
Expand Down
2 changes: 1 addition & 1 deletion packages/metals-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ async function fetchAndLaunchMetals(
const metalsDirPath = metalsDir(ConfigurationTarget.Global);

if (!fs.existsSync(metalsDirPath)) {
fs.existsSync(metalsDirPath);
fs.mkdirSync(metalsDirPath);
}

const { coursier, javaHome } = await metalsLanguageClient.setupCoursier(
Expand Down
Loading