Z次元
文章笔记日志
Workshop
代码实验
Sections
专栏分类
文章归档
Community
友情链接
朋友圈
留言
头像
系列文章
0 Articles
5 分钟阅读
2.2k 字

JDK8升级JDK21报错解决方案记录

系列文章
异常处理
更新于:2026/1/21
|
发布于:2025/12/28
J
文章摘要
......

前言

前段时间,公司项目升级了JDK21,由于SpringBoot2的一些致命漏洞,其实领导很早就下达了任务,年底是最后的期限。至于升级过程中大部分都依靠AI Agent完成的,再加上我们项目组是最晚升级的那一批,所以升级过程还算比较顺利,但还是遇到了一些坑,这里记录下我在升级过程中踩到的坑。

CompletableFuture异步任务报错

报错

在使用CompletableFuture.runAsync() 方法异步调用其它微服务时,出现了报错:

org.springframework.http.client.ClientHttpRequest referenced from a method is not visible from class loader: 'app'

原因

核心原因:

当直接使用 CompletableFuture.runAsync(() -> { ... }) 而不指定线程池时,默认使用的是 JDK 的 ForkJoinPool.commonPool()。

问题在于:

ForkJoinPool 中的线程通常是由 System ClassLoader(系统类加载器)加载的,但在 JDK 9 引入模块化系统(JPMS)之后,一直到 JDK 21,JVM 对 ForkJoinPool 做了严格的限制。

当异步线程试图加载 ClientHttpRequest 等 Spring 类时,由于类加载器隔离(Visibility),ForkJoinPool 的线程看不到 LaunchedURLClassLoader 中的类(位于 BOOT-INF/lib 下),从而报出 not visible from class loader 错误。

解决方案

网上大多数解决方案基本有两种,1. 自定义 ForkJoinPool 工厂 2. 自定义线程池

其中自定义 ForkJoinPool 工厂有点麻烦,博主并不推荐,自定义线程池倒是一个比较稳的方案。不过除了这两种方案,经过博主实践,其实还有两种更简单的方案,那就是直接使用虚拟线程池或者使用@Async注解替换CompletableFuture

自定义线程池

@EnableAsync
public class AsyncConfig {

    @Bean("ahzooAsyncExecutor")
    public Executor ahzooAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("Async-Ahzoo-Service-");
        // 这一步非常关键,它会初始化线程并继承父线程的上下文
        executor.initialize();
        return executor;
    }
}
@Autowired
@Qualifier("ahzooAsyncExecutor")
private Executor executor;

public void callMicroservice() {
    CompletableFuture.runAsync(() -> {
       // xxxxxxx
    }, executor); // <--- 关键点:传入 executor
}

虚拟线程

直接在配置文件中全局开启虚拟线程:

spring:
  threads:
    virtual:
      enabled: true

自定义ForkJoinPool 工厂

关于自定义自定义 ForkJoinPool 工厂的方法,可以在stackoverflow的这篇文章找到相关回答:CompletableFuture / ForkJoinPool Set Class Loader

版权声明
本文依据 CC-BY-NC-SA 4.0 许可协议授权,请您在转载时注明文章来源为 Z次元 ,若本文涉及转载第三方内容,请您一同注明。
异

异常处理

好记性不如烂笔头

更多专栏文章推荐
关于站点受到了大量未知访问路径这件事
2024/9/17
String.valueOf()踩坑记录
2024/5/23
记一次Npm报错E404解决
2026/5/24
记一次Npm报错E402
2026/3/8
评论区

删除确认

评论删除后无法恢复,请确认是否继续?
◆
目录
1
前言
2
CompletableFuture异步任务报错
报错
原因
解决方案
自定义线程池
虚拟线程
自定义ForkJoinPool 工厂
目录
1
前言
2
CompletableFuture异步任务报错
报错
原因
解决方案
自定义线程池
虚拟线程
自定义ForkJoinPool 工厂
博客
文章 笔记 日志
工坊
代码
专题
专栏分类 文章归档
友链
友情链接 朋友圈
交流
留言 关于我
主页
菜单
置顶
主题
我的
十玖八柒
每天进步多一点
欢迎到访φ(゜▽゜*)♪
最新评论
生辰八字算命:
文章不错支持一下,非常喜欢,支持一下
免费算命:
文章不错支持一下,非常喜欢
免费算命:
文章不错支持一下,非常喜欢,支持
柒: @棋
后台管理不都长差不多,而且你后台又没公开,谁知道长什么样
我的
关于我
个人主页
站点地图
RSS订阅
导航
十年之约
虫洞穿梭
开源博客
前端开源仓库
后端开源仓库
©2020 - 2026 By 十玖八柒 版权所有
豫ICP备20021466号