1 /* 2 * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jdi; 27 28 import java.io.IOException; 29 import java.util.List; 30 31 import com.sun.jdi.connect.AttachingConnector; 32 import com.sun.jdi.connect.Connector; 33 import com.sun.jdi.connect.LaunchingConnector; 34 import com.sun.jdi.connect.ListeningConnector; 35 import com.sun.jdi.connect.spi.Connection; 36 37 /** 38 * A manager of connections to target virtual machines. The 39 * VirtualMachineManager allows one application to debug 40 * multiple target VMs. (Note that the converse is not 41 * supported; a target VM can be debugged by only one 42 * debugger application.) This interface 43 * contains methods to manage connections 44 * to remote target VMs and to obtain the {@link VirtualMachine} 45 * mirror for available target VMs. 46 * <p> 47 * Connections can be made using one of several different 48 * {@link com.sun.jdi.connect.Connector} objects. Each connector encapsulates 49 * a different way of connecting the debugger with a target VM. 50 * <p> 51 * The VirtualMachineManager supports many different scenarios for 52 * connecting a debugger to a virtual machine. Four examples 53 * are presented in the table below. The 54 * examples use the command line syntax in Sun's implementation. 55 * Some {@link com.sun.jdi.connect.Connector} implementations may require slightly 56 * different handling than presented below. 57 * 58 * <TABLE BORDER="1" style="width:75%"> 59 * <CAPTION style="display:none">Four scenarios for connecting a debugger to a virtual machine"</CAPTION> 60 * <TR> 61 * <TH scope=col>Scenario</TH> 62 * <TH scope=col>Description</TH> 63 * <TR> 64 * <TD>Debugger launches target VM (simplest, most-common scenario)</TD> 65 * 66 * <TD>Debugger calls the 67 * {@link com.sun.jdi.connect.LaunchingConnector#launch(java.util.Map)} 68 * method of the default connector, obtained with {@link #defaultConnector}. The 69 * target VM is launched, and a connection between that VM and the 70 * debugger is established. A {@link VirtualMachine} mirror is returned. 71 * <P>Or, for more control 72 * <UL> 73 * <LI> 74 * Debugger selects a connector from the list returned by 75 * {@link #launchingConnectors} with desired characteristics 76 * (for example, transport type, etc.). 77 * <LI> 78 * Debugger calls the 79 * {@link com.sun.jdi.connect.LaunchingConnector#launch(java.util.Map)} 80 * method of the selected connector. The 81 * target VM is launched, and a connection between that VM and the 82 * debugger is established. A {@link VirtualMachine} mirror is returned. 83 * </UL> 84 * </TD> 85 * </TR> 86 * <TR> 87 * <TD>Debugger attaches to previously-running VM</TD> 88 * <TD> 89 * <UL> 90 * <LI> 91 * Target VM is launched using the options 92 * {@code -agentlib:jdwp=transport=xxx,server=y} 93 * </LI> 94 * <LI> 95 * Target VM generates and outputs the tranport-specific address at which it will 96 * listen for a connection.</LI> 97 * <LI> 98 * Debugger is launched. Debugger selects a connector in the list 99 * returned by {@link #attachingConnectors} matching the transport with 100 * the name "xxx". 101 * <LI> 102 * Debugger presents the default connector parameters (obtained through 103 * {@link com.sun.jdi.connect.Connector#defaultArguments()}) to the end user, 104 * allowing the user to 105 * fill in the transport-specific address generated by the target VM. 106 * <LI> 107 * Debugger calls the {@link com.sun.jdi.connect.AttachingConnector#attach(java.util.Map)} method 108 * of the selected to attach to the target VM. A {@link VirtualMachine} 109 * mirror is returned. 110 * </UL> 111 * </TD> 112 * </TR> 113 * 114 * <TR> 115 * <TD>Target VM attaches to previously-running debugger</TD> 116 * <TD> 117 * <UL> 118 * <LI> 119 * At startup, debugger selects one or more connectors from 120 * the list returned by {@link #listeningConnectors} for one or more 121 * transports.</LI> 122 * <LI> 123 * Debugger calls the {@link com.sun.jdi.connect.ListeningConnector#startListening(java.util.Map)} method for each selected 124 * connector. For each call, a transport-specific address string is 125 * generated and returned. The debugger makes the transport names and 126 * corresponding address strings available to the end user. 127 * <LI> 128 * Debugger calls 129 * {@link com.sun.jdi.connect.ListeningConnector#accept(java.util.Map)} 130 * for each selected connector to wait for 131 * a target VM to connect.</LI> 132 * <LI> 133 * Later, target VM is launched by end user with the options 134 * {@code -agentlib:jdwp=transport=xxx,address=yyy} 135 * where "xxx" the transport for one of the connectors selected by the 136 * the debugger and "yyy" 137 * is the address generated by 138 * {@link com.sun.jdi.connect.ListeningConnector#accept(java.util.Map)} for that 139 * transport.</LI> 140 * <LI> 141 * Debugger's call to {@link com.sun.jdi.connect.ListeningConnector#accept(java.util.Map)} returns 142 * a {@link VirtualMachine} mirror.</LI> 143 * </UL> 144 * </TD> 145 * </TR> 146 * 147 * <TR> 148 * <TD>Target VM launches debugger (sometimes called "Just-In-Time" debugging)</TD> 149 * <TD> 150 * <UL> 151 * <LI> 152 * Target VM is launched with the options 153 * {@code -agentlib:jdwp=launch=cmdline,onuncaught=y,transport=xxx,server=y} 154 * </LI> 155 * <LI> 156 * Later, an uncaught exception is thrown in the target VM. The target 157 * VM generates the tranport-specific address at which it will 158 * listen for a connection. 159 * <LI>Target VM launches the debugger with the following items concatenated 160 * together (separated by spaces) to form the command line: 161 * <UL> 162 * <LI> The launch= value 163 * <LI> The transport= value 164 * <LI> The generated transport-specific address at which VM is listening for 165 * debugger connection. 166 * </UL> 167 * <LI> 168 * Upon launch, debugger selects a connector in the list 169 * returned by {@link #attachingConnectors} matching the transport with 170 * the name "xxx". 171 * <LI> 172 * Debugger changes the default connector parameters (obtained through 173 * {@link com.sun.jdi.connect.Connector#defaultArguments()}) to specify 174 * the transport specific address at which the VM is listenig. Optionally, 175 * other connector arguments can be presented to the user. 176 * <LI> 177 * Debugger calls the 178 * {@link com.sun.jdi.connect.AttachingConnector#attach(java.util.Map)} method 179 * of the selected to attach to the target VM. A {@link VirtualMachine} 180 * mirror is returned. 181 * </UL> 182 * </TD> 183 * </TR> 184 * </TABLE> 185 * 186 * <p> Connectors are created at start-up time. That is, they 187 * are created the first time that {@link 188 * com.sun.jdi.Bootstrap#virtualMachineManager()} is invoked. 189 * The list of all Connectors created at start-up time can be 190 * obtained from the VirtualMachineManager by invoking the 191 * {@link #allConnectors allConnectors} method. 192 * 193 * <p> Connectors are created at start-up time if they are 194 * installed on the platform. In addition, Connectors are created 195 * automatically by the VirtualMachineManager to encapsulate any 196 * {@link com.sun.jdi.connect.spi.TransportService} implementations 197 * that are installed on the platform. These two mechanisms for 198 * creating Connectors are described here. 199 * 200 * <p> A Connector is installed on the platform if it is installed 201 * in a jar file that is visible to the defining class loader of 202 * the {@link com.sun.jdi.connect.Connector} type, 203 * and that jar file contains a provider configuration file named 204 * {@code com.sun.jdi.connect.Connector} in the resource directory 205 * {@code META-INF/services}, and the provider configuration file 206 * lists the full-qualified class name of the Connector 207 * implementation. A Connector is a class that implements the 208 * {@link com.sun.jdi.connect.Connector Connector} interface. More 209 * appropriately the class implements one of the specific Connector 210 * types, namely {@link com.sun.jdi.connect.AttachingConnector 211 * AttachingConnector}, {@link com.sun.jdi.connect.ListeningConnector 212 * ListeningConnector}, or {@link com.sun.jdi.connect.LaunchingConnector 213 * LaunchingConnector}. The format of the provider configuration file 214 * is one fully-qualified class name per line. Space and tab characters 215 * surrounding each class, as well as blank lines are ignored. The 216 * comment character is {@code '#'} ({@code 0x23}), and on each 217 * line all characters following the first comment character are 218 * ignored. The file must be encoded in UTF-8. 219 * 220 * <p> At start-up time the VirtualMachineManager attempts to load 221 * and instantiate (using the no-arg constructor) each class listed 222 * in the provider configuration file. Exceptions thrown when loading 223 * or creating the Connector are caught and ignored. In other words, 224 * the start-up process continues despite of errors. 225 * 226 * <p> In addition to Connectors installed on the platform the 227 * VirtualMachineManager will also create Connectors to encapsulate 228 * any {@link com.sun.jdi.connect.spi.TransportService} implementations 229 * that are installed on the platform. A TransportService is 230 * installed on the platform if it installed in a jar file that is 231 * visible to the defining class loader for the 232 * {@link com.sun.jdi.connect.spi.TransportService} type, and that jar 233 * file contains a provider configuration file named 234 * {@code com.sun.jdi.connect.spi.TransportService} in the resource 235 * directory {@code META-INF/services}, and the provider 236 * configuration file lists the full-qualified class name of the 237 * TransportService implementation. A TransportService is a concrete 238 * sub-class of {@link com.sun.jdi.connect.spi.TransportService 239 * TransportService}. The format of the provider configuration file 240 * is the same as the provider configuration file for Connectors 241 * except that each class listed must be the fully-qualified class 242 * name of a class that implements the TransportService interface. 243 * 244 * <p> For each TransportService installed on the platform, the 245 * VirtualMachineManager creates a corresponding 246 * {@link com.sun.jdi.connect.AttachingConnector} and 247 * {@link com.sun.jdi.connect.ListeningConnector}. These 248 * Connectors are created to encapsulate a {@link 249 * com.sun.jdi.connect.Transport Transport} that in turn 250 * encapsulates the TransportService. 251 * The AttachingConnector will be named based on the name of the 252 * transport service concatenated with the string {@code Attach}. 253 * For example, if the transport service {@link 254 * com.sun.jdi.connect.spi.TransportService#name() name()} method 255 * returns {@code telepathic} then the AttachingConnector will 256 * be named {@code telepathicAttach}. Similiarly the ListeningConnector 257 * will be named with the string {@code Listen} tagged onto the 258 * name of the transport service. The {@link 259 * com.sun.jdi.connect.Connector#description() description()} method 260 * of both the AttachingConnector, and the ListeningConnector, will 261 * delegate to the {@link com.sun.jdi.connect.spi.TransportService#description() 262 * description()} method of the underlying transport service. Both 263 * the AttachingConnector and the ListeningConnector will have two 264 * Connector {@link com.sun.jdi.connect.Connector.Argument Arguments}. 265 * A {@link com.sun.jdi.connect.Connector.StringArgument StringArgument} 266 * named {@code address} is the connector argument to specify the 267 * address to attach too, or to listen on. A 268 * {@link com.sun.jdi.connect.Connector.IntegerArgument IntegerArgument} 269 * named {@code timeout} is the connector argument to specify the 270 * timeout when attaching, or accepting. The timeout connector may be 271 * ignored depending on if the transport service supports an attach 272 * timeout or accept timeout. 273 * 274 * <p> Initialization of the virtual machine manager will fail, that is 275 * {@link com.sun.jdi.Bootstrap#virtualMachineManager()} will throw an 276 * error if the virtual machine manager is unable to create any 277 * connectors. 278 * 279 * @author Gordon Hirsch 280 * @since 1.3 281 */ 282 public interface VirtualMachineManager { 283 284 /** 285 * Identifies the default connector. This connector should 286 * be used as the launching connector when selection of a 287 * connector with specific characteristics is unnecessary. 288 * 289 * @return the default {@link com.sun.jdi.connect.LaunchingConnector} 290 */ 291 LaunchingConnector defaultConnector(); 292 293 /** 294 * Returns the list of known {@link com.sun.jdi.connect.LaunchingConnector} objects. 295 * Any of the returned objects can be used to launch a new target 296 * VM and immediately create a {@link VirtualMachine} mirror for it. 297 * 298 * Note that a target VM launched by a launching connector is not 299 * guaranteed to be stable until after the {@link com.sun.jdi.event.VMStartEvent} has been 300 * received. 301 * @return a list of {@link com.sun.jdi.connect.LaunchingConnector} objects. 302 */ 303 List<LaunchingConnector> launchingConnectors(); 304 305 /** 306 * Returns the list of known {@link com.sun.jdi.connect.AttachingConnector} objects. 307 * Any of the returned objects can be used to attach to an existing target 308 * VM and create a {@link VirtualMachine} mirror for it. 309 * 310 * @return a list of {@link com.sun.jdi.connect.AttachingConnector} objects. 311 */ 312 List<AttachingConnector> attachingConnectors(); 313 314 /** 315 * Returns the list of known {@link com.sun.jdi.connect.ListeningConnector} objects. 316 * Any of the returned objects can be used to listen for a 317 * connection initiated by a target VM 318 * and create a {@link VirtualMachine} mirror for it. 319 * 320 * @return a list of {@link com.sun.jdi.connect.ListeningConnector} objects. 321 */ 322 List<ListeningConnector> listeningConnectors(); 323 324 /** 325 * Returns the list of all known {@link com.sun.jdi.connect.Connector} objects. 326 * 327 * @return a list of {@link com.sun.jdi.connect.Connector} objects. 328 */ 329 List<Connector> allConnectors(); 330 331 /** 332 * Lists all target VMs which are connected to the debugger. 333 * The list includes {@link VirtualMachine} instances for 334 * any target VMs which initiated a connection 335 * and any 336 * target VMs to which this manager has initiated a connection. 337 * A target VM will remain in this list 338 * until the VM is disconnected. 339 * {@link com.sun.jdi.event.VMDisconnectEvent} is placed in the event queue 340 * after the VM is removed from the list. 341 * 342 * @return a list of {@link VirtualMachine} objects, each mirroring 343 * a target VM. 344 */ 345 List<VirtualMachine> connectedVirtualMachines(); 346 347 /** 348 * Returns the major version number of the JDI interface. 349 * See {@link VirtualMachine#version} target VM version and 350 * information and 351 * {@link VirtualMachine#description} more version information. 352 * 353 * @return the integer major version number. 354 */ 355 int majorInterfaceVersion(); 356 357 /** 358 * Returns the minor version number of the JDI interface. 359 * See {@link VirtualMachine#version} target VM version and 360 * information and 361 * {@link VirtualMachine#description} more version information. 362 * 363 * @return the integer minor version number 364 */ 365 int minorInterfaceVersion(); 366 367 /** 368 * Create a virtual machine mirror for a target VM. 369 * 370 * <p> Creates a virtual machine mirror for a target VM 371 * for which a {@link com.sun.jdi.connect.spi.Connection Connection} 372 * already exists. A Connection is created when a {@link 373 * com.sun.jdi.connect.Connector Connector} establishes 374 * a connection and successfully handshakes with a target VM. 375 * A Connector can then use this method to create a virtual machine 376 * mirror to represent the composite state of the target VM. 377 * 378 * <p> The {@code process} argument specifies the 379 * {@link java.lang.Process} object for the taget VM. It may be 380 * specified as {@code null}. If the target VM is launched 381 * by a {@link com.sun.jdi.connect.LaunchingConnector 382 * LaunchingConnector} the {@code process} argument should be 383 * specified, otherwise calling {@link com.sun.jdi.VirtualMachine#process()} 384 * on the created virtual machine will return {@code null}. 385 * 386 * <p> This method exists so that Connectors may create 387 * a virtual machine mirror when a connection is established 388 * to a target VM. Only developers creating new Connector 389 * implementations should need to make direct use of this 390 * method. 391 * 392 * @param connection 393 * The open connection to the target VM. 394 * 395 * @param process 396 * If launched, the {@link java.lang.Process} object for 397 * the target VM. {@code null} if not launched. 398 * 399 * @return new virtual machine representing the target VM. 400 * 401 * @throws IOException 402 * if an I/O error occurs 403 * 404 * @throws IllegalStateException 405 * if the connection is not open 406 * 407 * @see com.sun.jdi.connect.spi.Connection#isOpen() 408 * @see com.sun.jdi.VirtualMachine#process() 409 * 410 * @since 1.5 411 */ 412 VirtualMachine createVirtualMachine(Connection connection, Process process) throws IOException; 413 414 /** 415 * Creates a new virtual machine. 416 * 417 * <p> This convenience method works as if by invoking {@link 418 * #createVirtualMachine(Connection, Process)} method and 419 * specifying {@code null} as the {@code process} argument. 420 * 421 * <p> This method exists so that Connectors may create 422 * a virtual machine mirror when a connection is established 423 * to a target VM. Only developers creating new Connector 424 * implementations should need to make direct use of this 425 * method. 426 * 427 * @return the new virtual machine 428 * 429 * @throws IOException 430 * if an I/O error occurs 431 * 432 * @throws IllegalStateException 433 * if the connection is not open 434 * 435 * @since 1.5 436 */ 437 VirtualMachine createVirtualMachine(Connection connection) throws IOException; 438 }