惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
LINUX DO - 热门话题
S
Secure Thoughts
TaoSecurity Blog
TaoSecurity Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threat Research - Cisco Blogs
AI
AI
B
Blog RSS Feed
S
Schneier on Security
雷峰网
雷峰网
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
Cloudbric
Cloudbric
L
LINUX DO - 最新话题
罗磊的独立博客
有赞技术团队
有赞技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News
博客园 - Franky
Attack and Defense Labs
Attack and Defense Labs
The Cloudflare Blog
Webroot Blog
Webroot Blog
Last Week in AI
Last Week in AI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 叶小钗
美团技术团队
L
Lohrmann on Cybersecurity
T
The Blog of Author Tim Ferriss
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Vercel News
Vercel News
Know Your Adversary
Know Your Adversary
O
OpenAI News
博客园 - 【当耐特】
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cybersecurity and Infrastructure Security Agency CISA
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
PCI Perspectives
PCI Perspectives
H
Heimdal Security Blog
I
InfoQ
GbyAI
GbyAI
T
Threatpost
C
Cisco Blogs

微风静语

用 codebase-memory-mcp 给 AI 编程加一层“代码记忆” EchoCraft - 专为独立开发者和小型团队打造的产品官网主题 Halo 站长必备:外链安全与流量分析神器——“链接工具箱”重磅升级! Halo插件|一个面向创作者的多功能媒体处理工具集 分布式事务详解:从入门到精通 让你的网站初步适配PWA Halo主题 - 微浸:以轻量构建美学,用细节定义体验 深入理解Python爬虫技术:原理、实现与实践 Halo-2.20 新特性:自定义登录页面模版 vue3 中父子组件数据传输踩坑 将你的服务运维面板从宝塔替换为1panel Python实战项目:外星人入侵(源码分享) theme-hao主题适配友链自助提交插件 plugin-artalk 插件保姆级使用教程 plugin-blog-hao 插件部分功能演示 halo 插件开发踩坑记录(一) Thymeleaf 模版引擎语法浅记 信息洪流中的自我救赎 mac 系统里如何管理多个jdk版本 memso API 不完全指南 基础语法:从CPU角度看变量、数组、类型、运算、跳转、函数等语法 halo-theme-hao主题:artalk评论区美化 衡量个人成长 halo-theme-hao 主题魔改教程 分享一个魔改的 Artalk 评论系统邮件模版 halo-theme-hao 主题标签记录 开发一个 Halo2.0 的安全条跳转中台插件! Mac 软件推荐:使用 Mac 一年半来,我一直在用的软件! TypeScript教程---面向对象编程 软件版本命名规范 TypeScript教程---基础语法及编译设置 2024年家乡春季的第一场大雪 提问的智慧 基础篇:容器化部署技术 -—docker,从此摆脱多环境配置的苦恼! 普通本科的四年大学教育,给我带来了什么? 因果与平衡 程序的本质:代码是如何被执行的 软件开发者应该具备的基本提问素质 如何编写 Restful 风格的接口 探索力 Springboot入门基础篇 springboot中如何使用注解来实现aop Springboot项目生成接口文档方法 Java 实体代码生成器 lombok 的使用 深入 Java 泛型 分布式版本控制工具 git 的基本使用 如何搭建前后端分离的项目 初识Vue3--令人焕然一新的使用逻辑和代码组织方式! 浅谈前端发展史 为什么要学习数据结构和算法 关于富文本编辑器 wangeditor 在 vue2 项目中的使用
Halo插件开发:java17旧项目迁移至java21项目记录
webjing · 2025-07-01 · via 微风静语

最近 Halo 2.21.0的更新将 java版本从 17 升级到 21 ,同时针对前端部分增加了代码分割方案,使得控制台的代码提及变得更小,用户体验更良好。于是几经折腾下,对于我一些还没有发布的插件进行了逐步改造,将项目的 jdk 从17升级到 21。

先说一下我之前失败的迁移经历吧,我直接是通过修改 halo 插件项目根目录下的 build.gradle 的配置以及增加 ui 部分的 build.gradle 并同时修改 ui 部分的打包配置文件 vite.config.tsrsbuild.config.ts 。不知道为什么,总是在执行 pnpmSetup 命令的时候报错,试了各种办法都不行,索性直接使用新的 cli 来构建项目,然后把旧项目的文件迁移过去。

1、使用 cli 工具创建新的项目结构

pnpm create halo-plugin@latest

接着控制台会出现如下提示,输入插件名称的时候不要加 plugin- , 此 cli 工具会自动为插件名称加入此前缀。

🚀 Welcome to Halo Plugin Creator!

✔ Plugin name: › hello-world
✔ Domain (for group and package name): › com.example
✔ Author name: › Halo
✔ Choose UI build tool: › Rsbuild

📋 Project Configuration:
   Name: hello-world
   Domain: com.example
   Package: com.example.hello-world
   Author: Halo
   UI Tool: rsbuild
   Output Directory: /path/to/hello-world

✔ Create project? › yes

2、配置项目

halo 插件项目要求的开发环境如下:


- Java 21+
- Node.js 18+
- pnpm

按照下图所示设置 jdk版本

jdk21-seting.png

接着设置 一下 nodejs 的环境

