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 }