Skip to content

Commit 156b916

Browse files
Add check for JAVA 9
* Add check for JAVA 9 Currently Gradle cannot work with JAVA 9, so detect if it has been used return correct warning. Fix detection of Javac version The command `javac -version` prints result to stderr when JAVA 8 is used and to stdout when JAVA 9 is used. Current check uses the stderr output, so when JAVA 9 is installed it fails to detect the correct version. In order to support both JAVA 8 and JAVA 9, capture both stdout and stderr and get the version from there. Also remove unneeded check for Java version - we care about JAVA Compiler, which is included in JDK. * Handle case when Javac version is a single number (9 for example) In some cases javac version is a single number, for example 9. In this case our validation fails to detect the correct version and to check if we support this version. In order to resolve this issue, use the `appendZeroesToVersion` method in order to make the versin semver valid.
1 parent e0a9b3b commit 156b916

File tree

13 files changed

+122
-88
lines changed

13 files changed

+122
-88
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: node_js
22
node_js:
3-
- '4'
3+
- '6'
44
git:
55
submodules: false
66
before_script:

README.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ Library that helps identifying if the environment can be used for development of
7979
// The default value is true. If set to false the result of each check for each element
8080
// of the sys info will not be cached.
8181
setShouldCacheSysInfo(false);
82-
const javaVersion = await sysInfo.getJavaVersion();
83-
console.log("java: ", javaVersion);
8482

