Find likely JDK locations and check configurations

This commit is contained in:
Michael B. Gale
2026-02-17 13:13:35 +00:00
parent 33e2dff082
commit a3d7d36aa6
4 changed files with 497 additions and 301 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -22,6 +22,7 @@ export enum KnownLanguage {
/** Java-specific environment variable names that we may care about. */
export enum JavaEnvVars {
JAVA_HOME = "JAVA_HOME",
JAVA_TOOL_OPTIONS = "JAVA_TOOL_OPTIONS",
JDK_JAVA_OPTIONS = "JDK_JAVA_OPTIONS",
_JAVA_OPTIONS = "_JAVA_OPTIONS",

View File

@@ -1,3 +1,7 @@
import * as fs from "fs";
import * as os from "os";
import path from "path";
import test, { ExecutionContext } from "ava";
import { JavaEnvVars, KnownLanguage } from "../languages";
@@ -7,11 +11,14 @@ import {
LoggedMessage,
setupTests,
} from "../testing-utils";
import { withTmpDir } from "../util";
import {
checkJavaEnvVars,
checkJdkSettings,
checkProxyEnvironment,
checkProxyEnvVars,
discoverActionsJdks,
JAVA_PROXY_ENV_VARS,
ProxyEnvVars,
} from "./environment";
@@ -58,6 +65,59 @@ test("checkJavaEnvironment - logs values when variables are set", (t) => {
assertEnvVarLogMessages(t, JAVA_PROXY_ENV_VARS, messages, true);
});
test("discoverActionsJdks - discovers JDK paths", (t) => {
const jdk8 = "/usr/lib/jvm/temurin-8-jdk-amd64";
const jdk17 = "/usr/lib/jvm/temurin-17-jdk-amd64";
const jdk21 = "/usr/lib/jvm/temurin-21-jdk-amd64";
process.env[JavaEnvVars.JAVA_HOME] = jdk17;
process.env["JAVA_HOME_8_X64"] = jdk8;
process.env["JAVA_HOME_17_X64"] = jdk17;
process.env["JAVA_HOME_21_X64"] = jdk21;
const results = discoverActionsJdks();
t.is(results.size, 3);
t.true(results.has(jdk8));
t.true(results.has(jdk17));
t.true(results.has(jdk21));
});
test("checkJdkSettings - does not throw for an empty directory", async (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
await withTmpDir(async (tmpDir) => {
t.notThrows(() => checkJdkSettings(logger, tmpDir));
});
});
test("checkJdkSettings - finds files and logs relevant properties", async (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
await withTmpDir(async (tmpDir) => {
const dir = path.join(tmpDir, "conf");
fs.mkdirSync(dir);
const file = path.join(dir, "net.properties");
fs.writeFileSync(
file,
[
"irrelevant.property=foo",
"http.proxyHost=proxy.example.com",
"http.unrelated=bar",
].join(os.EOL),
{},
);
checkJdkSettings(logger, tmpDir);
checkExpectedLogMessages(t, messages, [
`Found '${file}'.`,
`Found 'http.proxyHost=proxy.example.com' in '${file}'`,
]);
});
});
test("checkProxyEnvVars - none set", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);

View File

@@ -1,6 +1,10 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import { JavaEnvVars, KnownLanguage, Language } from "../languages";
import { Logger } from "../logging";
import { isDefined } from "../util";
import { getErrorMessage, isDefined } from "../util";
/**
* Checks whether an environment variable named `name` is set and logs its value if set.
@@ -37,6 +41,76 @@ export function checkJavaEnvVars(logger: Logger) {
}
}
/**
* Discovers paths to JDK directories based on JAVA_HOME and GHA-specific environement variables.
* @returns A set of JDK paths.
*/
export function discoverActionsJdks(): Set<string> {
const paths: Set<string> = new Set();
// Check whether JAVA_HOME is set.
const javaHome = process.env[JavaEnvVars.JAVA_HOME];
if (isDefined(javaHome)) {
paths.add(javaHome);
}
for (const [envVar, value] of Object.entries(process.env)) {
if (isDefined(value) && envVar.match(/^JAVA_HOME_\d+_/)) {
paths.add(value);
}
}
return paths;
}
/**
* Tries to inspect JDK configuration files for the specified JDK path which may contain proxy settings.
*
* @param logger The logger to use.
* @param jdkHome The JDK home directory.
*/
export function checkJdkSettings(logger: Logger, jdkHome: string) {
const filesToCheck = [
// JDK 9+
path.join("conf", "net.properties"),
// JDK 8 and below
path.join("lib", "net.properties"),
];
// The JRE properties that may affect the proxy.
const properties = [
"http.proxyHost",
"http.proxyPort",
"https.proxyHost",
"https.proxyPort",
"http.nonProxyHosts",
"java.net.useSystemProxies",
];
for (const fileToCheck of filesToCheck) {
const file = path.join(jdkHome, fileToCheck);
try {
if (fs.existsSync(file)) {
logger.debug(`Found '${file}'.`);
const lines = String(fs.readFileSync(file)).split(os.EOL);
for (const line of lines) {
for (const property of properties) {
if (line.startsWith(`${property}=`)) {
logger.info(`Found '${line}' in '${file}'.`);
}
}
}
} else {
logger.debug(`'${file}' does not exist.`);
}
} catch (err) {
logger.debug(`Failed to read '${file}': ${getErrorMessage(err)}`);
}
}
}
/** Enumerates environment variable names which may contain information about proxy settings. */
export enum ProxyEnvVars {
HTTP_PROXY = "HTTP_PROXY",
@@ -74,5 +148,10 @@ export function checkProxyEnvironment(
// then we perform all checks.
if (language === undefined || language === KnownLanguage.java) {
checkJavaEnvVars(logger);
const jdks = discoverActionsJdks();
for (const jdk of jdks) {
checkJdkSettings(logger, jdk);
}
}
}