pnpm-version.png

接着将自己之前的后端代码和前端代码粘贴至新的项目目录下,不过这块要注意下后端代码一些过时的API,这些API在 2.21.0版本下已经被移除,所有的破坏性更新如下:

破坏性更新

  • 移除过时类 run.halo.app.extension.router.selector.FieldCriteriaPredicateConverter 和
    run.halo.app.extension.router.selector.LabelCriteriaPredicateConverter,推荐用
    run.halo.app.extension.router.selector.SelectorConverter 替代。

  • 移除过时类 run.halo.app.search.SearchParam,推荐用 run.halo.app.search.SearchOption 替代。

  • 移除过时类 run.halo.app.search.post.PostDoc 和 run.halo.app.search.post.PostHit,推荐用
    run.halo.app.search.HaloDocument 替代。

  • 移除 Plugin 过时字段 spec.pluginClass,推荐在插件定义文件中移除此字段。

  • 移除 Plugin 过时字段 spec.website,推荐使用 spec.homepage 替代。

  • 移除 Plugin 过时字段 spec.require,推荐使用 spec.requires 替代。

  • 移除 SystemSetting.AuthProvider 过时字段 enabled,已经由 SystemSetting.AuthProvider 的 states 字段替代。

  • 移除 run.halo.app.extension.ExtensionMatcher 过时方法 getGvkgetLabelSelector和 getFieldSelector

  • 移动方法 run.halo.app.extension.MetadataOperator#metadataDeepEquals 至
    run.halo.app.extension.MetadataOperator#equals

  • 移除 run.halo.app.extension.router.QueryParamBuildUtil 过时方法 buildParametersFromType,推荐使用
    org.springdoc.core.fn.builders.operation.Builder#parameter 替代。

  • 移除 run.halo.app.extension.router.SortableRequest 过时方法 toPredicate,推荐使用
    run.halo.app.extension.router.SortableRequest#toListOptions 替代。

  • 移除 run.halo.app.extension.router.selector.SelectorUtil 过时方法 labelSelectorsToPredicate
    fieldSelectorToPredicate 和 labelAndFieldSelectorToPredicate,推荐使用
    run.halo.app.extension.router.selector.SelectorUtil#labelAndFieldSelectorToListOptions 替代。

  • 移除 run.halo.app.theme.finders.TagFinder 过时方法 list(Integer, Integer, Predicate, Predicate),推荐使用
    run.halo.app.theme.finders.TagFinder#list(Integer, Integer) 替代。

  • 移除 run.halo.app.plugin.BasePlugin 过时构造函数 BasePlugin(PluginWrapper),推荐使用 BasePlugin(PluginContext)
    替代。

  • 移除接口 GET&PUT /apis/api.console.halo.run/v1alpha1/plugins/{name}/config,推荐使用
    GET&PUT /apis/api.console.halo.run/v1alpha1/plugins/{name}/json-config 替代。

  • 移除接口 GET&PUT /apis/api.console.halo.run/v1alpha1/themes/{name}/config,推荐使用
    GET&PUT /apis/api.console.halo.run/v1alpha1/themes/{name}/json-config 替代。

  • 移除接口 POST /apis/api.halo.run/v1alpha1/indices/post,推荐使用 POST /apis/api.halo.run/v1alpha1/indices/-/search
    替代。

  • 移除接口 POST /apis/api.console.halo.run/v1alpha1/indices/post,推荐使用
    POST /apis/api.console.halo.run/v1alpha1/indices/-/rebuild 替代。

最后,请确保更新 plugin.yaml 中的 requires 字段为 >=2.21.0-alpha.1

3、运行项目

3.1、运行方案一

如果顺利的话,直接可以在halo提供的开发工具里边点击 haloServer 就可以运行,但是个人尝试后发现,时好时坏,因此建议命令行执行。

halo-server.png

3.2、运行方案二

# 运行前先执行此命令,停止所有 gradle 进程
./gradlew --stop
# 接着运行如下命令
./gradlew --haloServer

如果后边在使用 generateApiCLientreloadPlugin 工具时也出现报错,建议使用命令行执行。

3.3、运行方案三

如果上边两种方式都无法成功运行项目,可以使用终端去打开 Intelij idea后再去运行项目。

  • macos 系统下使用终端打开 idea

cd /Applications
./IntelliJ\ IDEA.app/Contents/MacOS/idea

其他操作系统请参考 Jetbrais 的官方文档查阅

4、常见错误解决方案

1、测试包报错

最新的 halo 插件项目中官方加入了测试包,默认会有如下这样一个测试方法,用于启动关闭插件。

@ExtendWith(MockitoExtension.class)
class TimelinesPluginTest {

    @Mock
    PluginContext context;

    @InjectMocks
    TimelinesPlugin plugin;

    @Test
    void contextLoads() {
        plugin.start();
        plugin.stop();
    }

}

上边的测试方法在空项目可以运行起来,但是我将旧项目迁移过来之后,就会报错,具体信息如下所示。

halo-project-test-err.webp

解决方法:删除上边的 contentLoads 测试方法即可


此教程只是针对我个人的情况以及成功案例进行一个记录,并不具有普适性,如果按照我的方案运行还有问题,欢迎评论区随时交流👏。