Bug 211625 - Need option to omit -XstartOnFirstThread for SWT projects
on MacOS
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java
index dddcda8..e329a2b 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2010 IBM Corporation and others.
+ *  Copyright (c) 2000, 2012 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -38,6 +38,8 @@
 	public static String RuntimeClasspathAdvancedDialog_6;
 	public static String RuntimeClasspathAdvancedDialog_7;
 
+	public static String VMArgumentsBlock_0;
+
 	public static String VMArgumentsBlock_VM_Arguments;
 	public static String VMArgumentsBlock_4;
 
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
index b91ad9c..33571dd 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-#  Copyright (c) 2000, 2010 IBM Corporation and others.
+#  Copyright (c) 2000, 2012 IBM Corporation and others.
 #  All rights reserved. This program and the accompanying materials
 #  are made available under the terms of the Eclipse Public License v1.0
 #  which accompanies this distribution, and is available at
@@ -18,6 +18,7 @@
 RuntimeClasspathAdvancedDialog_6=Add &Variable String:
 RuntimeClasspathAdvancedDialog_7=Va&riables...
 
+VMArgumentsBlock_0=Use the -&XStartOnFirstThread argument when launching with SWT
 VMArgumentsBlock_VM_Arguments=VM Arguments
 
 JavaConnectTab__Allow_termination_of_remote_VM_6=&Allow termination of remote VM
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/VMArgumentsBlock.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/VMArgumentsBlock.java
index b3070ce..26ef8ac 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/VMArgumentsBlock.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/VMArgumentsBlock.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,8 +12,10 @@
 
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.internal.ui.SWTFactory;
 import org.eclipse.debug.ui.StringVariableSelectionDialog;
 import org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchTab;
 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
@@ -41,6 +43,7 @@
 
 	// VM arguments widgets
 	protected Text fVMArgumentsText;
+	private Button fUseStartOnFirstThread = null;
 	private Button fPgrmArgVariableButton;
 	
 	/**
@@ -92,7 +95,7 @@
 			}
 		});	
 		ControlAccessibleListener.addListener(fVMArgumentsText, group.getText());
-				
+			
 		fPgrmArgVariableButton = createPushButton(group, LauncherMessages.VMArgumentsBlock_4, null);
 		fPgrmArgVariableButton.setFont(font);
 		fPgrmArgVariableButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
@@ -107,13 +110,18 @@
 				}
 			}
 		});
+		
+		if(Platform.OS_MACOSX.equals(Platform.getOS())) {
+			fUseStartOnFirstThread = SWTFactory.createCheckButton(group, LauncherMessages.VMArgumentsBlock_0, null, false, 1);
+		}
 	}
 
 	/**
 	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
 	 */
 	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
-		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, (String)null);		
+		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, (String)null);	
+		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_START_ON_FIRST_THREAD, true);
 	}
 
 	/**
@@ -123,6 +131,9 @@
 	public void initializeFrom(ILaunchConfiguration configuration) {
 		try {
 			fVMArgumentsText.setText(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "")); //$NON-NLS-1$
+			if(fUseStartOnFirstThread != null) {
+				fUseStartOnFirstThread.setSelection(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_START_ON_FIRST_THREAD, true));
+			}
 		} catch (CoreException e) {
 			setErrorMessage(LauncherMessages.JavaArgumentsTab_Exception_occurred_reading_configuration___15 + e.getStatus().getMessage()); 
 			JDIDebugUIPlugin.log(e);			
@@ -134,6 +145,9 @@
 	 */
 	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
 		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, getAttributeValueFrom(fVMArgumentsText));
+		if(fUseStartOnFirstThread != null) {
+			configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_START_ON_FIRST_THREAD, fUseStartOnFirstThread.getSelection());
+		}
 	}
 
 	/**
@@ -144,7 +158,7 @@
 	}
 	
 	/**
-	 * Retuns the string in the text widget, or <code>null</code> if empty.
+	 * Returns the string in the text widget, or <code>null</code> if empty.
 	 * 
 	 * @return text or <code>null</code>
 	 */
diff --git a/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
index 1b3fc1f..36d08bd 100644
--- a/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.launching.macosx; singleton:=true
-Bundle-Version: 3.2.100.qualifier
+Bundle-Version: 3.2.200.qualifier
 Bundle-Activator: org.eclipse.jdt.internal.launching.macosx.MacOSXLaunchingPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java
index 186f690..ad1b50b 100644
--- a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java
+++ b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2011 IBM Corporation and others.
+ *  Copyright (c) 2000, 2012 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -13,27 +13,62 @@
 import java.io.File;
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.jdt.internal.launching.StandardVMDebugger;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
 import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.VMRunnerConfiguration;
 
+/**
+ * Special override for MacOSX wrapping
+ */
 public class MacOSXDebugVMRunner extends StandardVMDebugger {
 	
+	static boolean startonfirstthread = false;
+	
+	/**
+	 * Constructor
+	 * @param vmInstance
+	 */
 	public MacOSXDebugVMRunner(IVMInstall vmInstance) {
 		super(vmInstance);
 	}
 	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.launching.StandardVMDebugger#run(org.eclipse.jdt.launching.VMRunnerConfiguration, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
+	 */
 	@Override
-	protected Process exec(String[] cmdLine, File workingDirectory) throws CoreException {
-		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine), workingDirectory);
+	public void run(VMRunnerConfiguration config, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+		ILaunchConfiguration lconfig = launch.getLaunchConfiguration();
+		if(lconfig != null) {
+			startonfirstthread = lconfig.getAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_START_ON_FIRST_THREAD, true);
+		}
+		super.run(config, launch, monitor);
 	}
 	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.AbstractVMRunner#exec(java.lang.String[], java.io.File)
