我正在研究一个遗留的(Java 6/7)项目,它使用
ProcessBuilder
以操作系统不可知的方式从机器请求uuid。我想用
Process.waitFor(long timeout, TimeUnit unit)
方法从
Java 8
,但这不是在Java 6中实现的。相反,我可以用
waitFor()
,它将阻塞直到完成或出错。
如果可能的话,我希望避免将Java版本升级到8,因为这就需要进行很多其他的更改(例如,迁移代码从删除的内部API和升级生产Tomcat服务器)。
如何在超时的情况下最好地实现用于执行进程的代码?我正在考虑以某种方式实现一个时间表,检查进程是否仍在运行,如果进程仍在运行,则取消/销毁它,并且已达到超时时间。
我的当前(Java 8)代码看起来像这样:
/** USE WMIC on Windows */
private static String getSystemProductUUID() {
String uuid = null;
String line;
List cmd = new ArrayList() {{
add("WMIC.exe"); add("csproduct"); add("get"); add("UUID");
}};
BufferedReader br = null;
Process p = null;
SimpleLogger.debug("Attempting to retrieve Windows System UUID through WMIC ...");
try {
ProcessBuilder pb = new ProcessBuilder().directory(getExecDir());
p = pb.command(cmd).start();
if (!p.waitFor(TIMEOUT, SECONDS)) { // No timeout in Java 6
throw new IOException("Timeout reached while waiting for UUID from WMIC!");
}
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine()) != null) {
if (null != line) {
line = line.replace("\t", "").replace(" ", "");
if (!line.isEmpty() && !line.equalsIgnoreCase("UUID")) {
uuid = line.replace("-", "");
}
}
}
} catch (IOException | InterruptedException ex) {
uuid = null;
SimpleLogger.error(
"Failed to retrieve machine UUID from WMIC!" + SimpleLogger.getPrependedStackTrace(ex)
);
// ex.printStackTrace(System.err);
} finally {
if (null != br) {
try {
br.close();
} catch (IOException ex) {
SimpleLogger.warn(
"Failed to close buffered reader while retrieving machine UUID!"
);
}
if (null != p) {
p.destroy();
}
}
}
return uuid;
}