Skip to content

Commit 22aa3c5

Browse files
Merge pull request #25 from NativeScript/vladimirov/detect-java-9
Add check for JAVA 9
2 parents e0a9b3b + 156b916 commit 22aa3c5

13 files changed

+122
-88
lines changed

.travis.yml

+1-1
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

-14
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

+21-23
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

+5
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

+2-3
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

+11-3
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

+1-1
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

-1
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

+2-19
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

+2
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",

test/android-tools-info.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { AndroidToolsInfo } from '../lib/android-tools-info';
2+
import { EOL } from 'os';
3+
import { assert } from "chai";
4+
import { ChildProcess } from '../lib/wrappers/child-process';
5+
import { FileSystem } from '../lib/wrappers/file-system';
6+
import { HostInfo } from '../lib/host-info';
7+
import { Helpers } from '../lib/helpers';
8+
import { Constants } from '../lib/constants';
9+
10+
interface ITestData {
11+
javacVersion: string;
12+
warnings?: string[];
13+
}
14+
15+
describe("androidToolsInfo", () => {
16+
const additionalInformation = "You will not be able to build your projects for Android." + EOL
17+
+ "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 +
18+
" described in " + Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform];
19+
20+
const getAndroidToolsInfo = (): AndroidToolsInfo => {
21+
const childProcess: ChildProcess = <any>{};
22+
const fs: FileSystem = <any>{};
23+
const hostInfo: HostInfo = <any>{};
24+
const helpers: Helpers = new Helpers(<any>{});
25+
return new AndroidToolsInfo(childProcess, fs, hostInfo, helpers);
26+
};
27+
28+
describe("validateJavacVersion", () => {
29+
const testData: ITestData[] = [
30+
{
31+
javacVersion: "1.8.0"
32+
},
33+
{
34+
javacVersion: "1.8.0_152"
35+
},
36+
{
37+
javacVersion: "9",
38+
warnings: ["Javac version 9 is not supported. You have to install version 1.8.0."]
39+
},
40+
{
41+
javacVersion: "9.0.1",
42+
warnings: ["Javac version 9.0.1 is not supported. You have to install version 1.8.0."]
43+
},
44+
{
45+
javacVersion: "1.7.0",
46+
warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0."]
47+
},
48+
{
49+
javacVersion: "1.7.0_132",
50+
warnings: ["Javac version 1.7.0_132 is not supported. You have to install at least 1.8.0."]
51+
},
52+
{
53+
javacVersion: null,
54+
warnings: ["Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."]
55+
}
56+
];
57+
58+
testData.forEach(({ javacVersion, warnings }) => {
59+
it(`returns correct result when version is ${javacVersion}`, () => {
60+
const androidToolsInfo = getAndroidToolsInfo();
61+
const actualWarnings = androidToolsInfo.validateJavacVersion(javacVersion);
62+
let expectedWarnings: NativeScriptDoctor.IWarning[] = [];
63+
if (warnings && warnings.length) {
64+
expectedWarnings = warnings.map(warning => {
65+
return {
66+
platforms: [Constants.ANDROID_PLATFORM_NAME],
67+
warning,
68+
additionalInformation
69+
};
70+
});
71+
}
72+
73+
assert.deepEqual(actualWarnings, expectedWarnings);
74+
});
75+
});
76+
});
77+
});

0 commit comments

Comments
 (0)