Skip to content

Commit 125296a

Browse files
committed
GH-616 implement timeout for some Attach API commands (windows only)
1 parent 04c4869 commit 125296a

File tree

2 files changed

+84
-15
lines changed

2 files changed

+84
-15
lines changed

visualvm/attach/src/org/graalvm/visualvm/attach/AttachModelImpl.java

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,17 @@
3737
import java.util.HashMap;
3838
import java.util.Map;
3939
import java.util.Properties;
40+
import java.util.concurrent.Callable;
41+
import java.util.concurrent.ExecutionException;
42+
import java.util.concurrent.ExecutorService;
43+
import java.util.concurrent.Executors;
44+
import java.util.concurrent.Future;
45+
import java.util.concurrent.TimeUnit;
46+
import java.util.concurrent.TimeoutException;
4047
import java.util.logging.Level;
4148
import java.util.logging.Logger;
49+
import javax.swing.SwingUtilities;
50+
import org.openide.util.Utilities;
4251
import sun.tools.attach.HotSpotVirtualMachine;
4352

4453
/**
@@ -51,6 +60,7 @@ class AttachModelImpl extends AttachModel {
5160
private static final String HEAP_DUMP_NO_SPACE_ID = "No space left on device"; // NOI18N
5261
private static final String JCMD_VM_COMMAND_LINE = "VM.command_line"; // NOI18N
5362
static final Logger LOGGER = Logger.getLogger(AttachModelImpl.class.getName());
63+
private static final ExecutorService winExec = Executors.newCachedThreadPool();
5464

5565
String pid;
5666
HotSpotVirtualMachine vm;
@@ -60,13 +70,33 @@ class AttachModelImpl extends AttachModel {
6070
pid = Integer.toString(app.getPid());
6171
}
6272

63-
public synchronized Properties getSystemProperties() {
73+
// see JmxModelImpl$LocalVirtualMachine.executeAndWait
74+
private static <V> V executeAndWait(Callable<V> call) {
75+
if (Utilities.isWindows()) {
76+
Future<V> result = winExec.submit(call);
77+
try {
78+
return result.get(SwingUtilities.isEventDispatchThread() ? 5 : 25, TimeUnit.SECONDS);
79+
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
80+
LOGGER.log(Level.INFO, "executeAndWait get", ex); // NOI18N
81+
}
82+
return null;
83+
}
6484
try {
65-
return getVirtualMachine().getSystemProperties();
66-
} catch (IOException ex) {
67-
LOGGER.log(Level.INFO,"getSystemProperties",ex); // NOI18N
85+
return call.call();
86+
} catch (Exception ex) {
87+
throw new RuntimeException(ex);
6888
}
69-
return null;
89+
}
90+
91+
public synchronized Properties getSystemProperties() {
92+
return executeAndWait(() -> {
93+
try {
94+
return getVirtualMachine().getSystemProperties();
95+
} catch (IOException ex) {
96+
LOGGER.log(Level.INFO,"getSystemProperties",ex); // NOI18N
97+
}
98+
return null;
99+
});
70100
}
71101

72102
public synchronized boolean takeHeapDump(String fileName) {
@@ -209,13 +239,15 @@ private synchronized Map<String,String> getVMCommandLine() {
209239
}
210240

211241
private synchronized String executeJCmd(String command) {
212-
try {
213-
InputStream in = getVirtualMachine().executeJCmd(command);
214-
return readToEOF(in);
215-
} catch (IOException ex) {
216-
LOGGER.log(Level.INFO,"executeJCmd",ex); // NOI18N
217-
}
218-
return null;
242+
return executeAndWait(() -> {
243+
try {
244+
InputStream in = getVirtualMachine().executeJCmd(command);
245+
return readToEOF(in);
246+
} catch (IOException ex) {
247+
LOGGER.log(Level.INFO, "executeJCmd", ex); // NOI18N
248+
}
249+
return null;
250+
});
219251
}
220252

221253
private String readToEOF(InputStream in) throws IOException {

visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxModelImpl.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,18 @@
4444
import java.util.Map;
4545
import java.util.Properties;
4646
import java.util.StringTokenizer;
47+
import java.util.concurrent.Callable;
48+
import java.util.concurrent.ExecutionException;
49+
import java.util.concurrent.ExecutorService;
50+
import java.util.concurrent.Executors;
51+
import java.util.concurrent.Future;
52+
import java.util.concurrent.TimeUnit;
53+
import java.util.concurrent.TimeoutException;
4754
import java.util.logging.Level;
4855
import java.util.logging.Logger;
4956
import javax.management.MBeanServerConnection;
5057
import javax.management.remote.JMXServiceURL;
58+
import javax.swing.SwingUtilities;
5159
import org.graalvm.visualvm.application.Application;
5260
import org.graalvm.visualvm.application.jvm.HeapHistogram;
5361
import org.graalvm.visualvm.core.VisualVM;
@@ -63,6 +71,7 @@
6371
import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;
6472
import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;
6573
import org.graalvm.visualvm.tools.jvmstat.JvmstatModel;
74+
import org.openide.util.Utilities;
6675

6776
/**
6877
* This class encapsulates the JMX functionality of the target Java application.
@@ -436,6 +445,8 @@ private String createTracedMessage(String message, Throwable thrwbl) {
436445
}
437446

438447
static class LocalVirtualMachine {
448+
private static ExecutorService winExec = Executors.newCachedThreadPool();
449+
439450
private int vmid;
440451
private boolean isAttachSupported;
441452
private String javaHome;
@@ -472,8 +483,15 @@ synchronized void startManagementAgent() throws IOException {
472483
throw new IOException("This virtual machine \"" + vmid + // NOI18N
473484
"\" does not support dynamic attach."); // NOI18N
474485
}
475-
476-
loadManagementAgent();
486+
executeAndWait(() -> {
487+
try {
488+
loadManagementAgent();
489+
} catch (IOException ex) {
490+
LOGGER.log(Level.INFO, "loadManagementAgent for PID "+vmid+" failed", ex); // NOI18N
491+
}
492+
// rerurn void
493+
return null;
494+
});
477495
// fails to load or start the management agent
478496
if (address == null) {
479497
// should never reach here
@@ -485,10 +503,11 @@ synchronized String connectorAddress() {
485503
// return null if not available or no JMX agent
486504
return address;
487505
}
506+
488507
private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
489508
"com.sun.management.jmxremote.localConnectorAddress"; // NOI18N
490509

491-
private synchronized void loadManagementAgent() throws IOException {
510+
private void loadManagementAgent() throws IOException {
492511
VirtualMachine vm = null;
493512
String name = String.valueOf(vmid);
494513
try {
@@ -543,5 +562,23 @@ private String loadManagementAgentViaJcmd(VirtualMachine vm) {
543562
}
544563
return null;
545564
}
565+
566+
// see AttachModelImpl.executeAndWait
567+
private static <V> V executeAndWait(Callable<V> call) {
568+
if (Utilities.isWindows()) {
569+
Future<V> result = winExec.submit(call);
570+
try {
571+
return result.get(SwingUtilities.isEventDispatchThread() ? 5 : 25, TimeUnit.SECONDS);
572+
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
573+
LOGGER.log(Level.INFO, "executeAndWait get", ex); // NOI18N
574+
}
575+
return null;
576+
}
577+
try {
578+
return call.call();
579+
} catch (Exception ex) {
580+
throw new RuntimeException(ex);
581+
}
582+
}
546583
}
547584
}

0 commit comments

Comments
 (0)