Skip to content

Commit dc70c9c

Browse files
#272 fix: Command invocation was improved
Also a new system property "appium.node.js.exec.path" has been added and it is supported now.
1 parent 418be7e commit dc70c9c

File tree

4 files changed

+55
-99
lines changed

4 files changed

+55
-99
lines changed

src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java

Lines changed: 50 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020
import com.google.common.collect.ImmutableMap;
2121
import io.appium.java_client.service.local.flags.ServerArgument;
2222
import org.apache.commons.io.FileUtils;
23-
import org.apache.commons.lang3.ArrayUtils;
2423
import org.apache.commons.lang3.StringUtils;
2524
import org.apache.commons.validator.routines.InetAddressValidator;
2625
import org.openqa.selenium.Platform;
26+
import org.openqa.selenium.os.CommandLine;
2727
import org.openqa.selenium.remote.service.DriverService;
2828

2929
import java.io.*;
30-
import java.nio.charset.Charset;
3130
import java.util.*;
3231
import java.util.concurrent.TimeUnit;
3332

@@ -37,123 +36,74 @@
3736

3837
public final class AppiumServiceBuilder extends DriverService.Builder<AppiumDriverLocalService, AppiumServiceBuilder> {
3938

39+
public static final String APPIUM_NODE_PROPERTY = "appium.node.path";
40+
public static final String NODE_JS_EXECUTABLE_PROPERTY = "appium.node.js.exec.path";
41+
4042
private static final String APPIUM_FOLDER = "appium";
4143
private static final String BIN_FOLDER = "bin";
4244
private static final String APPIUM_JS = "appium.js";
4345
private static final String APPIUM_NODE_MASK = File.separator +
4446
APPIUM_FOLDER + File.separator + BIN_FOLDER + File.separator + APPIUM_JS;
4547

46-
public static final String APPIUM_NODE_PROPERTY = "appium.node.path";
4748
public static final String DEFAULT_LOCAL_IP_ADDRESS = "0.0.0.0";
4849

4950
private static final int DEFAULT_APPIUM_PORT = 4723;
5051
private final static String BASH = "bash";
51-
private final static String CMD_EXE[] = {"cmd.exe", "/C"};
52+
private final static String CMD_EXE = "cmd.exe";
5253
private final static String NODE = "node";
53-
private final static String PATH_NAME = getPathVarName();
54-
5554

5655
final Map<String, String> serverArguments = new HashMap<>();
5756
private File appiumJS;
5857
private String ipAddress = DEFAULT_LOCAL_IP_ADDRESS;
5958
private File npmScript;
59+
private File getNodeJSExecutable;
6060

6161
//The first starting is slow sometimes on some
6262
//environment
6363
private long startupTimeout = 120;
6464
private TimeUnit timeUnit = TimeUnit.SECONDS;
6565

66-
private static String getPathVarName(){
67-
Map<String, String> envVariables = System.getenv();
68-
Set<String> keys = envVariables.keySet();
69-
70-
for (String key : keys) {
71-
if (key.toUpperCase().trim().equals("Path".toUpperCase())) {
72-
return key;
73-
}
74-
}
75-
return null;
76-
}
77-
78-
private static String getTheLastStringFromsOutput(InputStream stream ) throws IOException {
79-
BufferedReader reader = new BufferedReader(
80-
new InputStreamReader(stream, Charset.forName("UTF-8")));
81-
String current;
82-
String result = null;
83-
while ((current = reader.readLine()) != null) {
84-
if (StringUtils.isBlank(current)) {
85-
continue;
86-
}
87-
result = current;
88-
}
89-
reader.close();
90-
return result;
91-
}
92-
93-
private static String readErrorStream(Process process) {
94-
BufferedReader reader = new BufferedReader(
95-
new InputStreamReader(process.getErrorStream(), Charset.forName("UTF-8")));
96-
String current;
97-
String result = StringUtils.EMPTY;
98-
try {
99-
while ((current = reader.readLine()) != null) {
100-
if (StringUtils.isBlank(current)) {
101-
continue;
102-
}
103-
result = result + current + "\n";
104-
}
105-
reader.close();
106-
} catch (IOException e) {
107-
throw new RuntimeException(e);
66+
private void setUpNPMScript(){
67+
if (npmScript != null) {
68+
return;
10869
}
109-
return result;
110-
}
11170

112-
private static Process getSearchingProcess(String... command) throws Throwable {
113-
ProcessBuilder processBuilder = new ProcessBuilder(command);
114-
if (!StringUtils.isBlank(PATH_NAME)) {
115-
String path = System.getenv().get(PATH_NAME);
116-
processBuilder.environment().put(PATH_NAME, path);
71+
if (!Platform.getCurrent().is(Platform.WINDOWS)) {
72+
npmScript = Scripts.GET_PATH_TO_DEFAULT_NODE_UNIX.getScriptFile();
11773
}
118-
return processBuilder.start();
11974
}
12075

121-
private void setUpNPMScript(){
122-
if (npmScript != null) {
76+
private void setUpGetNodeJSExecutableScript() {
77+
if (getNodeJSExecutable != null) {
12378
return;
12479
}
12580

126-
if (Platform.getCurrent().is(Platform.WINDOWS)) {
127-
npmScript = NPMScript.GET_PATH_TO_DEFAULT_NODE_WIN.getScriptFile();
128-
}
129-
else {
130-
npmScript = NPMScript.GET_PATH_TO_DEFAULT_NODE_UNIX.getScriptFile();
131-
}
81+
getNodeJSExecutable = Scripts.GET_NODE_JS_EXECUTABLE.getScriptFile();
13282
}
13383

13484
private File findNodeInCurrentFileSystem(){
13585
setUpNPMScript();
13686

13787
String instancePath;
138-
Process p;
88+
CommandLine commandLine;
13989
try {
14090
if (Platform.getCurrent().is(Platform.WINDOWS)) {
141-
p = getSearchingProcess(ArrayUtils.add(CMD_EXE, npmScript.getAbsolutePath()));
142-
p.waitFor();
91+
commandLine = new CommandLine(CMD_EXE, "/C", "npm root -g");
14392
}
14493
else {
145-
p = getSearchingProcess(BASH, "-l", npmScript.getAbsolutePath());
94+
commandLine = new CommandLine(BASH, "-l", npmScript.getAbsolutePath());
14695
}
147-
instancePath = getTheLastStringFromsOutput(p.getInputStream());
96+
commandLine.execute();
14897
} catch (Throwable e) {
14998
throw new RuntimeException(e);
15099
}
151100

101+
instancePath = (commandLine.getStdOut()).trim();
152102
try {
153103
File result;
154104
if (StringUtils.isBlank(instancePath) || !(result = new File(instancePath + File.separator +
155105
APPIUM_NODE_MASK)).exists()) {
156-
String errorOutput = readErrorStream(p);
106+
String errorOutput = commandLine.getStdOut();
157107
throw new InvalidServerInstanceException("There is no installed nodes! Please install " +
158108
" node via NPM (https://www.npmjs.com/package/appium#using-node-js) or download and " +
159109
"install Appium app (http://appium.io/downloads.html)",
@@ -162,7 +112,7 @@ private File findNodeInCurrentFileSystem(){
162112
return result;
163113
}
164114
finally {
165-
p.destroy();
115+
commandLine.destroy();
166116
}
167117
}
168118

@@ -186,41 +136,42 @@ public AppiumServiceBuilder() {
186136

187137
@Override
188138
protected File findDefaultExecutable() {
189-
Process p;
139+
140+
String nodeJSExec = System.getProperty(NODE_JS_EXECUTABLE_PROPERTY);
141+
if (!StringUtils.isBlank(nodeJSExec)) {
142+
File result = new File(nodeJSExec);
143+
if (result.exists()) {
144+
return result;
145+
}
146+
}
147+
148+
CommandLine commandLine;
149+
setUpGetNodeJSExecutableScript();
190150
try {
191151
if (Platform.getCurrent().is(Platform.WINDOWS)) {
192-
p = getSearchingProcess(ArrayUtils.add(CMD_EXE, NODE));
152+
commandLine = new CommandLine(NODE + ".exe", getNodeJSExecutable.getAbsolutePath());
193153
}
194154
else {
195-
p = getSearchingProcess(BASH, "-l", "-c", NODE);
155+
commandLine = new CommandLine(NODE, getNodeJSExecutable.getAbsolutePath());
196156
}
157+
commandLine.execute();
197158
} catch (Throwable t) {
198159
throw new InvalidNodeJSInstance("Node.js is not installed!", t);
199160
}
200161

201-
String filePath;
202-
try {
203-
OutputStream outputStream = p.getOutputStream();
204-
PrintStream out = new PrintStream(outputStream) ;
205-
out.println("console.log(process.execPath);") ;
206-
out.close();
207-
filePath = getTheLastStringFromsOutput(p.getInputStream());
208-
}
209-
catch (Throwable t){
210-
p.destroy();
211-
throw new RuntimeException(t);
212-
}
162+
163+
String filePath = (commandLine.getStdOut()).trim();
213164

214165
try {
215-
if (StringUtils.isBlank(filePath)) {
216-
String errorOutput = readErrorStream(p);
166+
if (StringUtils.isBlank(filePath) || !new File(filePath).exists()) {
167+
String errorOutput = commandLine.getStdOut();
217168
String errorMessage = "Can't get a path to the default Node.js instance";
218169
throw new InvalidNodeJSInstance(errorMessage, new IOException(errorOutput));
219170
}
220171
return new File(filePath);
221172
}
222173
finally {
223-
p.destroy();
174+
commandLine.destroy();
224175
}
225176
}
226177

@@ -394,14 +345,19 @@ protected AppiumDriverLocalService createDriverService(File nodeJSExecutable, in
394345
}
395346
}
396347

397-
@Override
398-
protected void finalize() throws Throwable {
399-
if (npmScript != null) {
348+
private static void disposeCachedFile(File file) {
349+
if (file != null) {
400350
try {
401-
FileUtils.forceDelete(npmScript);
351+
FileUtils.forceDelete(file);
402352
} catch (IOException ignored) {
403353
}
404354
}
355+
}
356+
357+
@Override
358+
protected void finalize() throws Throwable {
359+
disposeCachedFile(npmScript);
360+
disposeCachedFile(getNodeJSExecutable);
405361
super.finalize();
406362
}
407-
}
363+
}

src/main/java/io/appium/java_client/service/local/NPMScript.java renamed to src/main/java/io/appium/java_client/service/local/Scripts.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
import org.apache.commons.io.IOUtils;
2020
import java.io.*;
2121

22-
enum NPMScript {
23-
GET_PATH_TO_DEFAULT_NODE_WIN("get_path_to_default_node.cmd"),
24-
GET_PATH_TO_DEFAULT_NODE_UNIX("get_path_to_default_node.sh")
22+
enum Scripts {
23+
GET_PATH_TO_DEFAULT_NODE_UNIX("get_path_to_default_node.sh"),
24+
GET_NODE_JS_EXECUTABLE("getExe.js")
2525
;
2626
private static final String RESOURCE_FOLDER = "/scripts/";
2727
private final String script;
2828

29-
NPMScript(String script) {
29+
Scripts(String script) {
3030
this.script = script;
3131
}
3232

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(process.execPath);

src/main/resources/scripts/get_path_to_default_node.cmd

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)