electronicarts / ea-async

EA Async implements async-await methods in the JVM.
https://go.ea.com/ea-async
Other
1.38k stars 129 forks source link

Says "the method invoking await must return a CompletableFuture" but it does already #34

Open DidierLoiseau opened 5 years ago

DidierLoiseau commented 5 years ago

If you forget to instrument the code, the wrong warning message is printed:

WARN com.ea.async.Async - Warning: Illegal call to await, the method invoking await must return a CompletableFuture

instead of

Warning: Illegal call to await, static { Async.init(); } must be added to the main program class and the method invoking await must return a CompletableFuture

As shown by the following simple example:

import java.util.concurrent.CompletableFuture;

import com.ea.async.Async;

public class EAsyncTest {

    static CompletableFuture<String> convert(CompletableFuture<?> future) {
        Object result = Async.await(future);
        return CompletableFuture.completedFuture(result.toString());
    }

    public static void main(String[] args) {
        convert(new CompletableFuture<>());
    }
}

This is because calling InitializeAsync.isRunning() triggers the class initialization, and only enters that method once isRunning = true. The only ways to have isRunning() returning false is if either the initialization crashes or if called from multiple threads.

In addition, I think it would be better to throw an exception than calling join(). In the above example this causes a deadlock, and you don't know which method it is referring to.

TryingToImprove commented 5 years ago

It also seems like if you have instrumented your code it will always give:

WARN com.ea.async.Async - Warning: Illegal call to await, the method invoking await must return a CompletableFuture

I am not sure if the else part should have been something like below instead

        if (!InitializeAsync.isRunning()) {
            warning = "Warning: Illegal call to await, static { Async.init(); } must be added to the main program class and the method invoking await must return a CompletableFuture";
        } else if (!(future instanceof CompletableFuture)) {
            warning = "Warning: Illegal call to await, the method invoking await must return a CompletableFuture";
        }
DidierLoiseau commented 4 years ago

@TryingToImprove if you have properly instrumented your code, the call to await() is removed, so you shouldn't get a warning.

spyro2000 commented 4 years ago

Getting this warning, too, despite initialized directly in the main method with Await.init().

jpines-vi commented 2 years ago

I am seeing this, too, even while my code (under test) runs as expected. Would a reproducer be helpful?