Repository navigation
Build
用 Klib Gradle 插件选择模块、生成 plugin.yml、重定位并打包出可部署的 JAR。
- Gradle 插件版本与 Klib 库版本相互独立。
- 插件内置的默认库版本可能落后于最新发布,建议始终用
libraryVersion.set(...)显式指定。版本记录见 CHANGELOG。
- 发布和部署业务插件时,
libraryVersion指向 Maven Central 已发布的版本。 - 新增库功能应先发布新版本,再升级插件依赖。
- CI 与部署构建不需要 Klib 源码目录,不通过
includeBuild或mavenLocal替换正式依赖。 - Klib 仓库自身验证发布制品的本地 Maven 任务属于库的发布检查,不能代替业务插件从正式仓库解析依赖的验证。
完整的 settings.gradle.kts、Spigot API 和插件入口配置见 快速开始。
- 插件解析仓库在
pluginManagement.repositories,普通依赖仓库在dependencyResolutionManagement.repositories,两者需要分别配置。 - 插件 DSL 生成
plugin.yml,不需要再手工维护另一份同名文件。
| 配置 | 用途 |
|---|---|
name(...) |
Bukkit 插件名,默认 Gradle 项目名 |
main(...) |
普通插件必填的主类全限定名 |
version(...) |
插件版本,默认 project.version |
targetPackage(...) |
内嵌 Klib 与依赖的重定位根包 |
apiVersion(...) / noApiVersion()
|
设置或省略 api-version |
depend(...) / softdepend(...)
|
Bukkit 依赖和可选依赖的加载顺序 |
libraryVersion(...) |
覆盖默认库版本;需要自行确认版本组合 |
klib {
libraryVersion.set("<klib-version>")
modules {
command()
data {
sqlite()
}
compatV1_12()
}
}| 类别 | 方法 |
|---|---|
| 基础 |
core()、config()、lang()、command()
|
| 功能 |
item()、data()、ui()、script()、hook()、remote()
|
| 数据后端 |
data { json(); jdbc(); pool(); sqlite(); mysql(); postgresql() },只选需要的 |
| 版本适配 |
compat()、compatV1_12()、compatV1_20()、compatV1_21()、compatV26()
|
| 无 |
none():不选择 Klib 模块 |
依赖闭包自动补齐:
-
command包含 lang、config、core;ui包含 item、command、core。 -
data()本身不包含生产存储后端;data { pool() }只加入可选池与 JDBC/Core 闭包,不选择数据库驱动。 -
compat()本身不包含版本实现。
源码按职责分组,消费方仍使用原有 modules {}、Gradle 项目名和 Maven 坐标:
| 源码目录 | 对应模块 |
|---|---|
libraries/ |
Core、Command、Config、Lang、Item、UI、Hook |
storage/ |
Data、共享 JDBC、可选池与 JSON/SQLite/MySQL/PostgreSQL 后端 |
platform/compat/、platform/versions/
|
公共兼容层与独立版本入口 |
runtime/ |
Script、Remote 与公开生命周期契约 |
目录组不是额外的 Gradle 项目或制品。例如 Core 的源码在 libraries/core/,任务仍是 :klib-core:test,制品仍是 me.kzheart.klib:klib-core。
完整职责和依赖方向见模块布局,项目到目录的唯一映射见 module-layout.properties。
插件以所选 Klib 模块和默认 Kotlin 标准库为显式内嵌根,打包这些根的运行时依赖闭包,以及显式放在 klibEmbedded 中的依赖。
dependencies {
// 由服务器提供,不打包。
compileOnly("org.spigotmc:spigot-api:1.12.2-R0.1-20180712.012057-156") {
isTransitive = false
}
// 用真实的第三方坐标替换下面的示意值。
// klibEmbedded("group:artifact:version")
}- 普通
implementation、runtimeOnly、compileOnly不会自动进入最终 JAR。 - 使用
modules {}后不需要重复声明 Klibimplementation。
| 依赖 | 处理方式 |
|---|---|
| 原生物品标签 | 随 item 提供,无需额外 NBT 依赖或插件 |
| Gson、SQLite JDBC | 按宿主依赖处理 |
| MySQL Connector/J | 随 mysql() 加入 |
| pgJDBC | 随 postgresql() 加入并自动重定位 |
| DBCP2、commons-pool2、commons-logging | 仅随 pool() 加入并一同重定位 |
现代 Bukkit/Paper 支持 plugin.yml 的 libraries 时,可声明:
klib {
externalLibrary("org.postgresql:postgresql:<pgjdbc-version>", "org.postgresql")
}构建插件把固定 Maven 坐标写进 libraries,从内嵌依赖中排除该制品,并停止该包的重定位。驱动由服务端加载,Klib 模块仍分别内嵌和隔离;首次启动前应准备依赖缓存。
同版本库文件可共用服务端缓存,不保证类在整个 JVM 只加载一次。该入口要求服务端具备 Bukkit/Paper 库加载器;Velocity 和独立 Java 程序须由自己的启动环境提供同版本驱动。
Kotlin/JVM 默认启用,src/main/kotlin 与 src/main/java 可混编,不需要另加编译插件、标准库或可选扩展模块。Java/Kotlin 默认都输出 Java 8 字节码。
Kotlin API 直接内置于 Core、Config、Command、UI、Item、Data 与 Script,无需额外 Kotlin 模块。Java 与 Kotlin 共用执行实现,保留必要的 Java SPI、注解、开放继承及二进制兼容边界;公共制品保持 Java 8 API 与字节码边界。
- Kotlin 标准库自动作为内嵌根,按运行时 JVM 变体解析,并与编译依赖版本对齐。
- Core 自带协程,Config 带入反射;这些运行时随显式根的依赖闭包打包,Java 业务插件也要包含。普通
runtimeClasspath不会全部内嵌。 - Kotlin metadata、module 索引、builtins 与运行时命名空间一起重定位,保留 multi-release 条目;不能用普通常量字符串替换代替结构化处理。
- kotlin-reflect 只适配构建插件声明的官方固定运行时版本,并校验字节形状;任意版本、第三方反射 payload 或跨插件类型交换不在保证范围内。
普通 Maven API 的 Kotlin 类型保留公开名称;部署 JAR 的私有运行时才重定位。不要把部署 JAR 当成供其他插件编译的公共 API。当前运行时约束详见 构建插件文档。
klib {
packaging { paper() }
api {
archive(apiJar.flatMap { it.archiveFile })
packages("com.example.api")
}
}apiJar 是业务自己声明的原始 API Jar 任务,按白名单只收录 API 类与对应 module 索引。
Jar producer 自动进入中间目录;验证后才生成正式 -api.jar,Maven publication 自动附加 api classifier。
候选包不能作为发布物重复附加,直接文件输入也必须在 build/libs 外。
Paper 模式的默认宿主包为 net.kyori、org.bukkit、io.papermc、com.google.gson、org.yaml.snakeyaml。
可用 packaging { hostPackages("org.example.host") } 追加,或通过属性替换完整名单。
选择模块时仅在 KLib 模块依赖边排除已知宿主制品;完整 runtime 闭包保留编译可见性,用户显式 klibEmbedded 输入仍须通过检查。
原始输入、重定位规则与最终包共同校验:宿主包、子包及覆盖它的父包都不能被重定位或内嵌;multi-release 各层均检查,嵌套 JAR/ZIP 拒绝。
API 包独立校验父类、接口、泛型、descriptor、throws、注解值、record 与完整方法体引用,包括 handle、indy、递归 condy。
仅允许声明的 API 包、JDK 与约定宿主(默认 Bukkit/Paper/Adventure),不允许 Kotlin 运行时、协程、KLib 或内部实现类型。
必要空值标记与 kotlin.Metadata 仅在注解描述符位置放行;字段、返回值、代码与注解 class/enum 值仍按普通类型检查。
Metadata 使用配套工具库的 JVM 映射和 stdlib 正式 typealias 声明,支持 Cloneable、Comparator、Appendable、RandomAccess;Pair、Result、函数类型、Intrinsics、DefaultConstructorMarker 与协程不享受例外。
API 的宿主名单与打包排除名单独立,可用 api { hostPackages("org.example.host") } 追加;Gson/SnakeYAML 不自动成为 API 类型。
纯 Kotlin 接口可通过,生成运行时调用的实现类留在插件内部。混合实现的 module 索引会被拒绝,必要时用独立 API source set。
反射字符串、动态生成类型和擦除为 Object 的实际值不在静态保证内;未知 metadata/不透明扩展会失败。
verifyKlibJar、verifyKlibApiJar、原 Guard 门禁接入 check、正式包和 Maven 发布;失败不晋升候选包。
Java/Kotlin 编译、资源处理与声明的 API producer 均先清理本插件拥有的当前正式主包/API 包,失败不遗留旧包;成功增量构建重新验证并恢复,不清理其他用户 JAR。
所有 Bukkit/Paper 成品必须只有一个根 plugin.yml,严格 UTF-8、无未展开占位且版本等于 project.version。
不声明 Paper 模式时保留通用重定位;Guard 不能与 Paper 模式混用。
消费者可独立配置 klib { jvmTarget(25) } 与 Java 25 toolchain,同时更新 Java release、Kotlin target 与 -Xjdk-release。
KLib 和构建插件自身仍保持 Java 8,嵌入库字节码不被提升。完整配置见构建插件文档。
- 不同插件使用不同
targetPackage。Klib 会重定位到<targetPackage>.libs.klib。 - 不要让多个插件共享未重定位的 Klib 类。
./gradlew clean shadowJar| 产物 | 路径 |
|---|---|
| 部署用 JAR | build/libs/<项目>-<版本>-all.jar |
| 打包依赖报告 | build/reports/klib/bundle-report.txt |
可以直接声明 Maven 制品:
dependencies {
implementation("me.kzheart.klib:klib-core:<klib-version>")
implementation("me.kzheart.klib:klib-config:<klib-version>")
}这种方式由自己的构建流程负责打包、重定位、Bukkit API 和 plugin.yml。仅声明依赖不代表最终 JAR 已包含运行时类。
Guard 商品使用 klib-guard-api,由门户提供 Core 与 API,不是普通 Bukkit 主类。
klib {
targetPackage("com.example.cloud")
modules {
core()
}
guardProduct {
entrypoint("com.example.cloud.CloudExample")
}
}声明目标服务器 API 后执行:
./gradlew clean guardProductJar- 产物为
build/libs/<项目>-<版本>-guard.jar,入口描述自动生成。 - 不要把 Guard API 或 Core 打入商品包。Guard API 保留公开 Java 契约,自身含 Kotlin 生命周期实现并依赖 Core,不能将它或其传递依赖闭包视为无 Kotlin 运行依赖。
- 不要把商品包直接放进 Bukkit 的 plugins 目录。
- Java 宿主签名与商品内部的标准库用法仍可使用。对父加载器 Klib 成员的调用、字段访问、方法句柄及真实覆写/接口实现中,若 JVM 描述符暴露待私有重定位的 Kotlin/协程类型,构建会静态拒绝。
- 擦除为
Object的传值、动态生成实现、反射及其他第三方 API 不在上述静态检测保证内。 - Guard 成品最多允许 4096 个归档条目,并禁止 multi-release 条目。完整 reflect/coroutines 等组合仍须满足这些限制,不能把普通 Bukkit JAR 构建成功推导为 Guard 商品兼容。
- Guard 商品必须遵守宿主的加载与打包合同;需要超出这些限制的组合时,先确认宿主合同支持并单独验证。