diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/src/main/java/edu/wpi/first/wpilib/plugins/java/launching/JavaLaunchShortcut.java b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/src/main/java/edu/wpi/first/wpilib/plugins/java/launching/JavaLaunchShortcut.java index c67daa32b3..481a4638ab 100644 --- a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/src/main/java/edu/wpi/first/wpilib/plugins/java/launching/JavaLaunchShortcut.java +++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/src/main/java/edu/wpi/first/wpilib/plugins/java/launching/JavaLaunchShortcut.java @@ -2,6 +2,7 @@ package edu.wpi.first.wpilib.plugins.java.launching; import java.io.File; import java.lang.reflect.Method; +import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import java.util.Vector; @@ -15,8 +16,6 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.IStreamListener; -import org.eclipse.debug.core.model.IStreamMonitor; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.ILaunchShortcut; import org.eclipse.jdt.core.IJavaElement; @@ -37,13 +36,13 @@ import edu.wpi.first.wpilib.plugins.java.WPILibJavaPlugin; @SuppressWarnings("restriction") public abstract class JavaLaunchShortcut implements ILaunchShortcut { + private static final int DEBUG_ATTACH_ATTEMPTS = 20; + private static final int DEBUG_ATTACH_RETRY_DELAY_SEC = 2; + //Class constants - used to delineate types for launch shortcuts public static final String DEPLOY_TYPE = "edu.wpi.first.wpilib.plugins.core.deploy"; private static final String ANT_SERVER_THREAD_NAME = "Ant Build Server Connection"; - // NOTE: This string must be changed if the port is changed. - private static final String DEBUG_START_TEXT = "Listening for transport dt_socket at address: 8348"; - private static ILaunch lastDeploy = null; /** @@ -155,11 +154,9 @@ public abstract class JavaLaunchShortcut implements ILaunchShortcut { lastDeploy = AntLauncher.runAntFile(new File (activeProj.getLocation().toOSString() + File.separator + "build.xml"), targets, null, mode); if((mode.equals(ILaunchManager.DEBUG_MODE))&&(getLaunchType().equals(DEPLOY_TYPE))) { - ILaunchConfigurationWorkingCopy config; try { - config = getRemoteDebugConfig(activeProj); - startDebugConfig(config, lastDeploy); - } catch (CoreException e) { + startDebugConfig(getRemoteDebugConfig(activeProj)); + } catch (CoreException | InterruptedException e) { WPILibJavaPlugin.logError("Debug attach failed", e); } } @@ -190,20 +187,28 @@ public abstract class JavaLaunchShortcut implements ILaunchShortcut { return WPILibCore.getDefault().getTargetIP(proj); } - private void startDebugConfig(final ILaunchConfigurationWorkingCopy config, ILaunch deploy) throws CoreException { - IStreamListener listener = new IStreamListener() { - @Override - public void streamAppended(String text, IStreamMonitor monitor) { - if (text.contains(DEBUG_START_TEXT)) { - try { - config.launch(ILaunchManager.DEBUG_MODE, null); - } catch (CoreException e) { - WPILibJavaPlugin.logError("Error starting debug config..", e); - } - monitor.removeListener(this); + private void startDebugConfig(final ILaunchConfigurationWorkingCopy config) + throws CoreException, InterruptedException { + int remainingAttempts = DEBUG_ATTACH_ATTEMPTS; + + // Retry until success or rethrow of exception on failure + while (true) { + try { + WPILibJavaPlugin.logInfo("Attemping to attach debugger..."); + config.launch(ILaunchManager.DEBUG_MODE, null); + WPILibJavaPlugin.logInfo("Debugger attached."); + break; + } catch (CoreException e) { + if (--remainingAttempts > 0) { + String errorMsg = MessageFormat.format("Unable to attach debugger. " + + "{0} attempts remain - waiting {1} second(s) before retrying...", + remainingAttempts, DEBUG_ATTACH_RETRY_DELAY_SEC); + WPILibJavaPlugin.logError(errorMsg, null); + Thread.sleep(DEBUG_ATTACH_RETRY_DELAY_SEC * 1000); + } else { + throw e; } } - }; - deploy.getProcesses()[0].getStreamsProxy().getOutputStreamMonitor().addListener(listener); + } } }