public CompletableFuture invokeMethodAsync()

in src/main/java/com/jetbrains/jdi/ObjectReferenceImpl.java [490:543]


    public CompletableFuture<Value> invokeMethodAsync(ThreadReference threadIntf, Method methodIntf,
                                                      List<? extends Value> origArguments, int options)
            throws InvalidTypeException,
            IncompatibleThreadStateException,
            InvocationException,
            ClassNotLoadedException {

        validateMirror(threadIntf);
        validateMirror(methodIntf);
        validateMirrorsOrNulls(origArguments);

        MethodImpl method = (MethodImpl) methodIntf;
        ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;

        if (method.isStatic()) {
            if (referenceType() instanceof InvokableTypeImpl) {
                InvokableTypeImpl type = (InvokableTypeImpl) referenceType();
                return type.invokeMethodAsync(thread, method, origArguments, options);
            } else {
                throw new IllegalArgumentException("Invalid type for static method invocation");
            }
        }

        validateMethodInvocation(method, options);

        List<Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments, options);

        ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
        PacketStream stream =
                sendInvokeCommand(thread, invokableReferenceType(method),
                        method, args, options);
        return stream.readReply(packet -> new JDWP.ObjectReference.InvokeMethod(vm, stream))
                .exceptionally(throwable -> {
                    throwable = AsyncUtils.unwrap(throwable);
                    if (throwable instanceof IllegalThreadStateException) {
                        throw new CompletionException(new IncompatibleThreadStateException());
                    }
                    throw (RuntimeException) throwable;
                })
                .thenApply(ret -> {
                    /*
                     * 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.exception != null) {
                        throw new CompletionException(new InvocationException(ret.exception));
                    } else {
                        return ret.returnValue;
                    }
                });
    }