apache/cordova-android · error · CordovaError
Failed to run "javac -version", make sure that you have a JD
Error message
Failed to run "javac -version", make sure that you have a JDK version 8 installed. You can get it from the following location: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
What it means
java.getVersion runs `javac -version` via execa; if the process fails to spawn (typically ENOENT - no javac on PATH, i.e. no JDK or only a JRE) it emits the execa shortMessage on verbose and throws this CordovaError. When JAVA_HOME is set but its bin/javac is unusable, the message additionally appends 'Your JAVA_HOME is invalid: <value>'. Note the text recommends JDK 8 - this code targets an older cordova-android; newer releases require JDK 17.
Source
Thrown at lib/env/java.js:58
getVersion: async () => {
await java._ensure(process.env);
// Java <= 8 writes version info to stderr, Java >= 9 to stdout
let javacOutput;
try {
javacOutput = (await execa('javac', ['-version'], { all: true })).all;
} catch (ex) {
events.emit('verbose', ex.shortMessage);
let msg =
'Failed to run "javac -version", make sure that you have a JDK version 8 installed.\n' +
'You can get it from the following location:\n' +
'https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html';
if (process.env.JAVA_HOME) {
msg += '\n\n';
msg += 'Your JAVA_HOME is invalid: ' + process.env.JAVA_HOME;
}
throw new CordovaError(msg);
}
// We have to filter the output, because javac prints _JAVA_OPTIONS
// before printing the version which causes semver.coerce to fail to get
// the correct version if those options contain any numbers.
const match = /javac\s+([\d.]+)/i.exec(javacOutput);
return semver.coerce(match && match[1]);
},
/**
* Ensures that Java is installed. Will throw exception if not.
* Will set JAVA_HOME and PATH environment variables.
*
* This function becomes a no-op if already ran previously.
*/
_ensure: async (environment) => {
if (javaIsEnsured) {
return;View on GitHub (pinned to 7c1e190064)
Solutions
- Install a JDK matching your cordova-android version (8 for this codebase; cordova-android >= 13 needs JDK 17).
- Set JAVA_HOME to the JDK root such that $JAVA_HOME/bin/javac exists, and put $JAVA_HOME/bin on PATH.
- Open a new shell (or `hash -r`) after PATH changes so the old 'command not found' cache clears.
Example fix
# before export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-jre # JRE: no javac # after export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 # JDK: bin/javac exists export PATH="$JAVA_HOME/bin:$PATH"
Defensive patterns
Strategy: validation
Validate before calling
const javac = await execa('javac', ['-version'], { all: true }).catch(() => null);
if (!javac) {
throw new Error('No usable javac on PATH - install a JDK and set JAVA_HOME so $JAVA_HOME/bin/javac exists');
} Try / catch
try {
await check_reqs.check_java();
} catch (e) {
if (/Failed to run "javac -version"/.test(e.message)) {
// JDK missing/invalid: install JDK, fix JAVA_HOME, open a new shell, rerun `cordova requirements android`
}
throw e;
} Prevention
- Install the full JDK (not a JRE) matching your cordova-android version (8 here; 17 for cordova-android >= 13).
- Assert JAVA_HOME/bin/javac exists in your env setup script before any cordova command.
- After upgrading or removing JDKs, update JAVA_HOME and open a fresh shell.
When it happens
Trigger: check_java / `cordova requirements android` / any build when `javac` is not resolvable: JDK not installed, only a JRE installed (java exists but javac does not), or JAVA_HOME pointing at a JRE/deleted directory.
Common situations: CI images shipping a JRE only; JAVA_HOME left stale after a JDK upgrade or OS cleanup; fresh machine with no Java; PATH ordering hiding the right JDK.
Related errors
- Failed to find 'JAVA_HOME' environment variable. Try setting
- Failed to find 'ANDROID_HOME' environment variable. Try sett
- Failed to find 'ANDROID_HOME' environment variable. Try sett
- Failed to find 'ANDROID_HOME' environment variable. Try sett
- 'ANDROID_HOME' environment variable is set to non-existent p
AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22).
Data as JSON: /api/errors/e4e680624299374e.
Report an issue: GitHub.