正常是这样调用, 这个在正常调试时是没问题的.
1
2
3
|
CompletableFuture.runAsync(()->{
xxx...
});
|
但是当进行打包后, 放到服务器上运行时, 就会出现 ClassNotFoundException.
镜像使用的是 ghcr.io/graalvm/graalvm-ce, 该镜像内部为Tomcat服务.
当在runnable 中调用mybatis的相关方法时, 就会报 ClassNotFoundException, 导致完全无法进行数据库操作.
经过搜索, 发现是默认的 CompletableFuture.runAsync 方法内部使用了 ForkJoinPool.commonPool() 方法, 这个线程池在Tomcat中就会出问题.
解决方案: 手动指定一个自己的线程池.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@EnableAsync
@Configuration
public class MyTaskExecutor {
@Bean("threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(120);
// 设置队列容量
executor.setQueueCapacity(120);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(600);
executor.setThreadNamePrefix("BM-Pool#Task");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
|
注入后作为runAsync的第二个参数即可.