Reputation: 10538
I am trying to use a CompletableFuture<T>
to respond to a LWJGL OpenGL context being created. This is done by calling the open
method on LWJGLGameWindow
. Here is the concerning code:
@Override
public CompletableFuture<?> open() {
CompletableFuture<Void> future = new CompletableFuture<>();
scheduledExecutorService.schedule(() -> {
future.completeExceptionally(new TimeoutException("Could not establish contact with LWJGL"));
}, 2000, TimeUnit.MILLISECONDS);
scheduledExecutorService.execute(() -> {
try {
display.setDisplayMode(new DisplayMode(defaultWidth, defaultHeight));
display.create();
future.complete(null);
} catch (LWJGLException e) {
future.completeExceptionally(e);
}
});
return future;
}
The idea is to defer the creation of a display on a scheduled executor service. This is set up to be a single threaded scheduled executor service, because OpenGL contexts are thread-bound. If it takes too long to connect to LWJGL, then the returned future will break out of itself early.
The problem is that in unit tests, this works absolutely swimmingly. However, when I try and debug the program, any call to any of the display
methods results in a real exception being thrown by lwjgl (because my library for lwjgl is not linked. This is still thrown as a LwjglException
, though). For some reason, this exception is not picked up from the try-catch in this code here, and instead the exception is swallowed; the future
never gets completed exceptionally.
So somewhere along the line, my exception is being swallowed in this code.
NB: display
is simply a interface around LWJGL's Display
- no fancy magic going on there. scheduledExecutorService
is a single threaded scheduled executor.
I also appreciate that .submit()
and schedule
on scheduledExecutorService
both return Future<T>
but this lacks the composition I would like to use from CompletableFuture<T>
. I'd like to be able to keep using that if at all possible.
Upvotes: 2
Views: 128
Reputation: 10538
The code actually works exactly as it should. The real problem is that the error I was expecting, java.lang.UnsatisifiedLinkError
, is not an Exception
but actually an Error
. Amending the code to catch a Throwable
solves this issue.
Upvotes: 1