发生异常时,ExecutorService runnable 从不点击尝试

ExecutorService runnable never hits try when an Exception occurs

我正在尝试使用 CompletableFuture<T> 来响应正在创建的 LWJGL OpenGL 上下文。这是通过在 LWJGLGameWindow 上调用 open 方法来完成的。这是相关代码:

  @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;
  }

这个想法是推迟在计划的执行程序服务上创建显示。这被设置为单线程计划执行程序服务,因为 OpenGL 上下文是线程绑定的。如果连接到 LWJGL 花费的时间太长,那么 returned 的未来会提前自我突破。

问题是在单元测试中,这绝对是顺畅的。但是,当我尝试调试程序时,对任何 display 方法的任何调用都会导致 lwjgl 抛出真正的异常(因为我的 lwjgl 库未链接。这仍然作为 LwjglException, 虽然)。由于某种原因,此异常并未从此处代码中的 try-catch 中获取,而是被吞噬了; future 永远不会异常完成。

所以在某处,我的异常被这段代码吞没了。

注意:display 只是围绕 LWJGL 的 Display 的一个界面 - 那里没有什么花哨的魔法。 scheduledExecutorService 是单线程计划执行程序。

我也很欣赏 scheduledExecutorService 上的 .submit()schedule 都 return Future<T> 但这缺少我想从 CompletableFuture<T>。如果可能的话,我希望能够继续使用它。

该代码实际上完全可以正常工作。真正的问题是我预期的错误 java.lang.UnsatisifiedLinkError 不是 Exception,而是 Error。修改代码以捕捉 Throwable 解决了这个问题。