下面列出了怎么用com.sun.jdi.ClassNotLoadedException的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == null) {
// Ignore resume.
return ;
}
LOG.fine("Current frame changed>");
if (steppingField != null) {
try {
serviceClass.setValue(steppingField, serviceClass.virtualMachine().mirrorOf(-1));
steppingField = null;
RemoteServices.interruptServiceAccessThread(debugger);
LOG.fine("StepIntoScriptHandler: isSteppingInto set to false.");
} catch (InvalidTypeException | ClassNotLoadedException ex) {
Exceptions.printStackTrace(ex);
}
} else {
// Cancel step into when the service is created
DebugManagerHandler.execStepInto(debugger, false);
}
}
@Override
public void setValue(Value value) {
try {
if (fieldObject != null) {
fieldObject.setValue(field, value);
} else {
((ClassType) field.declaringType()).setValue(field, value);
}
} catch (IllegalArgumentException iaex) {
throw new IllegalStateException(new InvalidExpressionException (iaex));
} catch (InvalidTypeException itex) {
throw new IllegalStateException(new InvalidExpressionException (itex));
} catch (ClassNotLoadedException cnlex) {
throw new IllegalStateException(cnlex);
}
}
private Value handleSetValueForObject(String name, String belongToClass, String valueString,
ObjectReference container, Map<String, Object> options) throws InvalidTypeException, ClassNotLoadedException {
Value newValue;
if (container instanceof ArrayReference) {
ArrayReference array = (ArrayReference) container;
Type eleType = ((ArrayType) array.referenceType()).componentType();
newValue = setArrayValue(array, eleType, Integer.parseInt(name), valueString, options);
} else {
if (StringUtils.isBlank(belongToClass)) {
Field field = container.referenceType().fieldByName(name);
if (field != null) {
if (field.isStatic()) {
newValue = this.setStaticFieldValue(container.referenceType(), field, name, valueString, options);
} else {
newValue = this.setObjectFieldValue(container, field, name, valueString, options);
}
} else {
throw new IllegalArgumentException(
String.format("SetVariableRequest: Variable %s cannot be found.", name));
}
} else {
newValue = setFieldValueWithConflict(container, container.referenceType().allFields(), name, belongToClass, valueString, options);
}
}
return newValue;
}
private Value setFieldValueWithConflict(ObjectReference obj, List<Field> fields, String name, String belongToClass,
String value, Map<String, Object> options) throws ClassNotLoadedException, InvalidTypeException {
Field field;
// first try to resolve field by fully qualified name
List<Field> narrowedFields = fields.stream().filter(TypeComponent::isStatic)
.filter(t -> t.name().equals(name) && t.declaringType().name().equals(belongToClass))
.collect(Collectors.toList());
if (narrowedFields.isEmpty()) {
// second try to resolve field by formatted name
narrowedFields = fields.stream().filter(TypeComponent::isStatic)
.filter(t -> t.name().equals(name)
&& context.getVariableFormatter().typeToString(t.declaringType(), options).equals(belongToClass))
.collect(Collectors.toList());
}
if (narrowedFields.size() == 1) {
field = narrowedFields.get(0);
} else {
throw new UnsupportedOperationException(String.format("SetVariableRequest: Name conflicted for %s.", name));
}
return field.isStatic() ? setStaticFieldValue(field.declaringType(), field, name, value, options)
: this.setObjectFieldValue(obj, field, name, value, options);
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
private static void resumeMedia(ThreadReference tr, VirtualMachine vm) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException {
if (!pausedPlayers.isEmpty()) {
final InterfaceType mediaPlayerClass = getInterface(vm, tr, "com.sun.media.jfxmedia.MediaPlayer");
List<Method> play = mediaPlayerClass.methodsByName("play", "()V");
if (play.isEmpty()) {
return;
}
Method p = play.iterator().next();
for(ObjectReference pR : pausedPlayers) {
pR.invokeMethod(tr, p, Collections.emptyList(), ObjectReference.INVOKE_SINGLE_THREADED);
}
}
}
private static ReferenceType getType(VirtualMachine vm, ThreadReference tr, String name) {
List<ReferenceType> classList = VirtualMachineWrapper.classesByName0(vm, name);
if (!classList.isEmpty()) {
return classList.iterator().next();
}
List<ReferenceType> classClassList = VirtualMachineWrapper.classesByName0(vm, "java.lang.Class"); // NOI18N
if (classClassList.isEmpty()) {
throw new IllegalStateException("Cannot load class Class"); // NOI18N
}
ClassType cls = (ClassType) classClassList.iterator().next();
try {
Method m = ClassTypeWrapper.concreteMethodByName(cls, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); // NOI18N
StringReference mirrorOfName = VirtualMachineWrapper.mirrorOf(vm, name);
ClassTypeWrapper.invokeMethod(cls, tr, m, Collections.singletonList(mirrorOfName), ObjectReference.INVOKE_SINGLE_THREADED);
List<ReferenceType> classList2 = VirtualMachineWrapper.classesByName0(vm, name);
if (!classList2.isEmpty()) {
return classList2.iterator().next();
}
} catch (ClassNotLoadedException | ClassNotPreparedExceptionWrapper |
IncompatibleThreadStateException | InvalidTypeException |
InvocationException | InternalExceptionWrapper |
ObjectCollectedExceptionWrapper | UnsupportedOperationExceptionWrapper |
VMDisconnectedExceptionWrapper ex) {
logger.log(Level.FINE, "Cannot load class " + name, ex); // NOI18N
}
return null;
}
private static ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes,
ByteValue[] mirrorBytesCache) throws InvalidTypeException,
ClassNotLoadedException,
InternalExceptionWrapper,
VMDisconnectedExceptionWrapper,
ObjectCollectedExceptionWrapper,
UnsupportedOperationExceptionWrapper {
ArrayType bytesArrayClass = getArrayClass(vm, "byte[]");
ArrayReference array = null;
boolean disabledCollection = false;
while (!disabledCollection) {
array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length);
try {
ObjectReferenceWrapper.disableCollection(array);
disabledCollection = true;
} catch (ObjectCollectedExceptionWrapper ocex) {
// Collected too soon, try again...
}
}
List<Value> values = new ArrayList<Value>(bytes.length);
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
ByteValue mb = mirrorBytesCache[128 + b];
if (mb == null) {
mb = VirtualMachineWrapper.mirrorOf(vm, b);
mirrorBytesCache[128 + b] = mb;
}
values.add(mb);
}
ArrayReferenceWrapper.setValues(array, values);
return array;
}
public boolean sendStopUserCode() throws IllegalStateException {
if (closed) {
return false;
}
vm.suspend();
try {
ObjectReference myRef = getAgentObjectReference();
OUTER:
for (ThreadReference thread : vm.allThreads()) {
// could also tag the thread (e.g. using name), to find it easier
AGENT: for (StackFrame frame : thread.frames()) {
if (REMOTE_AGENT_CLASS.equals(frame.location().declaringType().name())) {
String n = frame.location().method().name();
if (AGENT_INVOKE_METHOD.equals(n) || AGENT_VARVALUE_METHOD.equals(n)) {
ObjectReference thiz = frame.thisObject();
if (myRef != null && myRef != thiz) {
break AGENT;
}
if (((BooleanValue) thiz.getValue(thiz.referenceType().fieldByName("inClientCode"))).value()) {
thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(true));
ObjectReference stopInstance = (ObjectReference) thiz.getValue(thiz.referenceType().fieldByName("stopException"));
vm.resume();
thread.stop(stopInstance);
thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(false));
}
return true;
}
}
}
}
} catch (ClassNotLoadedException | IncompatibleThreadStateException | InvalidTypeException ex) {
throw new IllegalStateException(ex);
} finally {
vm.resume();
}
return false;
}
private static ObjectReference getTruffleClassLoader(ThreadReference tawt, VirtualMachine vm) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException, IOException, PropertyVetoException, InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ObjectCollectedExceptionWrapper, UnsupportedOperationExceptionWrapper, ClassNotPreparedExceptionWrapper {
/* Use:
com.oracle.truffle.api.impl.TruffleLocator.class.getClassLoader()
*/
ClassType truffleLocatorClass = getClass(vm, "com.oracle.truffle.api.impl.TruffleLocator");
return truffleLocatorClass.classLoader();
}
private static ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes,
ByteValue[] mirrorBytesCache) throws InvalidTypeException,
ClassNotLoadedException,
InternalExceptionWrapper,
VMDisconnectedExceptionWrapper,
ObjectCollectedExceptionWrapper,
UnsupportedOperationExceptionWrapper {
ArrayType bytesArrayClass = getArrayClass(vm, "byte[]");
ArrayReference array = null;
boolean disabledCollection = false;
while (!disabledCollection) {
array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length);
try {
ObjectReferenceWrapper.disableCollection(array);
disabledCollection = true;
} catch (ObjectCollectedExceptionWrapper ocex) {
// Collected too soon, try again...
}
}
List<Value> values = new ArrayList<Value>(bytes.length);
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
ByteValue mb = mirrorBytesCache[128 + b];
if (mb == null) {
mb = VirtualMachineWrapper.mirrorOf(vm, b);
mirrorBytesCache[128 + b] = mb;
}
values.add(mb);
}
ArrayReferenceWrapper.setValues(array, values);
return array;
}
private static void setValueToFinalField(ObjectReference obj, String name, ClassType clazz, Value fv, VirtualMachine vm, ThreadReference thread) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ClassNotPreparedExceptionWrapper, ClassNotLoadedException, ObjectCollectedExceptionWrapper, IncompatibleThreadStateException, UnsupportedOperationExceptionWrapper, InvalidTypeException, InvalidObjectException {
ObjectReference fieldRef = getDeclaredOrInheritedField(clazz, name, vm, thread);
if (fieldRef == null) {
InvalidObjectException ioex = new InvalidObjectException("No field "+name+" of class "+clazz);
throw ioex;
}
// field.setAccessible(true);
ClassType fieldClassType = (ClassType) ValueWrapper.type(fieldRef);
com.sun.jdi.Method setAccessibleMethod = ClassTypeWrapper.concreteMethodByName(
fieldClassType, "setAccessible", "(Z)V");
try {
ObjectReferenceWrapper.invokeMethod(fieldRef, thread, setAccessibleMethod,
Collections.singletonList(vm.mirrorOf(true)),
ClassType.INVOKE_SINGLE_THREADED);
// field.set(newInstance, fv);
com.sun.jdi.Method setMethod = ClassTypeWrapper.concreteMethodByName(
fieldClassType, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
if (fv instanceof PrimitiveValue) {
PrimitiveType pt = (PrimitiveType) ValueWrapper.type(fv);
ReferenceType fieldBoxingClass = EvaluatorVisitor.adjustBoxingType(clazz, pt, null);
fv = EvaluatorVisitor.box((PrimitiveValue) fv, fieldBoxingClass, thread, null);
}
List<Value> args = Arrays.asList(new Value[] { obj, fv });
ObjectReferenceWrapper.invokeMethod(fieldRef, thread, setMethod,
args,
ClassType.INVOKE_SINGLE_THREADED);
} catch (InvocationException iex) {
throw new InvalidObjectException(
"Problem setting value "+fv+" to field "+name+" of class "+clazz+
" : "+iex.exception());
}
}
private static ObjectReference getDeclaredOrInheritedField(ClassType clazz, String name, VirtualMachine vm, ThreadReference thread) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ClassNotPreparedExceptionWrapper, ClassNotLoadedException, ObjectCollectedExceptionWrapper, IncompatibleThreadStateException, UnsupportedOperationExceptionWrapper, InvalidTypeException {
//try {
// java.lang.reflect.Field field = clazz.getDeclaredField(name);
// return field;
//} catch (NoSuchFieldException ex) {}
ClassType classType = (ClassType) getOrLoadClass(vm, "java.lang.Class");
com.sun.jdi.Method getDeclaredFieldMethod = ClassTypeWrapper.concreteMethodByName(
classType, "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;");
try {
ObjectReference fieldRef = (ObjectReference)
ObjectReferenceWrapper.invokeMethod(ReferenceTypeWrapper.classObject(clazz),
thread,
getDeclaredFieldMethod,
Collections.singletonList(vm.mirrorOf(name)),
ClassType.INVOKE_SINGLE_THREADED);
return fieldRef;
} catch (InvocationException ex) {
// Likely NoSuchFieldException, try the super class...
}
//Class superClass = clazz.getSuperclass();
ClassType superClass = ClassTypeWrapper.superclass(clazz);
if (superClass != null) {
return getDeclaredOrInheritedField(superClass, name, vm, thread);
} else {
return null;
}
}
private static ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes,
ByteValue[] mirrorBytesCache) throws InvalidTypeException,
ClassNotLoadedException,
InternalExceptionWrapper,
VMDisconnectedExceptionWrapper,
ObjectCollectedExceptionWrapper {
ArrayType bytesArrayClass = getArrayClass(vm, "byte[]");
ArrayReference array = null;
boolean disabledCollection = false;
while (!disabledCollection) {
array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length);
try {
ObjectReferenceWrapper.disableCollection(array);
disabledCollection = true;
} catch (ObjectCollectedExceptionWrapper ocex) {
// Collected too soon, try again...
} catch (UnsupportedOperationExceptionWrapper uex) {
// Hope it will not be GC'ed...
disabledCollection = true;
}
}
List<Value> values = new ArrayList<Value>(bytes.length);
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
ByteValue mb = mirrorBytesCache[128 + b];
if (mb == null) {
mb = VirtualMachineWrapper.mirrorOf(vm, b);
mirrorBytesCache[128 + b] = mb;
}
values.add(mb);
}
ArrayReferenceWrapper.setValues(array, values);
return array;
}
@Override
public void setValue(Value value) {
try {
context.getFrame().setValue(var, value);
} catch (InvalidTypeException itex) {
throw new IllegalStateException(new InvalidExpressionException (itex));
} catch (ClassNotLoadedException cnlex) {
throw new IllegalStateException(cnlex);
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
private Value handleSetValueForStackFrame(String name, String belongToClass, String valueString,
boolean showStaticVariables, StackFrame container, Map<String, Object> options)
throws AbsentInformationException, InvalidTypeException, ClassNotLoadedException {
Value newValue;
if (name.equals("this")) {
throw new UnsupportedOperationException("SetVariableRequest: 'This' variable cannot be changed.");
}
LocalVariable variable = container.visibleVariableByName(name);
if (StringUtils.isBlank(belongToClass) && variable != null) {
newValue = this.setFrameValue(container, variable, valueString, options);
} else {
if (showStaticVariables && container.location().method().isStatic()) {
ReferenceType type = container.location().declaringType();
if (StringUtils.isBlank(belongToClass)) {
Field field = type.fieldByName(name);
newValue = setStaticFieldValue(type, field, name, valueString, options);
} else {
newValue = setFieldValueWithConflict(null, type.allFields(), name, belongToClass,
valueString, options);
}
} else {
throw new UnsupportedOperationException(
String.format("SetVariableRequest: Variable %s cannot be found.", name));
}
}
return newValue;
}
private Value setStaticFieldValue(Type declaringType, Field field, String name, String value, Map<String, Object> options)
throws ClassNotLoadedException, InvalidTypeException {
if (field.isFinal()) {
throw new UnsupportedOperationException(
String.format("SetVariableRequest: Final field %s cannot be changed.", name));
}
if (!(declaringType instanceof ClassType)) {
throw new UnsupportedOperationException(
String.format("SetVariableRequest: Field %s in interface cannot be changed.", name));
}
return setValueProxy(field.type(), value, newValue -> ((ClassType) declaringType).setValue(field, newValue), options);
}
private Value setObjectFieldValue(ObjectReference obj, Field field, String name, String value, Map<String, Object> options)
throws ClassNotLoadedException, InvalidTypeException {
if (field.isFinal()) {
throw new UnsupportedOperationException(
String.format("SetVariableRequest: Final field %s cannot be changed.", name));
}
return setValueProxy(field.type(), value, newValue -> obj.setValue(field, newValue), options);
}
@Override
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response,
IDebugAdapterContext context) {
ExceptionInfoArguments exceptionInfoArgs = (ExceptionInfoArguments) arguments;
ThreadReference thread = DebugUtility.getThread(context.getDebugSession(), exceptionInfoArgs.threadId);
if (thread == null) {
throw AdapterUtils.createCompletionException("Thread " + exceptionInfoArgs.threadId + " doesn't exist.", ErrorCode.EXCEPTION_INFO_FAILURE);
}
JdiExceptionReference jdiException = context.getExceptionManager().getException(exceptionInfoArgs.threadId);
if (jdiException == null) {
throw AdapterUtils.createCompletionException("No exception exists in thread " + exceptionInfoArgs.threadId, ErrorCode.EXCEPTION_INFO_FAILURE);
}
Method toStringMethod = null;
for (Method method : jdiException.exception.referenceType().allMethods()) {
if (Objects.equals("toString", method.name()) && Objects.equals("()Ljava/lang/String;", method.signature())) {
toStringMethod = method;
break;
}
}
String typeName = jdiException.exception.type().name();
String exceptionToString = typeName;
if (toStringMethod != null) {
try {
Value returnValue = jdiException.exception.invokeMethod(thread, toStringMethod, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED);
exceptionToString = returnValue.toString();
} catch (InvalidTypeException | ClassNotLoadedException | IncompatibleThreadStateException
| InvocationException e) {
logger.log(Level.SEVERE, String.format("Failed to get the return value of the method Exception.toString(): %s", e.toString(), e));
}
}
response.body = new Responses.ExceptionInfoResponse(typeName, exceptionToString,
jdiException.isUncaught ? ExceptionBreakMode.USERUNHANDLED : ExceptionBreakMode.ALWAYS);
return CompletableFuture.completedFuture(response);
}
private static String getGenericName(ReferenceType type) throws DebugException {
if (type instanceof ArrayType) {
try {
Type componentType;
componentType = ((ArrayType) type).componentType();
if (componentType instanceof ReferenceType) {
return getGenericName((ReferenceType) componentType) + "[]"; //$NON-NLS-1$
}
return type.name();
} catch (ClassNotLoadedException e) {
// we cannot create the generic name using the component type,
// just try to create one with the information
}
}
String signature = type.signature();
StringBuffer res = new StringBuffer(getTypeName(signature));
String genericSignature = type.genericSignature();
if (genericSignature != null) {
String[] typeParameters = Signature.getTypeParameters(genericSignature);
if (typeParameters.length > 0) {
res.append('<').append(Signature.getTypeVariable(typeParameters[0]));
for (int i = 1; i < typeParameters.length; i++) {
res.append(',').append(Signature.getTypeVariable(typeParameters[i]));
}
res.append('>');
}
}
return res.toString();
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}
/**
* Method invocation support.
* Shared by ClassType and InterfaceType
* @param threadIntf the thread in which to invoke.
* @param methodIntf method the {@link Method} to invoke.
* @param origArguments 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 type, if the size of the argument list
* does not match the number of declared arguments for the method, or
* if the method is not static or is a static initializer.
* @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument
* type.
* @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()}.
*/
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List<? extends Value> origArguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
MethodImpl method = (MethodImpl) methodIntf;
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
validateMethodInvocation(method);
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
InvocationResult ret;
try {
PacketStream stream = sendInvokeCommand(thread, method, args, options);
ret = waitForReply(stream);
} catch (JDWPException exc) {
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
throw new IncompatibleThreadStateException();
} else {
throw exc.toJDIException();
}
}
/*
* There is an implict VM-wide suspend at the conclusion
* of a normal (non-single-threaded) method invoke
*/
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
vm.notifySuspend();
}
if (ret.getException() != null) {
throw new InvocationException(ret.getException());
} else {
return ret.getResult();
}
}