GroovyScript Class Documentation

Overview

This class provides the interface between Groovy and the JDI Java classes.

Table of Contents

Breakpoint Management

setBreakpoint(String className, String methodName)

This method sets a breakpoint at the entry point of the specified method.

Parameters:
  • className: The fully qualified name of the class containing the method.

  • methodName: The name of the method where the breakpoint should be set.

setBreakpoint(String className, String methodName, Runnable callback)

Sets a breakpoint on the specified method and associates it with a callback. This method sets a breakpoint at the entry point of the specified method and associates a callback to be executed when the breakpoint is hit. The callback is executed within the dispatchEvent loop.

Parameters:
  • callback: A callback to be executed when the breakpoint is hit.

  • className: The fully qualified name of the class containing the method.

  • methodName: The name of the method where the breakpoint should be set.

Example:

setBreakpoint("io.undo.test.BreakpointTest", "sleep", {
    when = getTimestamps()
    printf("Hit sleep breakpoint at %d\n", when.currentBbcount)
})

Note

  • The callback is executed in the context of the dispatchEvent loop.

  • This method only sets the breakpoint; you must call dispatchEvent to handle events.

setBreakpoint(String className, int lineNumber)

This method sets a breakpoint at the specified line number in the given class.

Parameters:
  • className: The fully qualified name of the class containing the line.

  • lineNumber: The line number where the breakpoint should be set.

setBreakpoint(String className, int lineNumber, Runnable callback)

Sets a breakpoint on the specified line and associates it with a callback. This method sets a breakpoint at the specified line number in the given class and associates a callback to be executed when the breakpoint is hit. The callback is executed within the dispatchEvent loop.

Parameters:
  • callback: A callback to be executed when the breakpoint is hit.

  • className: The fully qualified name of the class containing the line.

  • lineNumber: The line number where the breakpoint should be set.

Example:

setBreakpoint("io.undo.test.Delayed", 15, {
    when = getTimestamps()
    i = getLocalVariable("i")
    printf("Hit run breakpoint at %d with i %s\n", when.currentBbcount, i)
})

Note

  • The callback is executed in the context of the dispatchEvent loop.

  • This method only sets the breakpoint; you must call dispatchEvent to handle events.

deleteBreakpoint(String className, int lineNumber)

Deletes a breakpoint set at the specified line. This method removes a previously set breakpoint at the given line in the specified class.

Parameters:
  • className: The fully qualified name of the class containing the breakpoint.

  • lineNumber: The line number where the breakpoint is set.

Example:

deleteBreakpoint("io.undo.test.BreakpointTest", 42)

Note

  • If no breakpoint exists at the specified location, the method has no effect.

deleteAllBreakpoints()

Deletes all breakpoints currently set. This method removes all breakpoints in the current debugging session, regardless of their location.

Example:

deleteAllBreakpoints()

Note

  • After calling this method, no breakpoints will remain active in the session.

setExceptionBreakpoint(String className)

Sets an exception breakpoint for the specified class. This method sets a breakpoint that triggers when an exception of the specified class is thrown during program execution.

Parameters:
  • className: The fully qualified name of the exception class to monitor.

Note

  • If the specified exception class does not exist or cannot be monitored, this method may throw an exception.

setExceptionBreakpoint(String className, Runnable callback)

Sets an exception breakpoint for the specified class and associates it with a callback. This method sets a breakpoint that triggers when an exception of the specified class is thrown during program execution. When the exception is thrown, the provided callback is executed.

Parameters:
  • callback: A callback to be executed when the exception breakpoint is hit.

  • className: The fully qualified name of the exception class to monitor.

Example:

setExceptionBreakpoint("java.lang.NullPointerException", {
    println "Caught a NullPointerException!"
})

Note

  • The callback is executed in the context of the dispatchEvent loop.

  • This method only sets the exception breakpoint; you must call dispatchEvent or resume to process events.

  • If the specified exception class does not exist or cannot be monitored, this method may throw an exception.

