Halo modified the [class loading order](https://github.com/halo-dev/halo/pull/4663) of plugins in 2.10.x to P (Plugin) D (Dependencies) A (Application), resulting in a LinkageError when the current plugin is actually run. ```java java.lang.LinkageError: loader constraint violation: when resolving method 'reactor.core.publisher.Flux reactor.core.publisher.Mono.thenMany(org.reactivestreams.Publisher)' the class loader org.pf4j.PluginClassLoader @5da2e534 of the current class, run/halo/s3os/S3OsAttachmentHandler, and the class loader org.springframework.boot.loader.LaunchedURLClassLoader @87aac27 for the method's defining class, reactor/core/publisher/Mono, have different Class objects for the type org/reactivestreams/Publisher used in the signature (run.halo.s3os.S3OsAttachmentHandler is in unnamed module of loader org.pf4j.PluginClassLoader @5da2e534, parent loader org.springframework.boot.loader.LaunchedURLClassLoader @87aac27; reactor.core.publisher.Mono is in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @87aac27, parent loader 'app') at run.halo.s3os.S3OsAttachmentHandler.lambda$upload$28(S3OsAttachmentHandler.java:298) ~[na:na] at reactor.core.publisher.MonoUsing.subscribe(MonoUsing.java:85) ~[reactor-core-3.5.10.jar:3.5.10] at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.10.jar:3.5.10] at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:126) ~[reactor-core-3.5.10.jar:3.5.10] at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) ~[reactor-core-3.5.10.jar:3.5.10] at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) ~[reactor-core-3.5.10.jar:3.5.10] at java.base/java.util.concurrent.FutureTask.run(Unknown Source) ~[na:na] at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:na] at java.base/java.lang.Thread.run(Unknown Source) ~[na:na] ``` We just remove the reactive-streams dependency that is already in Halo to resolve the problem. Fixes https://github.com/halo-dev/halo/issues/4676 /kind bug ```release-note 修复在 Halo 2.10 中无法正常上传的问题 ```
plugin-s3
为 Halo 2.0 提供 S3 协议的对象存储策略,支持阿里云、腾讯云、七牛云等兼容 S3 协议的对象存储服务商
使用方法
- 下载,目前提供以下两个下载方式:
- GitHub Releases:访问 Releases 下载 Assets 中的 JAR 文件。
- Halo 应用市场:https://halo.run/store/apps/app-Qxhpp
- 安装,插件安装和更新方式可参考:https://docs.halo.run/user-guide/plugins
- 进入后台附件管理。
- 点击右上角的存储策略,在存储策略弹框的右上角可新建 S3 Object Storage 存储策略。
- 创建完成之后即可在上传的时候选择新创建的 S3 Object Storage 存储策略。
配置指南
Endpoint 访问风格
请根据下方表格中的兼容访问风格选择,若您的服务商不在表格中,请自行查看服务商的 s3 兼容性文档或自行尝试。
风格说明:
当Endpoint填写s3.example.com时
Path Style:SDK将访问s3.example.com/<bucket-name>/<object-key>
Virtual Hosted Style:SDK将访问<bucket-name>.s3.example.com/<object-key>
Endpoint
此处统一填写不带 bucket-name 的 Endpoint,SDK 会自动处理访问风格。
想了解 s3 协议的 Endpoint 的配置可在服务商的文档中搜索 s3、Endpoint 或访问域名等关键词,一般与服务商自己的 Endpoint 相同。
例如百度云提供
s3.bj.bcebos.com和<bucket-name>.s3.bj.bcebos.com两种 Endpoint,请填写s3.bj.bcebos.com。
Access Key & Access Secret
与服务商自己 API 的 Access Key 和 Access Secret 相同,详情查看对应服务商的文档。
Bucket 桶名称
一般与服务商控制台中的空间名称一致。
注意部分服务商 s3 空间名 ≠ 空间名称,若出现“Access Denied”报错可检查 Bucket 是否正确。
可通过 S3Browser 查看桶列表,七牛云也可在“开发者平台-对象存储-空间概览-s3域名”中查看 s3 空间名。
Region
一般留空即可。
若确认过其他配置正确又不能访问,请在服务商的文档中查看并填写英文的 Region,例如
cn-east-1。Cloudflare 需要填写均为小写字母的
auto。
部分对象存储服务商兼容性
开发环境
./gradlew build
修改 Halo 的配置文件
plugin:
runtime-mode: development # development, deployment
classes-directories:
- "build/classes"
- "build/resources"
lib-directories:
- "libs"
fixedPluginPath:
- "path/to/plugin-s3"
启动 Halo 之后即可在后台插件管理看到此插件。
生产构建
./gradlew build
构建完成之后,可以在 build/libs 目录得到插件的 JAR 包,在 Halo 后台的插件管理上传即可。