/* * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.jdi; import java.util.List; import java.util.Map; /** * An object that currently exists in the target VM. An ObjectReference * mirrors only the object itself and is not specific to any * {@link Field} or {@link LocalVariable} to which it is currently * assigned. An ObjectReference can * have 0 or more references from field(s) and/or variable(s). *

* Any method on ObjectReference which directly or * indirectly takes ObjectReference as an parameter may throw * {@link com.sun.jdi.VMDisconnectedException} if the target VM is * disconnected and the {@link com.sun.jdi.event.VMDisconnectEvent} has been or is * available to be read from the {@link com.sun.jdi.event.EventQueue}. *

* Any method on ObjectReference which directly or * indirectly takes ObjectReference as an parameter may throw * {@link com.sun.jdi.VMOutOfMemoryException} if the target VM has run out of memory. *

* Any method on ObjectReference or which directly or indirectly takes * ObjectReference as parameter may throw * {@link com.sun.jdi.ObjectCollectedException} if the mirrored object has been * garbage collected. * * @author Robert Field * @author Gordon Hirsch * @author James McIlree * @since 1.3 */ public interface ObjectReference extends Value { /** * Gets the {@link ReferenceType} that mirrors the type * of this object. The type may be a subclass or implementor of the * declared type of any field or variable which currently holds it. * For example, right after the following statement. *

* Object obj = new String("Hello, world!"); *

* The ReferenceType of obj will mirror java.lang.String and not * java.lang.Object. *

* The type of an object never changes, so this method will * always return the same ReferenceType over the lifetime of the * mirrored object. *

* The returned ReferenceType will be a {@link ClassType} or * {@link ArrayType} and never an {@link InterfaceType}. * * @return the {@link ReferenceType} for this object. */ ReferenceType referenceType(); /** * Gets the value of a given instance or static field in this object. * The Field must be valid for this ObjectReference; * that is, it must be from * the mirrored object's class or a superclass of that class. * * @param sig the field containing the requested value * @return the {@link Value} of the instance field. * @throws java.lang.IllegalArgumentException if the field is not valid for * this object's class. */ Value getValue(Field sig); /** * Gets the value of multiple instance and/or static fields in this object. * The Fields must be valid for this ObjectReference; * that is, they must be from * the mirrored object's class or a superclass of that class. * * @param fields a list of {@link Field} objects containing the * requested values. * @return a Map of the requested {@link Field} objects with * their {@link Value}. * @throws java.lang.IllegalArgumentException if any field is not valid for * this object's class. */ Map getValues(List fields); /** * Sets the value of a given instance or static field in this object. * The {@link Field} must be valid for this ObjectReference; that is, * it must be from the mirrored object's class or a superclass of that class. * If static, the field must not be final. *

* Object values must be assignment compatible with the field type * (This implies that the field type must be loaded through the * enclosing class's class loader). Primitive values must be * either assignment compatible with the field type or must be * convertible to the field type without loss of information. * See section 5.2 of * The Java™ Language Specification * for more information on assignment * compatibility. * * @param field the field containing the requested value * @param value the new value to assign * @throws java.lang.IllegalArgumentException if the field is not valid for * this object's class. * @throws InvalidTypeException if the value's type does not match * the field's type. * @throws ClassNotLoadedException if 'value' is not null, and the field * type has not yet been loaded through the appropriate class loader. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. */ void setValue(Field field, Value value) throws InvalidTypeException, ClassNotLoadedException; /** Perform method invocation with only the invoking thread resumed */ static final int INVOKE_SINGLE_THREADED = 0x1; /** Perform non-virtual method invocation */ static final int INVOKE_NONVIRTUAL = 0x2; /** * Invokes the specified {@link Method} on this object in the * target VM. The * specified method can be defined in this object's class, * in a superclass of this object's class, or in an interface * implemented by this object. The method may be a static method * or an instance method, but not a static initializer or constructor. * Use {@link ClassType#newInstance} to create a new object and * run its constructor. *

* The method invocation will occur in the specified thread. * Method invocation can occur only if the specified thread * has been suspended by an event which occurred in that thread. * Method invocation is not supported * when the target VM has been suspended through * {@link VirtualMachine#suspend} or when the specified thread * is suspended through {@link ThreadReference#suspend}. *

* The specified method is invoked with the arguments in the specified * argument list. The method invocation is synchronous; this method * does not return until the invoked method returns in the target VM. * If the invoked method throws an exception, this method * will throw an {@link InvocationException} which contains * a mirror to the exception object thrown. *

* Object arguments must be assignment compatible with the argument type * (This implies that the argument type must be loaded through the * enclosing class's class loader). Primitive arguments must be * either assignment compatible with the argument type or must be * convertible to the argument type without loss of information. * If the method being called accepts a variable number of arguments, * then the last argument type is an array of some component type. * The argument in the matching position can be omitted, or can be null, * an array of the same component type, or an argument of the * component type followed by any number of other arguments of the same * type. If the argument is omitted, then a 0 length array of the * component type is passed. The component type can be a primitive type. * Autoboxing is not supported. * * See section 5.2 of * The Java™ Language Specification * for more information on assignment compatibility. *

* By default, the method is invoked using dynamic lookup as * documented in section 15.12.4.4 of * The Java™ Language Specification * in particular, overriding based on the runtime type of the object * mirrored by this {@link ObjectReference} will occur. This * behavior can be changed by specifying the * {@link #INVOKE_NONVIRTUAL} bit flag in the options * argument. If this flag is set, the specified method is invoked * whether or not it is overridden for this object's runtime type. * The method, in this case, must have an implementation, either in a class * or an interface. This option is useful for performing method invocations * like those done with the super keyword in the Java programming * language. *

* By default, all threads in the target VM are resumed while * the method is being invoked if they were previously * suspended by an event or by {@link VirtualMachine#suspend} or * {@link ThreadReference#suspend}. This is done to prevent the deadlocks * that will occur if any of the threads own monitors * that will be needed by the invoked method. * Note, however, that this implicit resume acts exactly like * {@link ThreadReference#resume}, so if the thread's suspend * count is greater than 1, it will remain in a suspended state * during the invocation and thus a deadlock could still occur. * By default, when the invocation completes, * all threads in the target VM are suspended, regardless their state * before the invocation. * It is possible that * breakpoints or other events might occur during the invocation. * This can cause deadlocks as described above. It can also cause a deadlock * if invokeMethod is called from the client's event handler thread. In this * case, this thread will be waiting for the invokeMethod to complete and * won't read the EventSet that comes in for the new event. If this * new EventSet is SUSPEND_ALL, then a deadlock will occur because no * one will resume the EventSet. To avoid this, all EventRequests should * be disabled before doing the invokeMethod, or the invokeMethod should * not be done from the client's event handler thread. *

* The resumption of other threads during the invocation can be prevented * by specifying the {@link #INVOKE_SINGLE_THREADED} * bit flag in the options argument; however, * there is no protection against or recovery from the deadlocks * described above, so this option should be used with great caution. * Only the specified thread will be resumed (as described for all * threads above). Upon completion of a single threaded invoke, the invoking thread * will be suspended once again. Note that any threads started during * the single threaded invocation will not be suspended when the * invocation completes. *

* If the target VM is disconnected during the invoke (for example, through * {@link VirtualMachine#dispose}) the method invocation continues. * * @param thread the thread in which to invoke. * @param method the {@link Method} to invoke. * @param arguments the list of {@link Value} arguments bound to the * invoked method. Values from the list are assigned to arguments * in the order they appear in the method signature. * @param options the integer bit flag options. * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this object's class, if the size of the argument list * does not match the number of declared arguments for the method, * if the method is a constructor or static initializer, or * if {@link #INVOKE_NONVIRTUAL} is specified and the method is * abstract. * @throws ClassNotLoadedException if any argument type has not yet been loaded * through the appropriate class loader. * @throws IncompatibleThreadStateException if the specified thread has not * been suspended by an event. * @throws InvocationException if the method invocation resulted in * an exception in the target VM. * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be * loaded through the enclosing class's class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment * compatibility. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. */ Value invokeMethod(ThreadReference thread, Method method, List arguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException; /** * Prevents garbage collection for this object. By default all * {@link ObjectReference} values returned by JDI may be collected * at any time the target VM is running. A call to this method * guarantees that the object will not be collected. * {@link #enableCollection} can be used to allow collection once * again. *

* Calls to this method are counted. Every call to this method * requires a corresponding call to {@link #enableCollection} before * garbage collection is re-enabled. *

* Note that while the target VM is suspended, no garbage collection * will occur because all threads are suspended. The typical * examination of variables, fields, and arrays during the suspension * is safe without explicitly disabling garbage collection. *

* This method should be used sparingly, as it alters the * pattern of garbage collection in the target VM and, * consequently, may result in application behavior under the * debugger that differs from its non-debugged behavior. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only * -see {@link VirtualMachine#canBeModified()}. */ void disableCollection(); /** * Permits garbage collection for this object. By default all * {@link ObjectReference} values returned by JDI may be collected * at any time the target VM is running. A call to this method * is necessary only if garbage collection was previously disabled * with {@link #disableCollection}. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only * -see {@link VirtualMachine#canBeModified()}. */ void enableCollection(); /** * Determines if this object has been garbage collected in the target * VM. * * @return true if this {@link ObjectReference} has been collected; * false otherwise. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only * -see {@link VirtualMachine#canBeModified()}. */ boolean isCollected(); /** * Returns a unique identifier for this ObjectReference. * It is guaranteed to be unique among all * ObjectReferences from the same VM that have not yet been disposed. * The guarantee applies as long * as this ObjectReference has not yet been disposed. * * @return a long unique ID */ long uniqueID(); /** * Returns a List containing a {@link ThreadReference} for * each thread currently waiting for this object's monitor. * See {@link ThreadReference#currentContendedMonitor} for * information about when a thread is considered to be waiting * for a monitor. *

* Not all target VMs support this operation. See * VirtualMachine#canGetMonitorInfo to determine if the * operation is supported. * * @return a List of {@link ThreadReference} objects. The list * has zero length if no threads are waiting for the monitor. * @throws java.lang.UnsupportedOperationException if the * target VM does not support this operation. * @throws IncompatibleThreadStateException if any * waiting thread is not suspended * in the target VM */ List waitingThreads() throws IncompatibleThreadStateException; /** * Returns an {@link ThreadReference} for the thread, if any, * which currently owns this object's monitor. * See {@link ThreadReference#ownedMonitors} for a definition * of ownership. *

* Not all target VMs support this operation. See * VirtualMachine#canGetMonitorInfo to determine if the * operation is supported. * * @return the {@link ThreadReference} which currently owns the * monitor, or null if it is unowned. * * @throws java.lang.UnsupportedOperationException if the * target VM does not support this operation. * @throws IncompatibleThreadStateException if the owning thread is * not suspended in the target VM */ ThreadReference owningThread() throws IncompatibleThreadStateException; /** * Returns the number times this object's monitor has been * entered by the current owning thread. * See {@link ThreadReference#ownedMonitors} for a definition * of ownership. *

* Not all target VMs support this operation. See * VirtualMachine#canGetMonitorInfo to determine if the * operation is supported. * * @see #owningThread * @return the integer count of the number of entries. * * @throws java.lang.UnsupportedOperationException if the * target VM does not support this operation. * @throws IncompatibleThreadStateException if the owning thread is * not suspended in the target VM */ int entryCount() throws IncompatibleThreadStateException; /** * Returns objects that directly reference this object. * Only objects that are reachable for the purposes of garbage collection * are returned. Note that an object can also be referenced in other ways, * such as from a local variable in a stack frame, or from a JNI global * reference. Such non-object referrers are not returned by this method. *

* Not all target virtual machines support this operation. * Use {@link VirtualMachine#canGetInstanceInfo()} * to determine if the operation is supported. * * @see VirtualMachine#instanceCounts(List) * @see ReferenceType#instances(long) * @param maxReferrers The maximum number of referring objects to return. * Must be non-negative. If zero, all referring * objects are returned. * @return a of List of {@link ObjectReference} objects. If there are * no objects that reference this object, a zero-length list is returned.. * @throws java.lang.UnsupportedOperationException if * the target virtual machine does not support this * operation - see * {@link VirtualMachine#canGetInstanceInfo() canGetInstanceInfo()} * @throws java.lang.IllegalArgumentException if maxReferrers is less * than zero. * @since 1.6 */ List referringObjects(long maxReferrers); /** * Compares the specified Object with this ObjectReference for equality. * * @return true if the Object is an ObjectReference, if the * ObjectReferences belong to the same VM, and if applying the * "==" operator on the mirrored objects in that VM evaluates to true. */ boolean equals(Object obj); /** * Returns the hash code value for this ObjectReference. * * @return the integer hash code */ int hashCode(); }