expectExceptionBreakpoint(String className)

Resumes execution and waits for the specified exception breakpoint to be hit. This method resumes program execution and waits until an exception of the specified class is thrown. If the exception is not thrown, the method returns false.

Parameters:
  • className: The fully qualified name of the exception class to monitor.

Returns: true if the exception breakpoint is hit, false otherwise.

Example:

if (!expectExceptionBreakpoint("java.lang.NullPointerException")) {
    println "Exception breakpoint not hit."
} else {
    println "NullPointerException caught."
}

Note

  • If the exception is thrown, execution pauses at the point where it occurred.

  • This method suppresses exceptions internally; if you want exceptions to propagate, a different method or approach should be used.

Watchpoint Management

setWatchpoint(String className, String fieldName)

Sets a watchpoint on the specified field. This method sets a watchpoint on the specified field in the given class. A watchpoint monitors access or modifications to the field.

Parameters:
  • className: The fully qualified name of the class containing the field.

  • fieldName: The name of the field to watch.

setWatchpoint(String className, String fieldName, Runnable callback)

Sets a watchpoint on the specified field and associates it with a callback. This method sets a watchpoint on the specified field in the given class and associates a callback to be executed when the field is accessed or modified. The callback is executed within the dispatchEvent loop.

Parameters:
  • callback: A callback to be executed when the watchpoint is hit.

  • className: The fully qualified name of the class containing the field.

  • fieldName: The name of the field to watch.

Example:

setWatchpoint("io.undo.test.Delayed", "currenti", {
    when = getTimestamps()
    currenti = getStatic("io.undo.test.Delayed", "currenti")
    printf("Hit watchpoint at %d with currenti %s\n", when.currentBbcount, currenti)
})

Note

  • The callback is executed in the context of the dispatchEvent loop.

  • This method only sets the watchpoint; you must call dispatchEvent to handle events.

deleteWatchpoint(String className, String fieldName)

Deletes a watchpoint set on the specified field. This method removes a previously set watchpoint on the given field in the specified class.

Parameters:
  • className: The fully qualified name of the class containing the field.

  • fieldName: The name of the field with the watchpoint.

Example:

deleteWatchpoint("io.undo.test.Delayed", "currenti")

Note

  • If no watchpoint exists on the specified field, the method has no effect.

expectWatchpoint(String className, String fieldName)

Resumes execution and waits for the specified watchpoint to be hit. This method verifies that a watchpoint is triggered for the specified field in the given class. It resumes execution and waits for the program to hit the watchpoint. If the watchpoint is not hit and the end of the recording is reached, it suspends execution and returns false.

Parameters:
  • className: The fully qualified name of the class to monitor.

  • fieldName: The name of the field to monitor for changes.

Returns: true if the watchpoint is hit, false if the end of the recording is reached without hitting the watchpoint.

Note

  • If the end of the recording is reached before the watchpoint is triggered, execution is suspended.

expectWatchpointOrFail(String className, int lineNumber, String fieldName)

Resumes execution and waits for the specified watchpoint to be hit, asserting success. This method resumes execution and verifies that the specified watchpoint is triggered at the given line number for the specified field in the given class. If the watchpoint is not hit, the method throws an exception.

Parameters:
  • className: The fully qualified name of the class to monitor.

  • fieldName: The name of the field to monitor for changes.

  • lineNumber: The line number in the class where the watchpoint is expected.

Raises:
  • Exception If the watchpoint is not hit.

State and Information

frames()

Retrieves the current stack frames of the program. This method returns a list of com.sun.jdi.StackFrame objects representing the current call stack.

Returns: A list of com.sun.jdi.StackFrame objects.

Example:

def stackFrames = frames()
stackFrames.each { frame ->
    println "Class: ${frame.location().declaringType().name()}, Method: ${frame.location().method().name()}"
}

Note

  • This method provides a snapshot of the call stack at the current execution point.

currentThread()

Retrieves the current thread reference. This method returns the com.sun.jdi.ThreadReference object representing the thread currently being debugged.