8583
const javacVersion = await sysInfo.getJavaCompilerVersion();
8684
console.log("javac: ", javacVersion);
@@ -150,12 +148,6 @@ Library that helps identifying if the environment can be used for development of
150148
* Describes methods which helps collecting system information.
151149
*/
152150
interface ISysInfo {
153-
/**
154-
* Returns the currently installed Java version.
155-
* @return {Promise<string>} The currently installed Java version.
156-
*/
157-
getJavaVersion(): Promise<string>;
158-
159151
/**
160152
* Returns the currently installed Java compiler version.
161153
* @return {Promise<string>} The currently installed Java compiler version.
@@ -336,12 +328,6 @@ Library that helps identifying if the environment can be used for development of
336328
nodeGypVer: string;
337329

338330
// dependencies
339-
/**
340-
* Version of java, as returned by `java -version`.
341-
* @type {string}
342-
*/
343-
javaVer: string;
344-
345331
/**
346332
* Xcode version string as returned by `xcodebuild -version`. Valid only on Mac.
347333
* @type {string}

lib/android-tools-info.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ChildProcess } from "./wrappers/child-process";
22
import { FileSystem } from "./wrappers/file-system";
33
import { HostInfo } from "./host-info";
44
import { Constants } from "./constants";
5+
import { Helpers } from './helpers';
56
import { EOL } from "os";
67
import * as semver from "semver";
78
import * as path from "path";
@@ -13,14 +14,16 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
1314
private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23";
1415
private static VERSION_REGEX = /((\d+\.){2}\d+)/;
1516
private static MIN_JAVA_VERSION = "1.8.0";
17+
private static MAX_JAVA_VERSION = "1.9.0";
1618

1719
private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData;
1820
private androidHome = process.env["ANDROID_HOME"];
1921
private pathToEmulatorExecutable: string;
2022

2123
constructor(private childProcess: ChildProcess,
2224
private fs: FileSystem,
23-
private hostInfo: HostInfo) { }
25+
private hostInfo: HostInfo,
26+
private helpers: Helpers) { }
2427

2528
public getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData {
2629
if (!this.toolsInfo) {
@@ -86,17 +89,27 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
8689
return errors;
8790
}
8891

89-
public validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[] {
92+
public validateJavacVersion(installedJavaCompilerVersion: string): NativeScriptDoctor.IWarning[] {
9093
const errors: NativeScriptDoctor.IWarning[] = [];
9194

9295
let additionalMessage = "You will not be able to build your projects for Android." + EOL
9396
+ "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL +
9497
" described in " + this.getSystemRequirementsLink();
95-
let matchingVersion = (installedJavaVersion || "").match(AndroidToolsInfo.VERSION_REGEX);
96-
if (matchingVersion && matchingVersion[1]) {
97-
if (semver.lt(matchingVersion[1], AndroidToolsInfo.MIN_JAVA_VERSION)) {
98+
99+
const matchingVersion = this.helpers.appendZeroesToVersion(installedJavaCompilerVersion || "", 3).match(AndroidToolsInfo.VERSION_REGEX);
100+
const installedJavaCompilerSemverVersion = matchingVersion && matchingVersion[1];
101+
if (installedJavaCompilerSemverVersion) {
102+
let warning: string = null;
103+
104+
if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) {
105+
warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`;
106+
} else if (semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) {
107+
warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install version ${AndroidToolsInfo.MIN_JAVA_VERSION}.`;
108+
}
109+
110+
if (warning) {
98111
errors.push({
99-
warning: `Javac version ${installedJavaVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`,
112+
warning,
100113
additionalInformation: additionalMessage,
101114
platforms: [Constants.ANDROID_PLATFORM_NAME]
102115
});
@@ -140,7 +153,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
140153
errors.push({
141154
warning: "The ANDROID_HOME environment variable points to incorrect directory. You will not be able to perform any build-related operations for Android.",
142155
additionalInformation: "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory, " +
143-
"where you will find `tools` and `platform-tools` directories.",
156+
"where you will find `tools` and `platform-tools` directories.",
144157
platforms: [Constants.ANDROID_PLATFORM_NAME]
145158
});
146159
}
@@ -299,22 +312,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
299312
}
300313

301314
private getSystemRequirementsLink(): string {
302-
let linkToSystemRequirements: string;
303-
switch (process.platform) {
304-
case "linux":
305-
linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-linux.html#system-requirements";
306-
break;
307-
case "win32":
308-
linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-win.html#system-requirements";
309-
break;
310-
case "darwin":
311-
linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-os-x.html#system-requirements";
312-
break;
313-
default:
314-
linkToSystemRequirements = "";
315-
}
316-
317-
return linkToSystemRequirements;
315+
return Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform] || "";
318316
}
319317

320318
private isAndroidHomeValid(): boolean {

lib/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ export class Constants {
22
public static ANDROID_PLATFORM_NAME = "Android";
33
public static IOS_PLATFORM_NAME = "iOS";
44
public static SUPPORTED_PLATFORMS = [Constants.ANDROID_PLATFORM_NAME, Constants.IOS_PLATFORM_NAME];
5+
public static SYSTEM_REQUIREMENTS_LINKS: IDictionary<string> = {
6+
"win32": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-win.html#system-requirements",
7+
"linux": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-linux.html#system-requirements",
8+
"darwin": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-os-x.html#system-requirements",
9+
};
510
}

lib/doctor.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,13 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
131131
});
132132
}
133133

134-
if (!sysInfoData.javaVer) {
134+
if (!sysInfoData.javacVersion) {
135135
result.push({
136136
warning: "WARNING: The Java Development Kit (JDK) is not installed or is not configured properly.",
137137
additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL
138138
+ "to perform some Android-related operations. To ensure that you can develop and" + EOL
139139
+ "test your apps for Android, verify that you have installed the JDK as" + EOL
140-
+ "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)" + EOL
141-
+ "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + EOL,
140+
+ "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)." + EOL,
142141
platforms: [Constants.ANDROID_PLATFORM_NAME]
143142
});
144143
}

lib/helpers.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ export class Helpers {
2222
return this.hostInfo.isWindows ? this.cmdQuote(value) : this.bashQuote(value);
2323
}
2424

25+
/**
26+
* Appends zeroes to a version string until it reaches a specified length.
27+
* @param {string} version The version on which to append zeroes.
28+
* @param {number} requiredVersionLength The required length of the version string.
29+
* @returns {string} Appended version string. In case input is null, undefined or empty string, it is returned immediately without appending anything.
30+
*/
2531
public appendZeroesToVersion(version: string, requiredVersionLength: number): string {
26-
const zeroesToAppend = requiredVersionLength - version.split(".").length;
27-
for (let index = 0; index < zeroesToAppend; index++) {
28-
version += ".0";
32+
if (version) {
33+
const zeroesToAppend = requiredVersionLength - version.split(".").length;
34+
for (let index = 0; index < zeroesToAppend; index++) {
35+
version += ".0";
36+
}
2937
}
3038

3139
return version;

lib/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const winReg = new WinReg();
1515
const hostInfo = new HostInfo(winReg);
1616
const fileSystem = new FileSystem();
1717
const helpers = new Helpers(hostInfo);
18-
const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo);
18+
const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo, helpers);
1919

2020
const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg, androidToolsInfo);
2121

