我正在研究一个旧的(Java 6/7)项目,该项目使用ProcessBuilder以与操作系统无关的方式从计算机请求UUID。 我想使用Java 8中的Process.waitFor(long timeout, TimeUnit unit)方法,但是在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;
}