Returns: The com.sun.jdi.ThreadReference for the current thread.

Example:

def thread = currentThread()
println "Current thread: ${thread.name()}"

Note

  • The returned ThreadReference provides access to information about the thread, including its name, state, and stack frames.

  • If no thread is currently active, this method may return null or throw an exception depending on the debugging context.

getTimestamps()

Retrieves timing information from the recording. The returned object has the following fields:

  • currentBbcount: The basic block count at the current location.

  • minBbcount: The minimum basic block count in the recording.

  • maxBbcount: The maximum basic block count in the recording.

  • currentUtcTime: The current UTC time in milliseconds.

  • minUtcTime: The minimum UTC time in the recording.

  • maxUtcTime: The maximum UTC time in the recording.

  • lowerUtcTime: The lower bound UTC time in microseconds at the current location.

  • upperUtcTime: The upper bound UTC time in microseconds at the current location.

    Returns: Timestamps object containing timing information.

getAllBookmarks()

Retrieves a list of all current bookmarks. This method returns a BookmarkList object containing all bookmarks currently set during the debugging session. Each bookmark in the list provides detailed information, such as its ID, location, basic block count, and thread ID.

Returns:

A BookmarkList object containing the following field: - bookmarks (List<Bookmark>): A list of Bookmark objects, each representing a single bookmark.

Raises:
  • Exception If there is an error retrieving the bookmarks.

Example:

def bookmarkList = getAllBookmarks()
println "Number of bookmarks: ${bookmarkList.bookmarks.size()}"
bookmarkList.bookmarks.each { bookmark ->
    println "Bookmark ID: ${bookmark.id}, Location: ${bookmark.location}"
}

Note

  • Each Bookmark object in the list contains:

    • id (int): The unique identifier of the bookmark.

    • location (String): The location of the bookmark in the format className.methodName:lineNumber.

    • bbcount (long): The basic block count at the bookmark location.

    • threadId (long): The ID of the thread at the bookmark location.

getLocalVariable(String variableName)

Retrieves the value of a local variable from the top stack frame. This method fetches the value of the specified local variable from the current top stack frame. If the variable is not present in the stack frame or its value is unavailable, null is returned.

Parameters:
  • variableName: The name of the local variable to retrieve.

Returns: The value of the local variable, or null if it is not available.

Raises:
  • IncompatibleThreadStateException If the thread is not in a compatible state to access variables.

  • AbsentInformationException If variable information is not available in the current context.

Note

  • If the local variable does not exist in the top stack frame or is not visible, the method returns null.

  • This method assumes the top stack frame is the context for retrieving the variable.

getLocalVariable(int index, String variableName)

Retrieves the value of a local variable from a specific stack frame. This method fetches the value of the specified local variable from the stack frame at the given index. If the variable is not present in the stack frame or its value is unavailable, null is returned.

Parameters:
  • index: The index of the stack frame to inspect (negative values count from the bottom).

  • variableName: The name of the local variable to retrieve.

Returns: The value of the local variable, or null if it is not available.

Raises:
  • IncompatibleThreadStateException If the thread is not in a compatible state to access variables.

  • AbsentInformationException If variable information is not available in the current context.

Note

  • If the local variable does not exist in the specified stack frame or is not visible, the method returns null.

  • A negative index is translated to count from the bottom of the stack, e.g., -1 for the bottom frame.

  • Use this method for cases where the desired variable is in a specific stack frame.

getStatic(String className, String fieldName)

Retrieves the value of a static field in the specified class.

Parameters:
  • className: The fully qualified name of the class containing the static field.

  • fieldName: The name of the static field to retrieve.

Returns: The value of the static field.

Note

  • If the field is not found or is inaccessible, this method may throw an exception.

thisObject()

Retrieves the this object from the current stack frame. This method returns the com.sun.jdi.ObjectReference representing the this object of the current stack frame. This allows access to the instance on which the current method is being executed.

