|
12 | 12 | *******************************************************************************/ |
13 | 13 | package org.eclipse.lemminx.commons; |
14 | 14 |
|
15 | | -import static org.eclipse.lemminx.utils.platform.Platform.isWindows; |
16 | | - |
17 | | -import java.io.IOException; |
| 15 | +import java.util.Optional; |
18 | 16 | import java.util.concurrent.Executors; |
19 | 17 | import java.util.concurrent.ScheduledExecutorService; |
20 | 18 | import java.util.concurrent.ScheduledFuture; |
21 | 19 | import java.util.concurrent.TimeUnit; |
22 | 20 | import java.util.function.Function; |
23 | | -import java.util.logging.Level; |
24 | 21 | import java.util.logging.Logger; |
25 | 22 |
|
26 | | -import com.google.common.io.Closeables; |
27 | | - |
28 | 23 | import org.eclipse.lsp4j.jsonrpc.MessageConsumer; |
29 | 24 | import org.eclipse.lsp4j.services.LanguageServer; |
30 | 25 |
|
|
36 | 31 | public final class ParentProcessWatcher implements Runnable, Function<MessageConsumer, MessageConsumer> { |
37 | 32 |
|
38 | 33 | private static final Logger LOGGER = Logger.getLogger(ParentProcessWatcher.class.getName()); |
39 | | - private static final boolean isJava1x = System.getProperty("java.version").startsWith("1."); |
40 | 34 |
|
41 | 35 | /** |
42 | 36 | * Exit code returned when XML Language Server is forced to exit. |
@@ -84,55 +78,8 @@ private boolean parentProcessStillRunning() { |
84 | 78 | if (pid == 0 || lastActivityTime > (System.currentTimeMillis() - INACTIVITY_DELAY_SECS)) { |
85 | 79 | return true; |
86 | 80 | } |
87 | | - String command; |
88 | | - if (isWindows) { |
89 | | - command = "cmd /c \"tasklist /FI \"PID eq " + pid + "\" | findstr " + pid + "\""; |
90 | | - } else { |
91 | | - command = "kill -0 " + pid; |
92 | | - } |
93 | | - Process process = null; |
94 | | - boolean finished = false; |
95 | | - try { |
96 | | - process = Runtime.getRuntime().exec(command); |
97 | | - finished = process.waitFor(POLL_DELAY_SECS, TimeUnit.SECONDS); |
98 | | - if (!finished) { |
99 | | - process.destroy(); |
100 | | - finished = process.waitFor(POLL_DELAY_SECS, TimeUnit.SECONDS); // wait for the process to stop |
101 | | - } |
102 | | - if (isWindows && finished && process.exitValue() > 1) { |
103 | | - // the tasklist command should return 0 (parent process exists) or 1 (parent process doesn't exist) |
104 | | - LOGGER.warning("The tasklist command: '" + command + "' returns " + process.exitValue()); |
105 | | - return true; |
106 | | - } |
107 | | - return !finished || process.exitValue() == 0; |
108 | | - } catch (IOException | InterruptedException e) { |
109 | | - LOGGER.log(Level.WARNING, e.getMessage(), e); |
110 | | - return true; |
111 | | - } finally { |
112 | | - if (process != null) { |
113 | | - if (!finished) { |
114 | | - process.destroyForcibly(); |
115 | | - } |
116 | | - // Terminating or destroying the Process doesn't close the process handle on Windows. |
117 | | - // It is only closed when the Process object is garbage collected (in its finalize() method). |
118 | | - // On Windows, when the Java LS is idle, we need to explicitly request a GC, |
119 | | - // to prevent an accumulation of zombie processes, as finalize() will be called. |
120 | | - if (isWindows) { |
121 | | - // Java >= 9 doesn't close the handle when the process is garbage collected |
122 | | - // We need to close the opened streams |
123 | | - if (!isJava1x) { |
124 | | - Closeables.closeQuietly(process.getInputStream()); |
125 | | - Closeables.closeQuietly(process.getErrorStream()); |
126 | | - try { |
127 | | - Closeables.close(process.getOutputStream(), false); |
128 | | - } catch (IOException e) { |
129 | | - } |
130 | | - } |
131 | | - System.gc(); |
132 | | - } |
133 | | - } |
134 | | - } |
135 | | - |
| 81 | + Optional<ProcessHandle> optionalHandle = ProcessHandle.of(pid); |
| 82 | + return !optionalHandle.isEmpty() && optionalHandle.get().isAlive(); |
136 | 83 | } |
137 | 84 |
|
138 | 85 | @Override |
|
0 commit comments