this is a famous problem, which exist since December 2012 - UnreachableBrowserException
So, I made some workaround - was created class, which extends PhantomJSDriver with overridden method "execute":
@Override
protected Response execute(String driverCommand, Map<String, ?> parameters) {
int retryAttempt = 0;
while (true) {
try {
return super.execute(driverCommand, parameters);
} catch (WebDriverException e) {
retryAttempt++;
if (retryAttempt > retryCount) {
throw e;
}
}
}
}
This is was helpful, but not always - sometimes phantomjs process did not stop working. So, I found a way to kill his process by PID (process id)
@Override
protected Response execute(String driverCommand, Map<String, ?> parameters) {
int retryAttempt = 0;
while (true) {
try {
return super.execute(driverCommand, parameters);
} catch (WebDriverException e) {
retryAttempt++;
if (retryAttempt > retryCount) {
if(driverCommand.equalsIgnoreCase("quit")) {
int port = GetDriverPort();
try {
int processID = GetPIDByServerPort(port);
boolean processExist = processID != -1;
if(processExist) {
log.info("Killing phantomJS, of process id:" + processID + " that listen to port:" + port);
KillPhantomProcess(processID);
}
return null;
} catch (IOException | InterruptedException ignore) {
throw e;
}
}
throw e;
}
}
}
}
private int GetDriverPort(){
return ((HttpCommandExecutor)(this).getCommandExecutor()).getAddressOfRemoteServer().getPort();
}
private int GetPIDByServerPort(int port) throws InterruptedException, IOException {
int pid = -1;
ProcessBuilder p = new ProcessBuilder("cmd.exe", "/C", "netstat -no | findstr :" + String.valueOf(port));
p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process netstat = p.start();
netstat.waitFor();
InputStream inputStream = netstat.getInputStream();
int bytesRead;
byte[] bytes = new byte[1024];
String result = "";
while ((bytesRead = inputStream.read(bytes)) > -1) {
result = result + new String(bytes, 0, bytesRead);
}
String[] lines = result.split("\\n+");
for (String line : lines) {
if(!(line.toUpperCase().contains("ESTABLISHED") && line.contains("127.0.0.1:" + port))) continue;
String[] str = line.trim().split("\\s+");
if(str[1].contains(String.valueOf(port))) pid = Integer.parseInt(str[4]);
}
return pid;
}
private void KillPhantomProcess(int pid) throws IOException {
try {
Runtime.getRuntime().exec(TASKKILL_COMMAND + pid);
} catch (IOException e) {
log.error("Failed to kill phantomJs process. PID: " + pid, e);
throw e;
}
if(pid > 0) log.info("phantomJs process " + pid + " was interrupted");
}
I hope this will helpfull