Returns: The com.sun.jdi.ObjectReference representing the this object, or null if unavailable.

Note

  • The this object is only available in instance methods. If the current frame corresponds to a static method, this method returns null.

  • This method accesses the top stack frame (frames().get(0)).

getInstanceVariable(Object object, String fieldName)

Retrieves the value of an instance field from the specified object. This method fetches the value of the specified field from the given object instance. The returned value is a com.sun.jdi.Value which can represent various types such as primitive values, object references, or arrays.

Parameters:
  • fieldName: The name of the instance field to retrieve.

  • object: The object instance containing the field.

Returns: A com.sun.jdi.Value representing the field value, or null if unavailable.

Raises:
  • Exception If the field cannot be accessed or retrieved.

Example:

def instanceValue = getInstanceVariable(myObject, "myField")
if (instanceValue instanceof com.sun.jdi.StringReference) {
    println "Field value: ${(instanceValue as com.sun.jdi.StringReference).value()}"
} else {
    println "Field value is not a string or is null."
}

Note

  • The returned Value may represent different JDI types, such as: - IntegerValue: For integer or long fields. - FloatValue: For float or double fields. - StringReference: For String fields. - ObjectReference: For object fields.

  • Use type checks or instanceof to determine the exact type of the returned Value.

  • If the specified field does not exist or cannot be accessed, this method may throw an exception.

Event Handling

dispatchEvent()

Waits for an event to arrive and executes the associated callback. This method resumes program execution and waits for a debugging event to occur. When an event is received, the associated callback (if any) is executed. If no event is received within the timeout or the start/end of the recording is reached, the method returns false.

Returns: true if an event was processed, false if the timeout expired or the start/end of recording was reached.

Example:

while (true) {
    if (!dispatchEvent()) {
        break
    }
}

Note

  • The dispatchEvent method processes events such as breakpoints and watchpoints.

  • If the end of the recording is reached, the program is suspended automatically.

expectBreakpoint(String className, String methodName)

Resumes execution and waits for the specified breakpoint to be hit. This method resumes program execution and waits until a breakpoint at the specified method in the given class is hit. If the breakpoint is not hit and the end of the recording is reached, the program is suspended, and the method returns false.

Parameters:
  • className: The fully qualified name of the class containing the method.

  • methodName: The name of the method where the breakpoint is set.

Returns: true if the breakpoint is hit, false if the end of the recording is reached.

Example:

if (!expectBreakpoint("io.undo.test.BreakpointTest", "sleep")) {
    println "Breakpoint not hit. End of recording reached."
}

Note

  • If the breakpoint is hit, execution pauses at the specified method.

  • This method suppresses exceptions internally. Use expectBreakpointOrFail to propagate exceptions.

expectBreakpoint(String className, int lineNumber)

Resumes execution and waits for the specified breakpoint to be hit. This method resumes program execution and waits until a breakpoint at the specified line number in the given class is hit. If the breakpoint is not hit and the end of the recording is reached, the program is suspended, and the method returns false.

Parameters:
  • className: The fully qualified name of the class containing the method.

  • lineNumber: The line number where the breakpoint

  • methodName: The name of the method where the breakpoint is set.

Returns: true if the breakpoint is hit, false if the end of the recording is reached.

Note

  • If the breakpoint is hit, execution pauses at the specified method.

  • This method suppresses exceptions internally. Use expectBreakpointOrFail to propagate exceptions.

expectBreakpointOrFail(String className, String methodName)

Resumes execution and waits for the specified breakpoint to be hit, propagating exceptions if unsuccessful. This method resumes program execution and waits until a breakpoint at the specified method in the given class is hit. If the breakpoint is not hit, an exception is thrown.

Parameters:
  • className: The fully qualified name of the class containing the method.

  • methodName: The name of the method where the breakpoint is set.

Raises:
  • Exception If the breakpoint is not hit.

Note

  • If the breakpoint is hit, execution pauses at the specified method.

  • Unlike expectBreakpoint, this method does not suppress exceptions.

