diff --git a/plugins/org.springframework.ide.eclipse.beans.ui.livegraph/src/org/springframework/ide/eclipse/beans/ui/livegraph/model/LiveBeansModelGenerator.java b/plugins/org.springframework.ide.eclipse.beans.ui.livegraph/src/org/springframework/ide/eclipse/beans/ui/livegraph/model/LiveBeansModelGenerator.java index 4260ee50ae..28c5bcfa45 100644 --- a/plugins/org.springframework.ide.eclipse.beans.ui.livegraph/src/org/springframework/ide/eclipse/beans/ui/livegraph/model/LiveBeansModelGenerator.java +++ b/plugins/org.springframework.ide.eclipse.beans.ui.livegraph/src/org/springframework/ide/eclipse/beans/ui/livegraph/model/LiveBeansModelGenerator.java @@ -15,6 +15,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.management.InstanceNotFoundException; import javax.management.MBeanServerConnection; @@ -26,8 +28,10 @@ import javax.management.remote.JMXServiceURL; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.json.JSONException; import org.springframework.context.support.LiveBeansViewMBean; import org.springframework.ide.eclipse.beans.ui.livegraph.LiveGraphUiPlugin; @@ -44,8 +48,10 @@ public class LiveBeansModelGenerator { /** * This method will not attempt to close the given {@link JMXConnector}. If * the connection has failed, clients may capture the thrown - * {@link CoreException} and inform the user. This method will never return - * a null {@link LiveBeansModel} + * {@link CoreException} and inform the user. This method is not UI safe, + * and may block the UI with network operations. Clients will need to call + * this method from a non-blocking {@link Job}. This method will never + * return a null {@link LiveBeansModel} * * @param connector * @param appName @@ -87,7 +93,8 @@ public static LiveBeansModel connectToModel(JMXConnector connector, String appNa * This method will attempt to create a {@link JMXConnector} from the given * parameters and will close it when it is finished. If the connection has * failed, clients may capture the thrown {@link CoreException} and inform - * the user. This method will never return a null + * the user. This method is UI safe, and will not block the UI with network + * operations. It will never return a null * {@link LiveBeansModel} * * @param serviceUrl @@ -98,24 +105,52 @@ public static LiveBeansModel connectToModel(JMXConnector connector, String appNa * failed * @throws CoreException */ - public static LiveBeansModel connectToModel(String serviceUrl, String username, String password, String appName) - throws CoreException { - JMXConnector connector = null; - try { - connector = setupConnector(serviceUrl, username, password); - return connectToModel(connector, appName); - } - finally { - if (connector != null) { + public static LiveBeansModel connectToModel(final String serviceUrl, final String username, final String password, + final String appName) throws CoreException { + final CountDownLatch latch = new CountDownLatch(1); + final LiveBeansModel[] result = new LiveBeansModel[1]; + final CoreException[] status = new CoreException[1]; + + Job jmxOperation = new Job("Executing Server Command") { + @Override + protected IStatus run(IProgressMonitor monitor) { + JMXConnector connector = null; try { - connector.close(); + connector = setupConnector(serviceUrl, username, password); + result[0] = connectToModel(connector, appName); + } + catch (CoreException e) { + status[0] = e; } - catch (IOException e) { - StatusHandler.log(new Status(IStatus.ERROR, LiveGraphUiPlugin.PLUGIN_ID, - "An error occurred while closing connection to server.", e)); + finally { + latch.countDown(); + if (connector != null) { + try { + connector.close(); + } + catch (IOException e) { + StatusHandler.log(new Status(IStatus.ERROR, LiveGraphUiPlugin.PLUGIN_ID, + "An error occurred while closing connection to server.", e)); + } + } } + return Status.OK_STATUS; } + }; + jmxOperation.schedule(); + + try { + if (latch.await(30, TimeUnit.SECONDS)) { + if (status[0] != null) { + throw status[0]; + } + return result[0]; + } + } + catch (InterruptedException e) { + // swallowed } + return new LiveBeansModel(); } private static LiveBeansModel generateModel(LiveBeansViewMBean mbean, String appName) throws CoreException {