lib/local-build-requirements/android-local-build-requirements.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export class AndroidLocalBuildRequirements {
66
const androidToolsInfo = await this.androidToolsInfo.validateInfo();
77
if (androidToolsInfo.length ||
88
!await this.sysInfo.getJavaCompilerVersion() ||
9-
!await this.sysInfo.getJavaVersion() ||
109
!await this.sysInfo.getAdbVersion()) {
1110
return false;
1211
}

lib/sys-info.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@ import { HostInfo } from "./host-info";
44
import { ExecOptions } from "child_process";
55
import { WinReg } from "./winreg";
66
import { Helpers } from "./helpers";
7-
import { platform } from "os";
7+
import { platform, EOL } from "os";
88
import * as path from "path";
99
import * as osenv from "osenv";
1010
import * as temp from "temp";
1111
import * as semver from "semver";
1212

1313
export class SysInfo implements NativeScriptDoctor.ISysInfo {
14-
// Different java has different format for `java -version` command.
15-
private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i;
16-
1714
private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im;
1815
private static XCODE_VERSION_REGEXP = /Xcode (.*)/;
1916
private static VERSION_REGEXP = /(\d{1,})\.(\d{1,})\.*([\w-]{0,})/m;
@@ -23,7 +20,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo {
2320

2421
private monoVerRegExp = /version (\d+[.]\d+[.]\d+) /gm;
2522

26-
private javaVerCache: string;
2723
private javaCompilerVerCache: string;
2824
private xCodeVerCache: string;
2925
private npmVerCache: string;
@@ -53,26 +49,14 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo {
5349
private winReg: WinReg,
5450
private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo) { }
5551

56-
public getJavaVersion(): Promise<string> {
57-
return this.getValueForProperty(() => this.javaVerCache, async (): Promise<string> => {
58-
try {
59-
const spawnResult = await this.childProcess.spawnFromEvent("java", ["-version"], "exit");
60-
const matches = spawnResult && SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr);
61-
return matches && matches[1];
62-
} catch (err) {
63-
return null;
64-
}
65-
});
66-
}
67-
6852
public getJavaCompilerVersion(): Promise<string> {
6953
return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise<string> => {
7054
const javaCompileExecutableName = "javac";
7155
const javaHome = process.env["JAVA_HOME"];
7256
const pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName;
7357
try {
7458
const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`);
75-
return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1];
59+
return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(`${output.stderr}${EOL}${output.stdout}`)[1];
7660
} catch (err) {
7761
return null;
7862
}
@@ -245,7 +229,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo {
245229
result.nodeGypVer = await this.getNodeGypVersion();
246230

247231
result.dotNetVer = await this.hostInfo.dotNetVersion();
248-
result.javaVer = await this.getJavaVersion();
249232
result.javacVersion = await this.getJavaCompilerVersion();
250233
result.xcodeVer = await this.getXcodeVersion();
251234
result.xcodeprojGemLocation = await this.getXcodeprojGemLocation();

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
},
2424
"homepage": "https://github.com/NativeScript/nativescript-doctor#readme",
2525
"devDependencies": {
26+
"@types/chai": "4.1.0",
2627
"@types/mocha": "2.2.32",
2728
"@types/semver": "5.3.30",
2829
"@types/temp": "0.8.29",
2930
"@types/winreg": "1.2.30",
31+
"chai": "4.1.2",
3032
"grunt": "1.0.1",
3133
"grunt-contrib-clean": "1.0.0",
3234
"grunt-contrib-watch": "1.0.0",

0 commit comments

Comments
 (0)