JavaTM Platform Debugger Architecture

Home Page
The Java Platform Debugger Architecture (JPDA) consists of two interfaces (JVMTI and JDI), a protocol (JDWP) and two software components which tie them together (back-end and front-end). JVMTI is a new interface in J2SE 5.0 which replaces JVMDI. The intent is multi-fold:


See Java Platform Debugger Architecture.


Details of the modular structure of JPDA are discussed below. In each case the standard JPDA usage is described. The reference implementation is described and alternative implementations and clients of the interface are discussed.

JVMTI Modularity

The Java Virtual Machine Tool Interface (JVMTI) describes the functionality provided by a virtual machine (VM) in order to allow debugging of Java programming language applications running under this VM. In JPDA, JVMTI is implemented by a VM and the client is the JPDA back-end. In the reference implementation of JPDA, JVMTI is implemented by the Java HotSpot VM and the client is the reference implementation of the back-end, supplied as a native shared library (, jdwp.dll, ...), which is shipped with the JDK.

Many VMs other than the Java HotSpot VM implement JVMTI. The reference implementation of the back-end has been ported to other platforms. And there are JVMTI clients other than the back-end, most notably agents for applications that allow debugging of both native and Java programming language code, and thus need native level control and information. We are aware of no clean-room implementations of the back-end, although this is possible - and a lot of work.

JDWP Modularity

The Java Debug Wire Protocol (JDWP) describes the format of debugging information and requests between a debuggee and a debugger. In JPDA, there is a communication channel between the front-end (in the debugger process) and the back-end (in the debuggee process) - the format of data flowing on this channel is described by JDWP. In the reference implementation of JPDA, the reference implementation of the back-end (above) provides the debuggee side of this channel, and the reference implementation of the front-end (a Java programming language component of the JDK, located in tools.jar) provides the debugger side.

JVMTI is problematic to implement in some VMs. JDWP is implemented directly in such VMs. On the client side, an application written in a language other than the Java programming language may not be an optimal candidate for using JDI. Some have chosen to be clients of JDWP.

JDI Modularity

The Java Debug Interface (JDI) provides a pure Java programming language interface for debugging Java programming language applications. In JPDA, the JDI is a remote view in the debugger process of a virtual machine in the debuggee process. It is implemented by the front-end (above) while a debugger-like application (IDE, debugger, tracer, monitoring tool, ...) is the client.

The JDI could be implemented by a system with a static view of an application. It could be implemented by a system with a mechanism utterly different than JDWP/front-end for collecting information or controlling a VM.


The various ways that the interfaces can be used is discussed above. This section will examine how the standard full JPDA works. The examples go into detail about specific calls and codes. It is not important to understand these -- they are present only to make the examples more concrete.

Across each interface there are two classes of activity: requests and events. Requests originate on the debugger side and include queries for information, setting of state changes in the remote VM/application, and setting of debugging state. Events originate on the debuggee side and denote changes of state in the remote VM/application.

Let's walk through an example. A user clicks on a local variable in a stack view in an IDE, requesting its value. The IDE uses the JDI to get the value, in particular it calls the getValue method, for example:

Where theStackFrame is a com.sun.jdi.StackFrame and theLocalVariable is a com.sun.jdi.LocalVariable.

The front-end then sends this query over a communications channel (let's say a socket) to the back-end running in the debuggee process. It sends it by formatting it into a byte stream in accordance with the JDWP. In particular, it sends a GetValues command (byte value: 1) in the StackFrame command set (byte value: 16), followed by the thread ID, frame ID, etc.

The back-end deciphers the byte-stream and sends the query off to the VM through the JVMTI. In particular, let's say the requested value is an integer, the following JVMTI function call is made:

    error = jvmti->GetLocalInt(frame, slot, &intValue);
The back-end sends back across the socket, a response packet, which will include the value of intValue, and which will be formatted according to JDWP. The front-end deciphers the response packet and returns the value as the value of the getValue method call. The IDE then displays the value.

Requests to change debugging state are processed in a similar manner. For example, a request to set a breakpoint goes through the same steps -- although, of course, the JDI methods called, the JDWP commands sent, and the JVMTI functions called are different. Additionally, the front-end and back-end do more than shove data back and forth, they track and schedule activity and convert, filter, and cache information, so a breakpoint request will be processed quite differently than a get value query - but the communication sequence will be the same.

What happens when the application being debugged finally hits this breakpoint? This is where events come into play. The virtual machine sends an event across the JVMTI interface. In particular, it calls the event handling function passing the breakpoint:

The back-end has set the event handling function to be:

static void Breakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jmethodID method, jlocation location) { ...
This back-end function starts a chain of activity which filters the event to see if it is interesting, queues it, and sends it across the socket in the JDWP format defined for breakpoint events. The front-end decodes and processes the event, eventually generating a JDI event. In particular, the JDI event is exposing it as a The IDE then gets the event by removing it from the event queue:
where theEventQueue is a com.sun.jdi.event.EventQueue. The IDE will probably update its displays by making many query calls across the JDI.


Each virtual machine implementation needs its own JVMTI implementation -- a JVMTI implementation must dig deeply into VM data structures and must set hooks into the VM implementation in order to get events. Adding JVMDT to a VM without JVMTI support is a significant undertaking. Depending on the complexity of the VM and the amount of optional JVMTI implemented, it might be a three to twelve month project. Porting a VM which has JVMTI support to a new platform is primarily the work of porting the non-JVMTI portions of the VM -- JVMTI adds a comparatively small amount of work.

The reference implementation of the back-end can usually be moved to a new platform with little (a few lines) or no change to the source and then recompiled. To use a new VM on the same platform, the binary of the back-end should generally work -- although, it's not Java programming language code so you never know. Note that licensing issues are not covered by this document.

The front-end implementation is written in the Java programming language and will run on any platform or VM. However, the connector code has functionality that may need to be extended for some systems. For example, the reference implementation of the front-end includes a launcher which assumes virtual machines are launched using J2SE conventions. A user of the JDI can configure any launcher syntax he or she wants, but generally a debugger application would prefer to leave this to the JDI implementation. If a different type of communication channel is desired (serial, for example) this too would need to be added. Plans are to eventually add an SPI to the JDI to allow these addition. Currently, however, these require changes to the source.

Copyright © 2004 Sun Microsystems, Inc. All Rights Reserved. 

Please send comments to: