1 /* 2 * Copyright (c) 2003, 2013, 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.connect.spi; 27 28 import java.io.IOException; 29 30 import com.sun.jdi.connect.TransportTimeoutException; 31 32 /** 33 * A transport service for connections between a debugger and 34 * a target VM. 35 * 36 * <p> A transport service is a concrete subclass of this class 37 * that has a zero-argument constructor and implements the abstract 38 * methods specified below. It is the underlying service 39 * used by a {@link com.sun.jdi.connect.Transport} for 40 * connections between a debugger and a target VM. 41 * 42 * <p> A transport service is used to establish a connection 43 * between a debugger and a target VM, and to transport Java 44 * Debug Wire Protocol (JDWP) packets over an underlying 45 * communication protocol. In essence a transport service 46 * implementation binds JDWP (as specified in the 47 * <a href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html"> 48 * JDWP specification</a>) to an underlying communication 49 * protocol. A transport service implementation provides 50 * a reliable JDWP packet transportation service. JDWP 51 * packets are sent to and from the target VM without duplication 52 * or data loss. A transport service implementation may be 53 * based on an underlying communication protocol that is 54 * reliable or unreliable. If the underlying communication 55 * protocol is reliable then the transport service implementation 56 * may be relatively simple and may only need to transport JDWP 57 * packets as payloads of the underlying communication 58 * protocol. In the case of an unreliable communication 59 * protocol the transport service implementation may include 60 * additional protocol support in order to ensure that packets 61 * are not duplicated and that there is no data loss. The 62 * details of such protocols are specific to the implementation 63 * but may involve techniques such as the <i>positive 64 * acknowledgment with retransmission</i> technique used in 65 * protocols such as the Transmission Control Protocol (TCP) 66 * (see <a href="http://www.ietf.org/rfc/rfc0793.txt"> RFC 793 67 * </a>). 68 * 69 * <p> A transport service can be used to initiate a connection 70 * to a target VM. This is done by invoking the {@link #attach} 71 * method. Alternatively, a transport service can listen and 72 * accept connections initiated by a target VM. This is done 73 * by invoking the {@link #startListening(String)} method to 74 * put the transport into listen mode. Then the {@link #accept} 75 * method is used to accept a connection initiated by a 76 * target VM. 77 * 78 * @since 1.5 79 */ 80 public abstract class TransportService { 81 82 /** 83 * Returns a name to identify the transport service. 84 * 85 * @return The name of the transport service 86 */ 87 public abstract String name(); 88 89 /** 90 * Returns a description of the transport service. 91 * 92 * @return The description of the transport service 93 */ 94 public abstract String description(); 95 96 /** 97 * The transport service capabilities. 98 */ 99 public static abstract class Capabilities { 100 101 /** 102 * Tells whether or not this transport service can support 103 * multiple concurrent connections to a single address that 104 * it is listening on. 105 * 106 * @return {@code true} if, and only if, this transport 107 * service supports multiple connections. 108 */ 109 public abstract boolean supportsMultipleConnections(); 110 111 /** 112 * Tell whether or not this transport service supports a timeout 113 * when attaching to a target VM. 114 * 115 * @return {@code true} if, and only if, this transport 116 * service supports attaching with a timeout. 117 * 118 * @see #attach(String,long,long) 119 */ 120 public abstract boolean supportsAttachTimeout(); 121 122 /** 123 * Tell whether or not this transport service supports a 124 * timeout while waiting for a target VM to connect. 125 * 126 * @return {@code true} if, and only if, this transport 127 * service supports timeout while waiting for 128 * a target VM to connect. 129 * 130 * @see #accept(TransportService.ListenKey,long,long) 131 */ 132 public abstract boolean supportsAcceptTimeout(); 133 134 /** 135 * Tells whether or not this transport service supports a 136 * timeout when handshaking with the target VM. 137 * 138 * @return {@code true} if, and only if, this transport 139 * service supports a timeout while handshaking 140 * with the target VM. 141 * 142 * @see #attach(String,long,long) 143 * @see #accept(TransportService.ListenKey,long,long) 144 */ 145 public abstract boolean supportsHandshakeTimeout(); 146 } 147 148 /** 149 * Returns the capabilities of the transport service. 150 * 151 * @return the transport service capabilities 152 */ 153 public abstract Capabilities capabilities(); 154 155 /** 156 * Attaches to the specified address. 157 * 158 * <p> Attaches to the specified address and returns a connection 159 * representing the bi-directional communication channel to the 160 * target VM. 161 * 162 * <p> Attaching to the target VM involves two steps: 163 * First, a connection is established to specified address. This 164 * is followed by a handshake to ensure that the connection is 165 * to a target VM. The handshake involves the exchange 166 * of a string <i>JDWP-Handshake</i> as specified in the <a 167 * href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html"> 168 * Java Debug Wire Protocol</a> specification. 169 * 170 * @param address 171 * The address of the target VM. 172 * 173 * @param attachTimeout 174 * If this transport service supports an attach timeout, 175 * and if {@code attachTimeout} is positive, then it specifies 176 * the timeout, in milliseconds (more or less), to use 177 * when attaching to the target VM. If the transport service 178 * does not support an attach timeout, or if {@code attachTimeout} 179 * is specified as zero then attach without any timeout. 180 * 181 * @param handshakeTimeout 182 * If this transport service supports a handshake timeout, 183 * and if {@code handshakeTimeout} is positive, then it 184 * specifies the timeout, in milliseconds (more or less), to 185 * use when handshaking with the target VM. The exact 186 * usage of the timeout are specific to the transport service. 187 * A transport service may, for example, use the handshake 188 * timeout as the inter-character timeout while waiting for 189 * the <i>JDWP-Handshake</i> message from the target VM. 190 * Alternatively, a transport service may, for example, 191 * use the handshakeTimeout as a timeout for the duration of the 192 * handshake exchange. 193 * If the transport service does not support a handshake 194 * timeout, or if {@code handshakeTimeout} is specified 195 * as zero then the handshake does not timeout if there 196 * isn't a response from the target VM. 197 * 198 * @return The Connection representing the bi-directional 199 * communication channel to the target VM. 200 * 201 * @throws TransportTimeoutException 202 * If a timeout occurs while establishing the connection. 203 * 204 * @throws IOException 205 * If an I/O error occurs (including a timeout when 206 * handshaking). 207 * 208 * @throws IllegalArgumentException 209 * If the address is invalid or the value of the 210 * attach timeout or handshake timeout is negative. 211 * 212 * @see TransportService.Capabilities#supportsAttachTimeout() 213 */ 214 public abstract Connection attach(String address, long attachTimeout, 215 long handshakeTimeout) throws IOException; 216 217 /** 218 * A <i>listen key</i>. 219 * 220 * <p> A {@code TransportService} may listen on multiple, yet 221 * different, addresses at the same time. To uniquely identify 222 * each {@code listener} a listen key is created each time that 223 * {@link #startListening startListening} is called. The listen 224 * key is used in calls to the {@link #accept accept} method 225 * to accept inbound connections to that listener. A listen 226 * key is valid until it is used as an argument to {@link 227 * #stopListening stopListening} to stop the transport 228 * service from listening on an address. 229 */ 230 public static abstract class ListenKey { 231 232 /** 233 * Returns a string representation of the listen key. 234 */ 235 public abstract String address(); 236 } 237 238 /** 239 * Listens on the specified address for inbound connections. 240 * 241 * <p> This method starts the transport service listening on 242 * the specified address so that it can subsequently accept 243 * an inbound connection. It does not wait until an inbound 244 * connection is established. 245 * 246 * @param address 247 * The address to start listening for connections, 248 * or {@code null} to listen on an address chosen 249 * by the transport service. 250 * 251 * @return a listen key to be used in subsequent calls to be 252 * {@link #accept accept} or {@link #stopListening 253 * stopListening} methods. 254 * 255 * @throws IOException 256 * If an I/O error occurs. 257 * 258 * @throws IllegalArgumentException 259 * If the specific address is invalid 260 */ 261 public abstract ListenKey startListening(String address) throws IOException; 262 263 /** 264 * Listens on an address chosen by the transport service. 265 * 266 * <p> This convenience method works as if by invoking 267 * {@link #startListening(String) startListening(null)}. 268 * 269 * @return a listen key to be used in subsequent calls to be 270 * {@link #accept accept} or {@link #stopListening 271 * stopListening} methods. 272 * 273 * @throws IOException 274 * If an I/O error occurs. 275 */ 276 public abstract ListenKey startListening() throws IOException; 277 278 /** 279 * Stop listening for inbound connections. 280 * 281 * <p> Invoking this method while another thread is blocked 282 * in {@link #accept accept}, with the same listen key, 283 * waiting to accept a connection will cause that thread to 284 * throw an IOException. If the thread blocked in accept 285 * has already accepted a connection from a target VM and 286 * is in the process of handshaking with the target VM then 287 * invoking this method will not cause the thread to throw 288 * an exception. 289 * 290 * @param listenKey 291 * The listen key obtained from a previous call to {@link 292 * #startListening(String)} or {@link #startListening()}. 293 * 294 * @throws IllegalArgumentException 295 * If the listen key is invalid 296 * 297 * @throws IOException 298 * If an I/O error occurs. 299 */ 300 public abstract void stopListening(ListenKey listenKey) throws IOException; 301 302 /** 303 * Accept a connection from a target VM. 304 * 305 * <p> Waits (indefinitely or with timeout) to accept a connection 306 * from a target VM. Returns a connection representing the 307 * bi-directional communication channel to the target VM. 308 * 309 * <p> Accepting a connection from a target VM involves two 310 * steps. First, the transport service waits to accept 311 * the connection from the target VM. Once the connection is 312 * established a handshake is performed to ensure that the 313 * connection is indeed to a target VM. The handshake involves 314 * the exchange of a string <i>JDWP-Handshake</i> as specified 315 * in the <a 316 * href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html"> 317 * Java Debug Wire Protocol</a> specification. 318 * 319 * @param listenKey 320 * A listen key obtained from a previous call to {@link 321 * #startListening(String)} or {@link #startListening()}. 322 * 323 * @param acceptTimeout 324 * if this transport service supports an accept timeout, and 325 * if {@code acceptTimeout} is positive then block for up to 326 * {@code acceptTimeout} milliseconds, more or less, while waiting 327 * for the target VM to connect. 328 * If the transport service does not support an accept timeout 329 * or if {@code acceptTimeout} is zero then block indefinitely 330 * for a target VM to connect. 331 * 332 * @param handshakeTimeout 333 * If this transport service supports a handshake timeout, 334 * and if {@code handshakeTimeout} is positive, then it 335 * specifies the timeout, in milliseconds (more or less), to 336 * use when handshaking with the target VM. The exact 337 * usage of the timeout is specific to the transport service. 338 * A transport service may, for example, use the handshake 339 * timeout as the inter-character timeout while waiting for 340 * the <i>JDWP-Handshake</i> message from the target VM. 341 * Alternatively, a transport service may, for example, 342 * use the timeout as a timeout for the duration of the 343 * handshake exchange. 344 * If the transport service does not support a handshake 345 * timeout, of if {@code handshakeTimeout} is specified 346 * as zero then the handshake does not timeout if there 347 * isn't a response from the target VM. 348 * 349 * @return The Connection representing the bi-directional 350 * communication channel to the target VM. 351 * 352 * @throws TransportTimeoutException 353 * If a timeout occurs while waiting for a target VM 354 * to connect. 355 * 356 * @throws IOException 357 * If an I/O error occurs (including a timeout when 358 * handshaking). 359 * 360 * @throws IllegalArgumentException 361 * If the value of the acceptTimeout argument, or 362 * handshakeTimeout is negative, or an invalid listen key 363 * is provided. 364 * 365 * @throws IllegalStateException 366 * If {@link #stopListening stopListening} has already been 367 * called with this listen key and the transport service 368 * is no longer listening for inbound connections. 369 * 370 * @see TransportService.Capabilities#supportsAcceptTimeout() 371 */ 372 public abstract Connection accept(ListenKey listenKey, long acceptTimeout, 373 long handshakeTimeout) throws IOException; 374 }