You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Project Loom中异常是否会在ExecutorService上下文向上传播?相关代码异常捕获问题咨询

Hey there, let's unpack what's going on with your exception handling issues—surprisingly, none of this is specific to Project Loom; it's all standard behavior of Java's ExecutorService API that applies to both virtual and platform threads.

First Test: Why the RuntimeException wasn't caught

Your initial code wraps a virtual thread-backed executor in a try-with-resources block, but here's the key point:

  • When you submit tasks via executorService.submit(), those tasks run asynchronously in the background. The try-with-resources block only takes care of shutting down the executor when the block exits—it doesn't wait for all tasks to finish, and it won't automatically grab exceptions thrown by those async tasks.
  • The catch block around the try-with-resources will only catch exceptions thrown by the executor itself (like if initializing it failed), not exceptions from the tasks you submitted.

To capture exceptions from your tasks, you need to save the Future objects returned by submit(), then call future.get() on each one. That's when any exception from the task gets wrapped in an ExecutionException and thrown to your main thread.

Second Test: Why the ExecutionException didn't behave as expected

Looking at your spawn method, the issue isn't that the ExecutionException isn't being caught—it actually is. The problem is in what you're doing inside the catch block:
When result.get() throws an ExecutionException (wrapping your IllegalStateException), your code calls callable.call() again. This re-runs the task, which throws the same IllegalStateException a second time—and this second exception isn't handled inside the spawn method. It bubbles up to the outer try-catch block that calls spawn, which is why you see it printed there.

If you remove the redundant callable.call() from your catch blocks and instead handle the wrapped exception properly, you'll see the ExecutionException works as you expected. For example:

catch (ExecutionException e) {
    Throwable actualError = e.getCause();
    return "Task failed: " + actualError.getMessage() + " - ExecutionException";
}

Talking to the Project Loom Team

You're already using the right primary channel: loom-dev@openjdk.java.net is the official mailing list for all Loom-related discussions, questions, and bug reports. Other good ways to engage include:

  • Submitting formal issues to the OpenJDK Jira (look for the "Loom" component)
  • Joining OpenJDK community review meetings or discussions (details are posted on the OpenJDK site)
  • Asking questions on Stack Overflow with the project-loom tag—both the Loom team and experienced Java devs often chime in there

As Steve Jobs said back in his NeXT days: "It should just work" — Loom aims to make virtual threads feel as intuitive as regular threads, but it's built on top of Java's existing concurrency APIs, so their rules (like how ExecutorService handles exceptions) still apply.

内容的提问来源于stack exchange,提问作者Eric Kolotyluk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 22:22:37