+	 */
+	@Override
+	protected Process exec(String[] cmdLine, File workingDirectory) throws CoreException {
+		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine, startonfirstthread), workingDirectory);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.AbstractVMRunner#exec(java.lang.String[], java.io.File, java.lang.String[])
+	 */
 	@Override
 	protected Process exec(String[] cmdLine, File workingDirectory, String[] envp) throws CoreException {
-		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine), workingDirectory, envp);
+		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine, startonfirstthread), workingDirectory, envp);
 	}	
 	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.launching.StandardVMRunner#renderCommandLine(java.lang.String[])
+	 */
 	@Override
 	protected String renderCommandLine(String[] commandLine) {
-		return super.renderCommandLine(MacOSXLaunchingPlugin.wrap(getClass(), commandLine));
+		return super.renderCommandLine(MacOSXLaunchingPlugin.wrap(getClass(), commandLine, startonfirstthread));
 	}
 }
diff --git a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXLaunchingPlugin.java b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXLaunchingPlugin.java
index 26f77a0..513d873 100644
--- a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXLaunchingPlugin.java
+++ b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXLaunchingPlugin.java
@@ -55,12 +55,18 @@
 		return getDefault().getBundle().getSymbolicName();
 	}
 
-	static String[] wrap(Class<?> clazz, String[] cmdLine) {
+	/**
+	 * @param clazz
+	 * @param cmdLine
+	 * @param startonfirstthread
+	 * @return
+	 */
+	static String[] wrap(Class<?> clazz, String[] cmdLine, boolean startonfirstthread) {
 		
 		for (int i= 0; i < cmdLine.length; i++) {
 			// test whether we depend on SWT
 			if (useSWT(cmdLine[i]))
-				return createSWTlauncher(clazz, cmdLine, cmdLine[0]);
+				return createSWTlauncher(clazz, cmdLine, cmdLine[0], startonfirstthread);
 		}
 		return cmdLine;
 	}
@@ -79,15 +85,18 @@
 	 * @param clazz the class
 	 * @param cmdLine the old command line
 	 * @param vmVersion the version of the VM
+	 * @param startonfirstthread
 	 * @return the new command line
 	 * 
 	 */
-	static String[] createSWTlauncher(Class<?> clazz, String[] cmdLine, String vmVersion) {
+	static String[] createSWTlauncher(Class<?> clazz, String[] cmdLine, String vmVersion, boolean startonfirstthread) {
 		
 		// the following property is defined if Eclipse is started via java_swt
 		String java_swt= System.getProperty("org.eclipse.swtlauncher");	//$NON-NLS-1$
 		
-		if (java_swt == null) {	
+		//newer VMs and non-MacOSX VMs don't like "-XstartOnFirstThread"
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=211625
+		if (java_swt == null && startonfirstthread) {	
 			// not started via java_swt -> now we require that the VM supports the "-XstartOnFirstThread" option
 			String[] newCmdLine= new String[cmdLine.length+1];
 			int argCount= 0;
diff --git a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java
index fa1b912..2866e8e 100644
--- a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java
+++ b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2011 IBM Corporation and others.
+ *  Copyright (c) 2000, 2012 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -13,27 +13,50 @@
 import java.io.*;
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.jdt.internal.launching.StandardVMRunner;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
 import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.VMRunnerConfiguration;
 
 public class MacOSXVMRunner extends StandardVMRunner {
 	
+	static boolean startonfirstthread = false;
+	
+	/**
+	 * Constructor
+	 * @param vmInstance
+	 */
 	public MacOSXVMRunner(IVMInstall vmInstance) {
 		super(vmInstance);
 	}
 	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.launching.StandardVMDebugger#run(org.eclipse.jdt.launching.VMRunnerConfiguration, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	@Override
+	public void run(VMRunnerConfiguration config, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+		ILaunchConfiguration lconfig = launch.getLaunchConfiguration();
+		if(lconfig != null) {
+			startonfirstthread = lconfig.getAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_START_ON_FIRST_THREAD, true);
+		}
+		super.run(config, launch, monitor);
+	}
+	
 	@Override
 	protected Process exec(String[] cmdLine, File workingDirectory) throws CoreException {
-		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine), workingDirectory);
+		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine, startonfirstthread), workingDirectory);
 	}
 
 	@Override
 	protected Process exec(String[] cmdLine, File workingDirectory, String[] envp) throws CoreException {
-		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine), workingDirectory, envp);
+		return super.exec(MacOSXLaunchingPlugin.wrap(getClass(), cmdLine, startonfirstthread), workingDirectory, envp);
 	}
 	
 	@Override
 	protected String renderCommandLine(String[] commandLine) {
-		return super.renderCommandLine(MacOSXLaunchingPlugin.wrap(getClass(), commandLine));
+		return super.renderCommandLine(MacOSXLaunchingPlugin.wrap(getClass(), commandLine, startonfirstthread));
 	}
 }
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
index b487e8c..6365f6e 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -318,6 +318,14 @@
 	public static final String ATTR_BOOTPATH_APPEND = LaunchingPlugin.getUniqueIdentifier() + ".-Xbootclasspath/a:";	 //$NON-NLS-1$
 
 	/**
+	 * Attribute key for a Mac OSX VM-specific argument. Value is a boolean
+	 * indicating if the <code>-XStartOnFirstThread</code> argument should be used 
+	 * when launching.
+	 * 
+	 * @since 3.7
+	 */
+	public static final String ATTR_USE_START_ON_FIRST_THREAD = LaunchingPlugin.getUniqueIdentifier() + ".ATTR_USE_START_ON_FIRST_THREAD"; //$NON-NLS-1$
+	/**
 	 * Status code indicating a launch configuration does not
 	 * specify a project when a project is required.
 	 */