diff options
author | Mike Rennie | 2012-03-05 20:48:40 +0000 |
---|---|---|
committer | Mike Rennie | 2012-03-05 20:48:40 +0000 |
commit | 535d7b50cddb871270ead6a06a4abde56afe9a35 (patch) | |
tree | 3838e65ec37856ec391b958de6269c8aa9542c9c | |
parent | 20b68383657cd467297bd15f92d8b6233809a6c0 (diff) | |
download | eclipse.jdt.debug-535d7b50cddb871270ead6a06a4abde56afe9a35.tar.gz eclipse.jdt.debug-535d7b50cddb871270ead6a06a4abde56afe9a35.tar.xz eclipse.jdt.debug-535d7b50cddb871270ead6a06a4abde56afe9a35.zip |
Bug 335896 - Investigate support for alternate launching/attachingmrennie/bug335896
connectors
15 files changed, 751 insertions, 26 deletions
diff --git a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF index 0e53906cb..2e80afff4 100644 --- a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF @@ -17,7 +17,7 @@ Export-Package: com.sun.jdi, org.eclipse.jdi, org.eclipse.jdi.hcr, org.eclipse.jdi.internal;x-friends:="org.eclipse.jdt.debug.ui", - org.eclipse.jdi.internal.connect;x-friends:="org.eclipse.jdt.debug.ui", + org.eclipse.jdi.internal.connect;x-friends:="org.eclipse.jdt.debug.ui,org.eclipse.jdt.launching", org.eclipse.jdi.internal.event;x-friends:="org.eclipse.jdt.debug.ui", org.eclipse.jdi.internal.jdwp;x-friends:="org.eclipse.jdt.debug.ui", org.eclipse.jdi.internal.request;x-friends:="org.eclipse.jdt.debug.ui", diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java index 533eda139..4de7e12da 100644 --- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java +++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java @@ -160,6 +160,13 @@ public class VirtualMachineImpl extends MirrorImpl implements VirtualMachine, private PacketSendManager fPacketSendManager; /** + * Constructor + */ + public VirtualMachineImpl() { + super("RMI"); //$NON-NLS-1$ + } + + /** * Creates a new Virtual Machine. */ public VirtualMachineImpl(Connection connection) { diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java index 0d13fe3a5..58b3494e2 100644 --- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java +++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java @@ -23,6 +23,8 @@ import java.util.PropertyResourceBundle; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IPreferencesService; +import org.eclipse.jdi.internal.connect.SACoreAttachingConnectorImpl; +import org.eclipse.jdi.internal.connect.SACoreDebugServerAttachingConnectorImpl; import org.eclipse.jdi.internal.connect.SocketAttachingConnectorImpl; import org.eclipse.jdi.internal.connect.SocketLaunchingConnectorImpl; import org.eclipse.jdi.internal.connect.SocketListeningConnectorImpl; @@ -190,6 +192,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { public List<AttachingConnector> attachingConnectors() { ArrayList<AttachingConnector> list = new ArrayList<AttachingConnector>(1); list.add(new SocketAttachingConnectorImpl(this)); + list.add(new SACoreAttachingConnectorImpl(this)); + list.add(new SACoreDebugServerAttachingConnectorImpl(this)); return list; } diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java index aa1b36e66..7e942c8b2 100644 --- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java +++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java @@ -18,6 +18,28 @@ public class ConnectMessages extends NLS { public static String PacketReceiveManager_Got_IOException_from_Virtual_Machine_1; public static String PacketReceiveManager_Got_IOException_from_Virtual_Machine_2; public static String PacketSendManager_Got_IOException_from_Virtual_Machine_1; + public static String SACoreAttachingConnectorImpl_0; + + public static String SACoreAttachingConnectorImpl_1; + + public static String SACoreAttachingConnectorImpl_2; + + public static String SACoreAttachingConnectorImpl_3; + + public static String SACoreAttachingConnectorImpl_4; + + public static String SACoreDebugServerAttachingConnectorImpl_0; + + public static String SACoreDebugServerAttachingConnectorImpl_1; + + public static String SACoreDebugServerAttachingConnectorImpl_2; + + public static String SACoreDebugServerAttachingConnectorImpl_3; + + public static String SACoreDebugServerAttachingConnectorImpl_4; + + public static String SACoreDebugServerAttachingConnectorImpl_5; + public static String SocketAttachingConnectorImpl_Machine_name_to_which_to_attach_for_VM_connections_1; public static String SocketAttachingConnectorImpl_Host_2; public static String SocketAttachingConnectorImpl_Port_number_to_which_to_attach_for_VM_connections_3; diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties index 01c6a554e..ed7a90fbd 100644 --- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties +++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties @@ -12,6 +12,17 @@ PacketReceiveManager_Got_IOException_from_Virtual_Machine_1=Got IOException from Virtual Machine PacketReceiveManager_Got_IOException_from_Virtual_Machine_2=Got IOException from Virtual Machine PacketSendManager_Got_IOException_from_Virtual_Machine_1=Got IOException from Virtual Machine +SACoreAttachingConnectorImpl_0=The fully qualified path to the core dump file to debug +SACoreAttachingConnectorImpl_1=Core File: +SACoreAttachingConnectorImpl_2=The fully qualified path to the Java executable that generated the core dump to debug +SACoreAttachingConnectorImpl_3=Java Executable: +SACoreAttachingConnectorImpl_4=Attaches to a local core dump file +SACoreDebugServerAttachingConnectorImpl_0=The name of the server running the core dump file +SACoreDebugServerAttachingConnectorImpl_1=Server Name: +SACoreDebugServerAttachingConnectorImpl_2=Attaches to a remote debug server running a core dump file +SACoreDebugServerAttachingConnectorImpl_3=The server name cannot be null +SACoreDebugServerAttachingConnectorImpl_4=The server name is not valid +SACoreDebugServerAttachingConnectorImpl_5=The server name is not bound SocketAttachingConnectorImpl_Machine_name_to_which_to_attach_for_VM_connections_1=Machine name to which to attach for VM connections SocketAttachingConnectorImpl_Host_2=Host: SocketAttachingConnectorImpl_Port_number_to_which_to_attach_for_VM_connections_3=Port number to which to attach for VM connections diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SACoreAttachingConnectorImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SACoreAttachingConnectorImpl.java new file mode 100644 index 000000000..7e42c7f74 --- /dev/null +++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SACoreAttachingConnectorImpl.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdi.internal.connect; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jdi.internal.VirtualMachineManagerImpl; + +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.connect.AttachingConnector; +import com.sun.jdi.connect.Connector; +import com.sun.jdi.connect.IllegalConnectorArgumentsException; + +/** + * The JDI implementation of the SA core attaching connector + * + * @see http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Connectors + * @since 3.8 + */ +public class SACoreAttachingConnectorImpl extends ConnectorImpl implements AttachingConnector { + + public static final String CORE_PATH = "core"; //$NON-NLS-1$ + public static final String JAVA_EXECUTABLE_PATH = "javaExecutable"; //$NON-NLS-1$ + public static final String JDI_CONNECTOR_ID = "sun.jvm.hotspot.jdi.SACoreAttachingConnector"; //$NON-NLS-1$ + + /** + * Constructor + * @param virtualMachineManager + */ + public SACoreAttachingConnectorImpl(VirtualMachineManagerImpl virtualMachineManager) { + super(virtualMachineManager); + } + + /* (non-Javadoc) + * @see com.sun.jdi.connect.Connector#defaultArguments() + */ + public Map<String, Argument> defaultArguments() { + HashMap<String, Argument> args = new HashMap<String, Connector.Argument>(); + StringArgumentImpl arg = new StringArgumentImpl(CORE_PATH, ConnectMessages.SACoreAttachingConnectorImpl_0, ConnectMessages.SACoreAttachingConnectorImpl_1, false); + arg.setValue(""); //$NON-NLS-1$ + args.put(CORE_PATH, arg); + arg = new StringArgumentImpl(JAVA_EXECUTABLE_PATH, ConnectMessages.SACoreAttachingConnectorImpl_2, ConnectMessages.SACoreAttachingConnectorImpl_3, true); + arg.setValue(""); //$NON-NLS-1$ + args.put(JAVA_EXECUTABLE_PATH, arg); + return args; + } + + /* (non-Javadoc) + * @see com.sun.jdi.connect.AttachingConnector#attach(java.util.Map) + */ + public VirtualMachine attach(Map<String, ? extends Argument> arguments) throws IOException, IllegalConnectorArgumentsException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jdi.internal.connect.ConnectorImpl#description() + */ + @Override + public String description() { + return ConnectMessages.SACoreAttachingConnectorImpl_4; + } + + /* (non-Javadoc) + * @see org.eclipse.jdi.internal.connect.ConnectorImpl#name() + */ + @Override + public String name() { + return JDI_CONNECTOR_ID; + } +} diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SACoreDebugServerAttachingConnectorImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SACoreDebugServerAttachingConnectorImpl.java new file mode 100644 index 000000000..fd4fbd9de --- /dev/null +++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SACoreDebugServerAttachingConnectorImpl.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdi.internal.connect; + +import java.io.IOException; +import java.rmi.ConnectException; +import java.rmi.Naming; +import java.rmi.NotBoundException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jdi.internal.VirtualMachineImpl; +import org.eclipse.jdi.internal.VirtualMachineManagerImpl; + +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.connect.AttachingConnector; +import com.sun.jdi.connect.Connector; +import com.sun.jdi.connect.IllegalConnectorArgumentsException; +import com.sun.jdi.connect.Transport; + +/** + * The JDI implementation of the SA core debug server attaching connector + * + * @see http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Connectors + * @since 3.8 + */ +public class SACoreDebugServerAttachingConnectorImpl extends ConnectorImpl implements AttachingConnector { + + public static final String DEBUG_SERVER_NAME = "debugServerName"; //$NON-NLS-1$ + public static final String JDI_CONNECTOR_ID = "sun.jvm.hotspot.jdi.SADebugServerAttachingConnector"; //$NON-NLS-1$ + + Transport fTransport = new Transport() { + public String name() { + return "RMI"; //$NON-NLS-1$ + } + }; + + /** + * Constructor + * @param virtualMachineManager + */ + public SACoreDebugServerAttachingConnectorImpl(VirtualMachineManagerImpl virtualMachineManager) { + super(virtualMachineManager); + } + + /* (non-Javadoc) + * @see com.sun.jdi.connect.Connector#defaultArguments() + */ + public Map<String, Argument> defaultArguments() { + HashMap<String, Argument> args = new HashMap<String, Connector.Argument>(); + StringArgumentImpl arg = new StringArgumentImpl(DEBUG_SERVER_NAME, ConnectMessages.SACoreDebugServerAttachingConnectorImpl_0, ConnectMessages.SACoreDebugServerAttachingConnectorImpl_1, true); + arg.setValue(""); //$NON-NLS-1$ + args.put(DEBUG_SERVER_NAME, arg); + return args; + } + + /* (non-Javadoc) + * @see com.sun.jdi.connect.AttachingConnector#attach(java.util.Map) + */ + public VirtualMachine attach(Map<String, ? extends Argument> arguments) throws IOException, IllegalConnectorArgumentsException { + String servername = arguments.get(DEBUG_SERVER_NAME).value(); + if(servername == null) { + throw new IllegalConnectorArgumentsException(ConnectMessages.SACoreDebugServerAttachingConnectorImpl_3, DEBUG_SERVER_NAME); + } + if(servername.length() < 1) { + throw new IllegalConnectorArgumentsException(ConnectMessages.SACoreDebugServerAttachingConnectorImpl_4, DEBUG_SERVER_NAME); + } + VirtualMachineImpl vm = null; + try { + Remote remote = Naming.lookup("rmi://"+servername); //$NON-NLS-1$ + System.out.println(remote.toString()); + vm = new VirtualMachineImpl(); + } + catch (NotBoundException e) { + throw new ConnectException(ConnectMessages.SACoreDebugServerAttachingConnectorImpl_5, e); + } + catch(RemoteException re) { + throw new ConnectException(ConnectMessages.SACoreDebugServerAttachingConnectorImpl_5, re); + } + return vm; + } + + /* (non-Javadoc) + * @see org.eclipse.jdi.internal.connect.ConnectorImpl#description() + */ + @Override + public String description() { + return ConnectMessages.SACoreDebugServerAttachingConnectorImpl_2; + } + + /* (non-Javadoc) + * @see org.eclipse.jdi.internal.connect.ConnectorImpl#name() + */ + @Override + public String name() { + return JDI_CONNECTOR_ID; + } + + /* (non-Javadoc) + * @see org.eclipse.jdi.internal.connect.ConnectorImpl#transport() + */ + @Override + public Transport transport() { + return fTransport; + } +} diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.java index bea519893..b23d34b8f 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.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 @@ -88,6 +88,22 @@ public class LaunchingMessages extends NLS { public static String libraryLocation_assert_libraryNotNull; + public static String SACoreAttachingConnector_0; + + public static String SACoreAttachingConnector_1; + + public static String SACoreAttachingConnector_2; + + public static String SACoreAttachingConnector_3; + + public static String SACoreAttachingConnector_4; + + public static String SACoreRemoteAttachingConnector_0; + + public static String SACoreRemoteAttachingConnector_1; + + public static String SACoreRemoteAttachingConnector_2; + public static String SocketAttachConnector_Failed_to_connect_to_remote_VM_1; public static String SocketAttachConnector_Socket_attaching_connector_not_available_3; public static String SocketAttachConnector_Standard__Socket_Attach__4; diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties index 0b05d47f4..74fdf6bf8 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.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 @@ -66,6 +66,14 @@ LaunchingPlugin_1=Update Installed JREs libraryLocation_assert_libraryNotNull=library cannot be null +SACoreAttachingConnector_0=Attaching to a local core file and JVM... +SACoreAttachingConnector_1=The fully qualified path to the core file cannot be null +SACoreAttachingConnector_2=The fully qualified path to the Java executable cannot be null +SACoreAttachingConnector_3=Failed to connect to the local VM. +SACoreAttachingConnector_4=SA Core Attaching Connector +SACoreRemoteAttachingConnector_0=SA Debug Server Attaching Connector +SACoreRemoteAttachingConnector_1=Attaching to remote JVM core dump server +SACoreRemoteAttachingConnector_2=The name of the remote server cannot be null SocketAttachConnector_Failed_to_connect_to_remote_VM_1=Failed to connect to remote VM SocketAttachConnector_Socket_attaching_connector_not_available_3=Socket attaching connector not available SocketAttachConnector_Standard__Socket_Attach__4=Standard (Socket Attach) diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SACoreAttachingConnector.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SACoreAttachingConnector.java new file mode 100644 index 000000000..358783074 --- /dev/null +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SACoreAttachingConnector.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.launching; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +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.SubMonitor; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.jdi.Bootstrap; +import org.eclipse.jdi.TimeoutException; +import org.eclipse.jdi.internal.connect.SACoreAttachingConnectorImpl; +import org.eclipse.jdt.debug.core.JDIDebugModel; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; +import org.eclipse.jdt.launching.IVMConnector; +import org.eclipse.osgi.util.NLS; + +import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.connect.AttachingConnector; +import com.sun.jdi.connect.Connector; +import com.sun.jdi.connect.IllegalConnectorArgumentsException; +import com.sun.jdi.connect.Connector.Argument; + +/** + * This {@link Connector} is used to attach to a core dump from a VM. + * <br><br> + * It is worth noting that you can only connect to a core dump that matches the same word size (32bit / 64bit) + * *and* using the same level of VM which produced the core dump. + * <br><br> + * For example a core dump from a 32bit Java 1.6 VM must be debugged only on a 32bit Java 1.6 VM. All others will fail. + * + * @see http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Connectors + * @since 3.8 + */ +public class SACoreAttachingConnector implements IVMConnector { + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#connect(java.util.Map, org.eclipse.core.runtime.IProgressMonitor, org.eclipse.debug.core.ILaunch) + */ + public void connect(Map<String, String> arguments, IProgressMonitor monitor, ILaunch launch) throws CoreException { + SubMonitor lmonitor = SubMonitor.convert(monitor, LaunchingMessages.SACoreAttachingConnector_0, 4); + try { + AttachingConnector connector = getAttachingConnector(); + if(lmonitor.isCanceled()) { + return; + } + lmonitor.worked(1); + String corepath = arguments.get(SACoreAttachingConnectorImpl.CORE_PATH); + if(corepath == null) { + abort(LaunchingMessages.SACoreAttachingConnector_1, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_CORE_FILE); + } + Map<String, Argument> args = connector.defaultArguments(); + Connector.Argument arg = args.get(SACoreAttachingConnectorImpl.CORE_PATH); + arg.setValue(corepath); + if(lmonitor.isCanceled()) { + return; + } + lmonitor.worked(1); + String exepath = arguments.get(SACoreAttachingConnectorImpl.JAVA_EXECUTABLE_PATH); + if(exepath == null) { + abort(LaunchingMessages.SACoreAttachingConnector_2, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_JAVA_EXECUTABLE_PATH); + + } + arg = args.get(SACoreAttachingConnectorImpl.JAVA_EXECUTABLE_PATH); + arg.setValue(exepath); + if(lmonitor.isCanceled()) { + return; + } + lmonitor.worked(1); + try { + VirtualMachine vm = connector.attach(args); + String vmLabel = constructVMLabel(vm, corepath, exepath, launch.getLaunchConfiguration()); + IDebugTarget debugTarget= JDIDebugModel.newDebugTarget(launch, vm, vmLabel, null, false, true); + launch.addDebugTarget(debugTarget); + lmonitor.worked(1); + } + catch(TimeoutException toe) { + abort(LaunchingMessages.SocketAttachConnector_0, toe, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch(UnknownHostException uhe) { + abort(NLS.bind(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_because_of_unknown_host____0___1, new String[]{corepath}), uhe, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch (ConnectException ce) { + abort(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_as_connection_was_refused_2, ce, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch(IOException ioe) { + abort(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_1, ioe, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch (IllegalConnectorArgumentsException icae) { + abort(LaunchingMessages.SACoreAttachingConnector_3, icae, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + } + finally { + if(!lmonitor.isCanceled()) { + lmonitor.done(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getName() + */ + public String getName() { + return LaunchingMessages.SACoreAttachingConnector_4; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getIdentifier() + */ + public String getIdentifier() { + return IJavaLaunchConfigurationConstants.ID_SA_ATTACH_VM_CONNECTOR; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getDefaultArguments() + */ + public Map<String, Argument> getDefaultArguments() throws CoreException { + return getAttachingConnector().defaultArguments(); + } + + /** + * Return the socket transport attaching connector + * + * @return the {@link AttachingConnector} + * @exception CoreException if unable to locate the connector + */ + protected static AttachingConnector getAttachingConnector() throws CoreException { + AttachingConnector connector= null; + Iterator<AttachingConnector> iter= Bootstrap.virtualMachineManager().attachingConnectors().iterator(); + while (iter.hasNext()) { + AttachingConnector lc= iter.next(); + if (lc.name().equals(SACoreAttachingConnectorImpl.JDI_CONNECTOR_ID)) { + connector= lc; + break; + } + } + return connector; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getArgumentOrder() + */ + public List<String> getArgumentOrder() { + ArrayList<String> list = new ArrayList<String>(); + list.add(SACoreAttachingConnectorImpl.CORE_PATH); + list.add(SACoreAttachingConnectorImpl.JAVA_EXECUTABLE_PATH); + return list; + } + + /** + * Throws a core exception with an error status object built from + * the given message, lower level exception, and error code. + * + * @param message the status message + * @param exception lower level exception associated with the + * error, or <code>null</code> if none + * @param code error code + * @throws CoreException if an error occurs + */ + protected void abort(String message, Throwable exception, int code) throws CoreException { + throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), code, message, exception)); + } + + /** + * Helper method that constructs a human-readable label for a remote VM. + * @param vm the VM + * @param corefile the full path to the core file being 'debugged' + * @param javaExecutable the full path to the Java executable + * @param configuration the backing configuration + * @return the new label for the VM + */ + protected String constructVMLabel(VirtualMachine vm, String corefile, String javaExecutable, ILaunchConfiguration configuration) { + String name = null; + try { + name = vm.name(); + } catch (TimeoutException e) { + // do nothing + } catch (VMDisconnectedException e) { + // do nothing + } + if (name == null) { + if (configuration == null) { + name = ""; //$NON-NLS-1$ + } else { + name = configuration.getName(); + } + } + StringBuffer buffer = new StringBuffer(name); + buffer.append('['); + buffer.append(corefile); + buffer.append('@'); + buffer.append(javaExecutable); + buffer.append(']'); + return buffer.toString(); + } +} diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SACoreDebugServerAttachingConnector.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SACoreDebugServerAttachingConnector.java new file mode 100644 index 000000000..517e1546e --- /dev/null +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SACoreDebugServerAttachingConnector.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.launching; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +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.SubMonitor; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.jdi.Bootstrap; +import org.eclipse.jdi.TimeoutException; +import org.eclipse.jdi.internal.connect.SACoreDebugServerAttachingConnectorImpl; +import org.eclipse.jdt.debug.core.JDIDebugModel; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; +import org.eclipse.jdt.launching.IVMConnector; +import org.eclipse.osgi.util.NLS; + +import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.connect.AttachingConnector; +import com.sun.jdi.connect.Connector; +import com.sun.jdi.connect.Connector.Argument; +import com.sun.jdi.connect.IllegalConnectorArgumentsException; + +/** + * This {@link Connector} is used to attach to a remote core dump from a VM. + * <br><br> + * It is worth noting that you can only connect to a core dump that matches the same word size (32bit / 64bit) + * *and* using the same level of VM which produced the core dump. + * <br><br> + * For example a core dump from a 32bit Java 1.6 VM must be debugged only on a 32bit Java 1.6 VM. All others will fail. + * + * @see http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Connectors + * @since 3.8 + */ +public class SACoreDebugServerAttachingConnector implements IVMConnector { + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#connect(java.util.Map, org.eclipse.core.runtime.IProgressMonitor, org.eclipse.debug.core.ILaunch) + */ + public void connect(Map<String, String> arguments, IProgressMonitor monitor, ILaunch launch) throws CoreException { + SubMonitor lmonitor = SubMonitor.convert(monitor, LaunchingMessages.SACoreRemoteAttachingConnector_1, 3); + try { + AttachingConnector connector = getAttachingConnector(); + if(lmonitor.isCanceled()) { + return; + } + lmonitor.worked(1); + String servername = arguments.get(SACoreDebugServerAttachingConnectorImpl.DEBUG_SERVER_NAME); + if(servername == null) { + abort(LaunchingMessages.SACoreRemoteAttachingConnector_2, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_HOSTNAME); + } + Map<String, Argument> args = connector.defaultArguments(); + Connector.Argument arg = args.get(SACoreDebugServerAttachingConnectorImpl.DEBUG_SERVER_NAME); + arg.setValue(servername); + if(lmonitor.isCanceled()) { + return; + } + lmonitor.worked(1); + try { + VirtualMachine vm = connector.attach(args); + String vmLabel = constructVMLabel(vm, servername, launch.getLaunchConfiguration()); + IDebugTarget debugTarget= JDIDebugModel.newDebugTarget(launch, vm, vmLabel, null, false, true); + launch.addDebugTarget(debugTarget); + lmonitor.worked(1); + } + catch(TimeoutException toe) { + abort(LaunchingMessages.SocketAttachConnector_0, toe, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch(UnknownHostException uhe) { + abort(NLS.bind(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_because_of_unknown_host____0___1, new String[]{servername}), uhe, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch (ConnectException ce) { + abort(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_as_connection_was_refused_2, ce, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch(IOException ioe) { + abort(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_1, ioe, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + catch (IllegalConnectorArgumentsException icae) { + abort(LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_1, icae, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED); + } + } + finally { + if(!lmonitor.isCanceled()) { + lmonitor.done(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getName() + */ + public String getName() { + return LaunchingMessages.SACoreRemoteAttachingConnector_0; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getIdentifier() + */ + public String getIdentifier() { + return IJavaLaunchConfigurationConstants.ID_SA_DEBUG_SERVER_ATTACH_VM_CONNECTOR; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getDefaultArguments() + */ + public Map<String, Argument> getDefaultArguments() throws CoreException { + return getAttachingConnector().defaultArguments(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.launching.IVMConnector#getArgumentOrder() + */ + public List<String> getArgumentOrder() { + ArrayList<String> args = new ArrayList<String>(); + args.add(SACoreDebugServerAttachingConnectorImpl.DEBUG_SERVER_NAME); + return args; + } + + /** + * Return the socket transport attaching connector + * + * @return the {@link AttachingConnector} + * @exception CoreException if unable to locate the connector + */ + AttachingConnector getAttachingConnector() throws CoreException { + AttachingConnector connector= null; + Iterator<AttachingConnector> iter= Bootstrap.virtualMachineManager().attachingConnectors().iterator(); + while (iter.hasNext()) { + AttachingConnector lc= iter.next(); + if (lc.name().equals(SACoreDebugServerAttachingConnectorImpl.JDI_CONNECTOR_ID)) { + connector= lc; + break; + } + } + if (connector == null) { + } + return connector; + } + + /** + * Throws a core exception with an error status object built from + * the given message, lower level exception, and error code. + * + * @param message the status message + * @param exception lower level exception associated with the + * error, or <code>null</code> if none + * @param code error code + * @throws CoreException if an error occurs + */ + protected void abort(String message, Throwable exception, int code) throws CoreException { + throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), code, message, exception)); + } + + /** + * Helper method that constructs a human-readable label for a remote VM. + * @param vm the VM + * @param host the host name + * @param configuration the backing configuration + * @return the new label for the VM + */ + protected String constructVMLabel(VirtualMachine vm, String host, ILaunchConfiguration configuration) { + String name = null; + try { + name = vm.name(); + } catch (TimeoutException e) { + // do nothing + } catch (VMDisconnectedException e) { + // do nothing + } + if (name == null) { + if (configuration == null) { + name = ""; //$NON-NLS-1$ + } else { + name = configuration.getName(); + } + } + StringBuffer buffer = new StringBuffer(name); + buffer.append('['); + buffer.append(host); + buffer.append(']'); + return buffer.toString(); + } +} diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java index 9bef4bf06..c36275ddf 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java @@ -46,24 +46,28 @@ import com.sun.jdi.connect.IllegalConnectorArgumentsException; */ public class SocketAttachConnector implements IVMConnector { + public static final String TIMEOUT = "timeout"; //$NON-NLS-1$ + public static final String HOSTNAME = "hostname"; //$NON-NLS-1$ + public static final String JDI_CONNECTOR_ID = "com.sun.jdi.SocketAttach"; //$NON-NLS-1$ + /** * Return the socket transport attaching connector * * @return the {@link AttachingConnector} * @exception CoreException if unable to locate the connector */ - protected static AttachingConnector getAttachingConnector() throws CoreException { + protected AttachingConnector getAttachingConnector() throws CoreException { AttachingConnector connector= null; Iterator<AttachingConnector> iter= Bootstrap.virtualMachineManager().attachingConnectors().iterator(); while (iter.hasNext()) { AttachingConnector lc= iter.next(); - if (lc.name().equals("com.sun.jdi.SocketAttach")) { //$NON-NLS-1$ + if (lc.name().equals(JDI_CONNECTOR_ID)) { connector= lc; break; } } if (connector == null) { - abort(LaunchingMessages.SocketAttachConnector_Socket_attaching_connector_not_available_3, null, IJavaLaunchConfigurationConstants.ERR_SHARED_MEMORY_CONNECTOR_UNAVAILABLE); + abort(LaunchingMessages.SocketAttachConnector_Socket_attaching_connector_not_available_3, null, IJavaLaunchConfigurationConstants.ERR_SHARED_MEMORY_CONNECTOR_UNAVAILABLE); } return connector; } @@ -92,7 +96,7 @@ public class SocketAttachConnector implements IVMConnector { * @param code error code * @throws CoreException if an error occurs */ - protected static void abort(String message, Throwable exception, int code) throws CoreException { + protected void abort(String message, Throwable exception, int code) throws CoreException { throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), code, message, exception)); } @@ -109,24 +113,24 @@ public class SocketAttachConnector implements IVMConnector { subMonitor.subTask(LaunchingMessages.SocketAttachConnector_Configuring_connection____1); AttachingConnector connector= getAttachingConnector(); - String portNumberString = arguments.get("port"); //$NON-NLS-1$ + String portNumberString = arguments.get(SocketListenConnector.PORT); if (portNumberString == null) { abort(LaunchingMessages.SocketAttachConnector_Port_unspecified_for_remote_connection__2, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_PORT); } - String host = arguments.get("hostname"); //$NON-NLS-1$ + String host = arguments.get(HOSTNAME); if (host == null) { abort(LaunchingMessages.SocketAttachConnector_Hostname_unspecified_for_remote_connection__4, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_HOSTNAME); } Map<String, Connector.Argument> map= connector.defaultArguments(); - Connector.Argument param= map.get("hostname"); //$NON-NLS-1$ + Connector.Argument param= map.get(HOSTNAME); param.setValue(host); - param= map.get("port"); //$NON-NLS-1$ + param= map.get(SocketListenConnector.PORT); param.setValue(portNumberString); - String timeoutString = arguments.get("timeout"); //$NON-NLS-1$ + String timeoutString = arguments.get(TIMEOUT); if (timeoutString != null) { - param= map.get("timeout"); //$NON-NLS-1$ + param= map.get(TIMEOUT); param.setValue(timeoutString); } @@ -195,7 +199,7 @@ public class SocketAttachConnector implements IVMConnector { */ public Map<String, Connector.Argument> getDefaultArguments() throws CoreException { Map<String, Connector.Argument> def = getAttachingConnector().defaultArguments(); - Connector.IntegerArgument arg = (Connector.IntegerArgument)def.get("port"); //$NON-NLS-1$ + Connector.IntegerArgument arg = (Connector.IntegerArgument)def.get(SocketListenConnector.PORT); arg.setValue(8000); return def; } @@ -205,8 +209,8 @@ public class SocketAttachConnector implements IVMConnector { */ public List<String> getArgumentOrder() { List<String> list = new ArrayList<String>(2); - list.add("hostname"); //$NON-NLS-1$ - list.add("port"); //$NON-NLS-1$ + list.add(HOSTNAME); + list.add(SocketListenConnector.PORT); return list; } } diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnector.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnector.java index d544b15e8..4fa793887 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnector.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 IBM Corporation and others. + * Copyright (c) 2007, 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,19 +38,22 @@ import com.sun.jdi.connect.ListeningConnector; * @see SocketListenConnectorProcess */ public class SocketListenConnector implements IVMConnector { - + + public static final String JDI_CONNECTOR_ID = "com.sun.jdi.SocketListen"; //$NON-NLS-1$ + public static final String PORT = "port"; //$NON-NLS-1$ + /** * Return the socket transport listening connector * * @return the new {@link ListeningConnector} * @exception CoreException if unable to locate the connector */ - protected static ListeningConnector getListeningConnector() throws CoreException { + protected ListeningConnector getListeningConnector() throws CoreException { ListeningConnector connector= null; Iterator<ListeningConnector> iter= Bootstrap.virtualMachineManager().listeningConnectors().iterator(); while (iter.hasNext()) { ListeningConnector lc= iter.next(); - if (lc.name().equals("com.sun.jdi.SocketListen")) { //$NON-NLS-1$ + if (lc.name().equals(JDI_CONNECTOR_ID)) { connector= lc; break; } @@ -87,14 +90,14 @@ public class SocketListenConnector implements IVMConnector { ListeningConnector connector= getListeningConnector(); - String portNumberString = arguments.get("port"); //$NON-NLS-1$ + String portNumberString = arguments.get(PORT); if (portNumberString == null) { abort(LaunchingMessages.SocketAttachConnector_Port_unspecified_for_remote_connection__2, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_PORT); } Map<String, Connector.Argument> acceptArguments = connector.defaultArguments(); - Connector.Argument param= acceptArguments.get("port"); //$NON-NLS-1$ + Connector.Argument param= acceptArguments.get(PORT); param.setValue(portNumberString); try { @@ -115,7 +118,7 @@ public class SocketListenConnector implements IVMConnector { */ public Map<String, Connector.Argument> getDefaultArguments() throws CoreException { Map<String, Connector.Argument> def = getListeningConnector().defaultArguments(); - Connector.IntegerArgument arg = (Connector.IntegerArgument)def.get("port"); //$NON-NLS-1$ + Connector.IntegerArgument arg = (Connector.IntegerArgument)def.get(PORT); arg.setValue(8000); return def; } @@ -125,7 +128,7 @@ public class SocketListenConnector implements IVMConnector { */ public List<String> getArgumentOrder() { List<String> list = new ArrayList<String>(1); - list.add("port"); //$NON-NLS-1$ + list.add(PORT); return list; } @@ -139,7 +142,7 @@ public class SocketListenConnector implements IVMConnector { * @param code error code * @throws CoreException if an error occurs */ - protected static void abort(String message, Throwable exception, int code) throws CoreException { + protected void abort(String message, Throwable exception, int code) throws CoreException { throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), code, message, exception)); } } 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 c0c45130e..1802c009f 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 @@ -54,6 +54,19 @@ public interface IJavaLaunchConfigurationConstants { * @since 3.4 */ public static final String ID_SOCKET_LISTEN_VM_CONNECTOR = LaunchingPlugin.getUniqueIdentifier() + ".socketListenConnector"; //$NON-NLS-1$ + /** + * Identifier for the standard local SA attaching connector + * (value <code>"org.eclipse.jdt.launching.SACoreAttachingConnector"</code>). + * @since 3.6 + */ + public static final String ID_SA_ATTACH_VM_CONNECTOR = LaunchingPlugin.getUniqueIdentifier() + ".SACoreAttachingConnector"; //$NON-NLS-1$ + + /** + * Identifier for the standard SA dbeug server attaching connector + * (value <code>"org.eclipse.jdt.launching.SACoreDebugServerAttachingConnector"</code>). + * @since 3.6 + */ + public static final String ID_SA_DEBUG_SERVER_ATTACH_VM_CONNECTOR = LaunchingPlugin.getUniqueIdentifier() + ".SACoreDebugServerAttachingConnector"; //$NON-NLS-1$ /** * Identifier for the java process type, which is annotated on processes created @@ -486,7 +499,20 @@ public interface IJavaLaunchConfigurationConstants { * * @since 3.0 */ - public static final int ERR_PROJECT_CLOSED = 124; + public static final int ERR_PROJECT_CLOSED = 124; + + /** + * Status code indicating that the path to the core dump file was not given + * + * @since 3.6 + */ + public static final int ERR_UNSPECIFIED_CORE_FILE = 125; + /** + * Status code indicating that the Java executable path was not given + * + * @since 3.6 + */ + public static final int ERR_UNSPECIFIED_JAVA_EXECUTABLE_PATH = 126; /** * Status code indicating an unexpected internal error. diff --git a/org.eclipse.jdt.launching/plugin.xml b/org.eclipse.jdt.launching/plugin.xml index a9afc7e2a..05ed8a505 100644 --- a/org.eclipse.jdt.launching/plugin.xml +++ b/org.eclipse.jdt.launching/plugin.xml @@ -84,6 +84,7 @@ </sourceLocator> </extension> <extension + id="sun.jvm.hotspot.jdi.SACoreAttachingConnector" point="org.eclipse.jdt.launching.vmConnectors"> <vmConnector class="org.eclipse.jdt.internal.launching.SocketAttachConnector" @@ -93,6 +94,14 @@ class="org.eclipse.jdt.internal.launching.SocketListenConnector" id="org.eclipse.jdt.launching.socketListenConnector"> </vmConnector> + <vmConnector + class="org.eclipse.jdt.internal.launching.SACoreAttachingConnector" + id="org.eclipse.jdt.launching.SACoreAttachingConnector"> + </vmConnector> + <vmConnector + class="org.eclipse.jdt.internal.launching.SACoreDebugServerAttachingConnector" + id="org.eclipse.jdt.launching.SACoreDebugServerAttachingConnector"> + </vmConnector> </extension> <extension point="org.eclipse.jdt.core.classpathVariableInitializer"> |