fix(ghidra): explain keg-only JDK admission remediation

Explain how to select an existing Homebrew JDK with JAVA_HOME when macOS
Java discovery cannot find a keg-only installation. Preserve caller-selected
runtime inputs and the Ghidra installation's declared Java bounds. Document
the installation paths and retain a regression showing only the requested
Java command is probed; no automatic JDK discovery or installation added.

Validation: 4 focused files, 122 passed; npm run check and docs:check passed.
Public CLI prerequisite fixtures ran on macOS; Homebrew keg-only guidance
is source/fixture verified against the primary formula documentation, not
a fresh Homebrew installation or a Windows runtime test.

Refs #4556
This commit is contained in:
morluto
2026-10-17 03:34:11 +08:00
parent c75cf827e7
commit ae07d15170
3 changed files with 43 additions and 2 deletions
+10
View File
@@ -833,6 +833,16 @@ rea doctor --json
rea setup
```
On macOS, [Homebrew OpenJDK is keg-only](https://formulae.brew.sh/formula/openjdk)
and may be unavailable to the system `java` wrapper. Set `JAVA_HOME` to the
selected formula's `libexec/openjdk.jdk/Contents/Home`, for example
`/opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home` or
`/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home`. Use a JDK inside the
Java version bounds declared by your Ghidra installation; REA does not select
another installed JDK automatically. Doctor distinguishes an absent Java
command from a command that runs and fails, and retains bounded probe output
and any parsed properties when the selected runtime cannot be admitted.
On Windows, configure the existing installation in PowerShell:
```powershell
+28
View File
@@ -1382,3 +1382,31 @@ describe("Ghidra Java probe os.arch extraction", () => {
}
});
});
it("explains the macOS keg-only JDK case without probing an unselected installation", () => {
const probed: string[] = [];
const inspection = inspectGhidraInstallation(
{
environment: {},
installDir: INSTALL,
platform: "darwin",
architecture: "arm64",
},
host({
probeJava: (command) => {
probed.push(command);
return missingJavaProbe;
},
}),
);
expect(probed).toEqual(["java"]);
expect(inspection.checks.find(({ name }) => name === "java")).toMatchObject({
status: "failed",
code: "runtime_missing",
remediation: expect.stringContaining("Homebrew OpenJDK can be keg-only"),
});
const java = inspection.checks.find(({ name }) => name === "java");
expect(java?.status === "failed" ? java.remediation : "").toContain(
"/opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home",
);
});
+5 -2
View File
@@ -534,6 +534,7 @@ const installationChecks = ({
coordinates.javaCommand,
javaHome,
coordinates.properties,
platform,
coordinates.javaProbeFailure,
),
];
@@ -823,6 +824,7 @@ const javaCheck = (
command: string,
configuredHome: string | undefined,
properties: GhidraApplicationProperties | undefined,
platform: NodeJS.Platform,
failure: GhidraJavaProbeFailure | undefined,
): GhidraInstallationCheck => {
const requirement = ghidraJavaRequirement(properties);
@@ -861,7 +863,7 @@ const javaCheck = (
? "unsupported_version"
: "version_unresolved",
detail,
remediation: javaRemediation(requirement, configuredHome, range),
remediation: javaRemediation(requirement, configuredHome, range, platform),
});
};
@@ -869,11 +871,12 @@ const javaRemediation = (
requirement: GhidraJavaRequirement,
configuredHome: string | undefined,
range: string,
platform: NodeJS.Platform,
): string => {
if (requirement.unresolved !== null)
return `The Ghidra installation's Java bounds could not be read (${requirement.unresolved}). Install a 64-bit full JDK inside the declared application.java.min and application.java.max.`;
return configuredHome === undefined
? `Install ${range}, or set JAVA_HOME before starting REA.`
? `Select ${range} on PATH, or set JAVA_HOME to its installation root before starting REA.${platform === "darwin" ? " Homebrew OpenJDK can be keg-only: set JAVA_HOME to the selected formula's libexec/openjdk.jdk/Contents/Home (for example /opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home or /usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home). The installed JDK must satisfy the declared Ghidra Java bounds." : ""}`
: `Update JAVA_HOME to the root of ${range} installation.`;
};