I am working on a legacy (Java 6/7) project that uses ProcessBuilder
to request a UUID from the machine in an OS-agnostic way. I would like to use the Process.waitFor(long timeout, TimeUnit unit)
method from Java 8, but this isn't implemented in Java 6. Instead, I can use waitFor()
, which blocks until completion or an error.
I would like to avoid upgrading the version of Java used to 8 if possible as this necessitates a lot of other changes (migrating code away from removed internal APIs and upgrading a production Tomcat server, for example).
How can I best implement the code for executing the process, with a timeout? I was thinking of somehow implementing a schedule that checks if the process is still running and cancelling/destroying it if it is and the timeout has been reached.
My current (Java 8) code looks like this:
/** USE WMIC on Windows */
private static String getSystemProductUUID() {
String uuid = null;
String line;
List<String> cmd = new ArrayList<String>() {{
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;
}