Spring DefaultManagedTaskExecutor在Liberty拒任务时抛isShutdown不支持异常
在SpringBoot 3.2.5 + WebSphere Liberty(启用concurrent-3.0特性)环境中,按Spring文档配置DefaultManagedTaskExecutor绑定Liberty的ManagedExecutorService作为任务执行器时,当任务达到并发数+队列上限被拒绝,未抛出预期的TaskRejectedException,反而触发java.lang.UnsupportedOperationException: isShutdown。原因是Spring构造TaskRejectedException时调用了容器托管ExecutorService的isShutdown()方法,而根据Jakarta Concurrency规范,容器提供的ManagedExecutorService不支持这类生命周期方法,直接抛出异常。
1. 自定义拒绝处理器绕过isShutdown()调用
直接替换DefaultManagedTaskExecutor的默认拒绝处理器,在任务被拒绝时直接抛出TaskRejectedException,跳过Spring默认逻辑中对isShutdown()的调用:
@Bean public DefaultManagedTaskExecutor managedTaskExecutor() { DefaultManagedTaskExecutor executor = new DefaultManagedTaskExecutor(); executor.setRejectedExecutionHandler((r, exec) -> { throw new TaskRejectedException("任务因容量限制被拒绝", r); }); return executor; }
2. 扩展DefaultManagedTaskExecutor重写拒绝逻辑
继承DefaultManagedTaskExecutor,替换默认的拒绝处理逻辑,避免触发禁用的生命周期方法:
public class LibertyManagedTaskExecutor extends DefaultManagedTaskExecutor { @Override public void afterPropertiesSet() throws NamingException { super.afterPropertiesSet(); setRejectedExecutionHandler((r, exec) -> { throw new TaskRejectedException("Liberty托管执行器拒绝任务", r); }); } }
将自定义类作为Bean注入:
@Bean public LibertyManagedTaskExecutor libertyManagedTaskExecutor() { return new LibertyManagedTaskExecutor(); }
3. 校验Liberty并发服务配置细节
确保Liberty的server.xml中正确配置了ManagedExecutorService的参数,避免因配置异常导致的逻辑错误:
<concurrentManagedExecutorService id="DefaultManagedExecutorService" corePoolSize="10" maxPoolSize="20" queueCapacity="50" keepAliveTime="30s"/>
注意:若自定义了id,需在Spring的DefaultManagedTaskExecutor中通过setJndiName()指定对应的JNDI名称(默认是java:comp/DefaultManagedExecutorService)。
- 确认SpringBoot的
spring-boot-starter-websphere-liberty依赖版本与SpringBoot 3.2.5匹配 - 检查Spring配置是否显式指定了
ManagedExecutorService的JNDI名称,避免自动查找错误 - 验证Liberty的
server.xml中已启用concurrent-3.0特性:<featureManager><feature>concurrent-3.0</feature></featureManager>
内容的提问来源于stack exchange,提问作者David Černý

