diff --git a/bin/templates/cordova/lib/env/java.js b/bin/templates/cordova/lib/env/java.js index 6eed6f60..90d53403 100644 --- a/bin/templates/cordova/lib/env/java.js +++ b/bin/templates/cordova/lib/env/java.js @@ -43,7 +43,28 @@ const java = { // Java <= 8 writes version info to stderr, Java >= 9 to stdout let version = null; try { - version = (await execa('javac', ['-version'], { all: true })).all; + const javacOutput = (await execa('javac', ['-version'], { all: true })).all; + + /* + A regex match for the java version looks like the following: + + version: [ + 'javac 1.8.0', + '1.8.0', + index: 45, + input: 'Picked up _JAVA_OPTIONS: -Xms1024M -Xmx2048M\njavac 1.8.0_271', + groups: undefined + ] + + We have to use a regular expression to get the java version, because on some environments + (e.g. macOS Big Sur) javac prints _JAVA_OPTIONS before printing the version and semver.coerce() + will fail to get the correct version from the output. + */ + + const match = /javac\s+([\d.]+)/i.exec(javacOutput); + if (match && match[1]) { + version = match[1]; + } } catch (ex) { events.emit('verbose', ex.shortMessage); diff --git a/spec/unit/check_reqs.spec.js b/spec/unit/check_reqs.spec.js index 65472000..68c3d387 100644 --- a/spec/unit/check_reqs.spec.js +++ b/spec/unit/check_reqs.spec.js @@ -64,6 +64,25 @@ describe('check_reqs', function () { await expectAsync(check_reqs.check_java()).toBeResolvedTo({ version: '1.8.0' }); }); + + it('should return the correct version if javac prints _JAVA_OPTIONS', async () => { + check_reqs.__set__({ + java: { + getVersion: async () => { + let version = null; + const javacOutput = 'Picked up _JAVA_OPTIONS: -Xms1024M -Xmx2048M\njavac 1.8.0_271'; + const match = /javac\s+([\d.]+)/i.exec(javacOutput); + if (match && match[1]) { + version = match[1]; + } + + return { version }; + } + } + }); + + await expectAsync(check_reqs.check_java()).toBeResolvedTo({ version: '1.8.0' }); + }); }); describe('check_android', function () {