KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > connect > SocketLaunchingConnectorImpl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Ivan Popov - Bug 184211: JDI connectors throw NullPointerException if used separately
11  * from Eclipse
12  *******************************************************************************/

13 package org.eclipse.jdi.internal.connect;
14
15
16 import java.io.IOException JavaDoc;
17 import java.io.InterruptedIOException JavaDoc;
18 import java.net.ServerSocket JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.eclipse.debug.core.DebugPlugin;
23 import org.eclipse.jdi.internal.VirtualMachineImpl;
24 import org.eclipse.jdi.internal.VirtualMachineManagerImpl;
25
26 import com.ibm.icu.text.MessageFormat;
27 import com.sun.jdi.VirtualMachine;
28 import com.sun.jdi.connect.Connector;
29 import com.sun.jdi.connect.IllegalConnectorArgumentsException;
30 import com.sun.jdi.connect.LaunchingConnector;
31 import com.sun.jdi.connect.VMStartException;
32
33
34 public class SocketLaunchingConnectorImpl extends ConnectorImpl implements LaunchingConnector {
35     /** Time that a launched VM is given to connect to us. */
36     private static final int ACCEPT_TIMEOUT = 10*1000;
37     
38     /** Home directory of the SDK or runtime environment used to launch the application. */
39     private String JavaDoc fHome;
40     /** Launched VM options. */
41     private String JavaDoc fOptions;
42     /** Main class and arguments, or if -jar is an option, the main jar file and arguments. */
43     private String JavaDoc fMain;
44     /** All threads will be suspended before execution of main. */
45     private boolean fSuspend;
46     /** Name of the Java VM launcher. */
47     private String JavaDoc fLauncher;
48     
49     /**
50      * Creates new SocketAttachingConnectorImpl.
51      */

52     public SocketLaunchingConnectorImpl(VirtualMachineManagerImpl virtualMachineManager) {
53         super(virtualMachineManager);
54         
55         // Create communication protocol specific transport.
56
SocketTransportImpl transport = new SocketTransportImpl();
57         setTransport(transport);
58     }
59     
60     /**
61      * @return Returns the default arguments.
62      */

63     public Map JavaDoc defaultArguments() {
64         HashMap JavaDoc arguments = new HashMap JavaDoc(6);
65         
66         // Home
67
StringArgumentImpl strArg = new StringArgumentImpl("home", ConnectMessages.SocketLaunchingConnectorImpl_Home_directory_of_the_SDK_or_runtime_environment_used_to_launch_the_application_1, ConnectMessages.SocketLaunchingConnectorImpl_Home_2, false); //$NON-NLS-1$
68
strArg.setValue(System.getProperty("java.home")); //$NON-NLS-1$
69
arguments.put(strArg.name(), strArg);
70         
71         // Options
72
strArg = new StringArgumentImpl("options", ConnectMessages.SocketLaunchingConnectorImpl_Launched_VM_options_3, ConnectMessages.SocketLaunchingConnectorImpl_Options_4, false); //$NON-NLS-1$
73
arguments.put(strArg.name(), strArg);
74         
75         // Main
76
strArg = new StringArgumentImpl("main", ConnectMessages.SocketLaunchingConnectorImpl_Main_class_and_arguments__or_if__jar_is_an_option__the_main_jar_file_and_arguments_5, ConnectMessages.SocketLaunchingConnectorImpl_Main_6, true); //$NON-NLS-1$
77
arguments.put(strArg.name(), strArg);
78
79         // Suspend
80
BooleanArgumentImpl boolArg = new BooleanArgumentImpl("suspend", ConnectMessages.SocketLaunchingConnectorImpl_All_threads_will_be_suspended_before_execution_of_main_7, ConnectMessages.SocketLaunchingConnectorImpl_Suspend_8, false); //$NON-NLS-1$
81
boolArg.setValue(true);
82         arguments.put(boolArg.name(), boolArg);
83
84         // Quote
85
strArg = new StringArgumentImpl("quote", ConnectMessages.SocketLaunchingConnectorImpl_Character_used_to_combine_space_delimited_text_into_a_single_command_line_argument_9, ConnectMessages.SocketLaunchingConnectorImpl_Quote_10, true); //$NON-NLS-1$
86
strArg.setValue("\""); //$NON-NLS-1$
87
arguments.put(strArg.name(), strArg);
88
89         // Launcher
90
strArg = new StringArgumentImpl("vmexec", ConnectMessages.SocketLaunchingConnectorImpl_Name_of_the_Java_VM_launcher_11, ConnectMessages.SocketLaunchingConnectorImpl_Launcher_12, true); //$NON-NLS-1$
91
strArg.setValue("java"); //$NON-NLS-1$
92
arguments.put(strArg.name(), strArg);
93
94         return arguments;
95     }
96     
97     /**
98      * @return Returns a short identifier for the connector.
99      */

100     public String JavaDoc name() {
101         return "com.sun.jdi.CommandLineLaunch"; //$NON-NLS-1$
102
}
103     
104     /**
105      * @return Returns a human-readable description of this connector and its purpose.
106      */

107     public String JavaDoc description() {
108         return ConnectMessages.SocketLaunchingConnectorImpl_Launches_target_using_Sun_Java_VM_command_line_and_attaches_to_it_13;
109     }
110     
111     /**
112      * Retrieves connection arguments.
113      */

114     private void getConnectionArguments(Map JavaDoc connectionArgs) throws IllegalConnectorArgumentsException {
115         String JavaDoc attribute = ""; //$NON-NLS-1$
116
try {
117             attribute = "home"; //$NON-NLS-1$
118
fHome = ((Connector.StringArgument)connectionArgs.get(attribute)).value();
119             attribute = "options"; //$NON-NLS-1$
120
fOptions = ((Connector.StringArgument)connectionArgs.get(attribute)).value();
121             attribute = "main"; //$NON-NLS-1$
122
fMain = ((Connector.StringArgument)connectionArgs.get(attribute)).value();
123             attribute = "suspend"; //$NON-NLS-1$
124
fSuspend = ((Connector.BooleanArgument)connectionArgs.get(attribute)).booleanValue();
125             attribute = "quote"; //$NON-NLS-1$
126
((Connector.StringArgument)connectionArgs.get(attribute)).value();
127             attribute = "vmexec"; //$NON-NLS-1$
128
fLauncher = ((Connector.StringArgument)connectionArgs.get(attribute)).value();
129         } catch (ClassCastException JavaDoc e) {
130             throw new IllegalConnectorArgumentsException(ConnectMessages.SocketLaunchingConnectorImpl_Connection_argument_is_not_of_the_right_type_14, attribute);
131         } catch (NullPointerException JavaDoc e) {
132             throw new IllegalConnectorArgumentsException(ConnectMessages.SocketLaunchingConnectorImpl_Necessary_connection_argument_is_null_15, attribute);
133         } catch (NumberFormatException JavaDoc e) {
134             throw new IllegalConnectorArgumentsException(ConnectMessages.SocketLaunchingConnectorImpl_Connection_argument_is_not_a_number_16, attribute);
135         }
136     }
137
138     /**
139      * Launches an application and connects to its VM.
140      * @return Returns a connected Virtual Machine.
141      */

142     public VirtualMachine launch(Map JavaDoc connectionArgs) throws IOException JavaDoc, IllegalConnectorArgumentsException, VMStartException {
143         getConnectionArguments(connectionArgs);
144         
145         // A listening connector is used that waits for a connection of the VM that is started up.
146
// Note that port number zero means that a free port is chosen.
147
SocketListeningConnectorImpl listenConnector = new SocketListeningConnectorImpl(virtualMachineManager());
148         Map JavaDoc args = listenConnector.defaultArguments();
149         ((Connector.IntegerArgument)args.get("timeout")).setValue(ACCEPT_TIMEOUT); //$NON-NLS-1$
150
String JavaDoc address = listenConnector.startListening(args);
151         
152         // String for Executable.
153
String JavaDoc slash = System.getProperty("file.separator"); //$NON-NLS-1$
154
String JavaDoc execString = fHome + slash + "bin" + slash + fLauncher; //$NON-NLS-1$
155

156         // Add Debug options.
157
execString += " -Xdebug -Xnoagent -Djava.compiler=NONE"; //$NON-NLS-1$
158
execString += " -Xrunjdwp:transport=dt_socket,address=" + address + ",server=n,suspend=" + (fSuspend ? "y" : "n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
159

160         // Add User specified options.
161
if (fOptions != null)
162             execString += " " + fOptions; //$NON-NLS-1$
163

164         // Add Main class.
165
execString += " " + fMain; //$NON-NLS-1$
166

167         // Start VM.
168
String JavaDoc[] cmdLine = DebugPlugin.parseArguments(execString);
169         Process JavaDoc proc = Runtime.getRuntime().exec(cmdLine);
170
171         // The accept times out if the VM does not connect.
172
VirtualMachineImpl virtualMachine;
173         try {
174             virtualMachine = (VirtualMachineImpl)listenConnector.accept(args);
175         } catch (InterruptedIOException JavaDoc e) {
176             proc.destroy();
177             String JavaDoc message= MessageFormat.format(ConnectMessages.SocketLaunchingConnectorImpl_VM_did_not_connect_within_given_time___0__ms_1, new String JavaDoc[]{((Connector.IntegerArgument)args.get("timeout")).value()}); //$NON-NLS-1$
178
throw new VMStartException(message, proc);
179         }
180         
181         virtualMachine.setLaunchedProcess(proc);
182         return virtualMachine;
183     }
184     
185     /**
186      * Returns a free port number on localhost, or -1 if unable to find a free port.
187      *
188      * @return a free port number on localhost, or -1 if unable to find a free port
189      * @since 3.2
190      */

191     public static int findFreePort() {
192         ServerSocket JavaDoc socket= null;
193         try {
194             socket= new ServerSocket JavaDoc(0);
195             return socket.getLocalPort();
196         } catch (IOException JavaDoc e) {
197         } finally {
198             if (socket != null) {
199                 try {
200                     socket.close();
201                 } catch (IOException JavaDoc e) {
202                 }
203             }
204         }
205         return -1;
206     }
207 }
208
Popular Tags