在构建服务器上运行phatomjs / java集成测试后,phantomjs进程仍然在后台运行,必须手动终止。
有没有办法在java代码中执行此操作?我已经在测试清理部分使用了driver.quit()。还有其他什么还要包括在内吗?
答案 0 :(得分:10)
处理这个问题的最简单方法(不一定是正式的方法)是从bash脚本中发出一个终止所有phantomjs进程的kill命令:
ps -ef | grep phantomjs | awk '{print $2}' | xargs sudo kill -9
在终端中运行的上述脚本将终止所有后台幻像,无论你是使用java还是python或ruby启动它们... 一个快速的解决方法,直到实际的bug得到解决,imo。
答案 1 :(得分:0)
这是一个着名的问题,自2012年12月以来一直存在 - UnreachableBrowserException
所以,我做了一些解决方法 - 创建了类,它使用重写方法“execute”扩展了PhantomJSDriver:
@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;
}
}
}
}
这是有帮助的,但并非总是如此 - 有时phantomjs过程并没有停止工作。所以,我找到了一种通过PID(进程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");
}
我希望这会有所帮助