expectBreakpointOrFail(String className, int lineNumber)

Resumes execution and waits for the specified breakpoint to be hit, propagating exceptions if unsuccessful. This method resumes program execution and waits until a breakpoint at the specified line number in the given class is hit. If the breakpoint is not hit, an exception is thrown.

Parameters:
  • className: The fully qualified name of the class containing the line.

  • lineNumber: The line number where the breakpoint is set.

Raises:
  • Exception If the breakpoint is not hit.

Note

  • If the breakpoint is hit, execution pauses at the specified line.

  • Unlike expectBreakpoint, this method does not suppress exceptions.

expectWhere(int index, String className, int lineNumber)

Verifies the current execution point matches the expected location. This method can be used to assert that the program is currently at the specified stack frame, class, and line number. If the conditions are not met, an exception is thrown.

Parameters:
  • className: The fully qualified name of the expected class.

  • index: The stack frame index (negative values are counted from the bottom of the stack).

  • lineNumber: The expected line number in the class.

Raises:
  • Exception If the current location does not match the expected location.

Example:

expectWhere(0, "com.example.MyClass", 42)

Note

If the stack trace is:

com.example.MyClass.methodA:42
com.example.MyClass.methodB:123

Calling expectWhere(0, "com.example.MyClass", 42) verifies the current execution point is at methodA:42.

Calling expectWhere(-1, "com.example.MyClass", 123) verifies the bottom of the stack is at methodB:123.

expectWhere(int index, String className, List<Integer> lineNumbers)

Verifies the current execution point matches one of the expected locations. This method can be used to assert that the program is currently at the specified stack frame and one of the provided line numbers in the given class. If the conditions are not met, an exception is thrown.

Parameters:
  • className: The fully qualified name of the expected class.

  • index: The stack frame index (negative values are counted from the bottom of the stack).

  • lineNumbers: A list of possible line numbers to match.

Raises:
  • Exception If the current location does not match the expected class and any of the given line numbers.

Example:

expectWhere(0, "io.undo.test.BreakpointTest", [9, 13, 15, 18])

Note

  • If none of the specified line numbers match, this method throws an exception.

waitForStart()

Waits until the start of the recording is reached. This method blocks until the program execution reaches the beginning of the recording.

waitForEnd()

Waits until the end of the recording is reached. This method blocks until the program execution reaches the end of the recording.

Utility Functions

formatTime(long millis, String format)

Formats a timestamp into a human-readable date and time string. This method converts a given timestamp (in milliseconds since the epoch) into a formatted date and time string based on the specified format pattern.

Parameters:
  • format: The format pattern for the output string.

  • millis: The timestamp in milliseconds since the epoch (UTC).

Returns: The formatted date and time string.

Raises:
  • IllegalArgumentException If the format pattern is invalid.

Example:

def formattedTime = formatTime(1672531200000L, "yyyy-MM-dd HH:mm:ss")
println "Formatted time: ${formattedTime}"  // Output: "2023-01-01 00:00:00"

Note

  • The timestamp is interpreted as UTC.

  • The format pattern must be valid according to java.time.format.DateTimeFormatter. Invalid patterns may throw an IllegalArgumentException.

  • Common format examples: - yyyy-MM-dd: Formats as 2023-01-01. - HH:mm:ss: Formats as 12:34:56. - yyyy-MM-dd HH:mm:ss: Combines date and time.

setTimeout(int millis)

Sets the timeout duration when waiting for an event to arrive. This method configures the maximum time the debugger will wait for an event (e.g., a breakpoint or watchpoint hit) before timing out. The default timeout is 10 minutes (600,000 milliseconds).

Parameters:
  • millis: The timeout duration in milliseconds.

Note

  • The timeout affects methods like dispatchEvent, which wait for events to occur.

  • A longer timeout ensures the debugger waits patiently for events but may cause delays if no events occur.

  • Setting a very short timeout might cause frequent timeouts and interruptions.