| name | chains-plugin-authoring |
|---|---|
| description | Author, package, review, and test Java Chains V2 plugins. Use when creating a plugin, Payload, Gadget, ChainSpec, Param, metadata YAML, preset, chains-plugin.json, LibrarySet, plugin jar, or when debugging tag matching, ClassLoader isolation, reload, and V1-to-V2 migration. Also use for Chinese requests mentioning Java Chains 插件、写插件、链标签、预设链、第三方依赖或插件打包。 |
使用公开 API 和本仓公开示例编写插件。先读取 deps/api/VERSION 并确认安装目标的 plugin-api 版本,再从 plugins/starter-demo 的最小链开始;不要假设宿主第三方依赖对插件可见。
| 要做什么 | 先读 |
|---|---|
| 理解链执行、Tag 匹配与插件加载 | mental-model.md |
| 选择注解、参数或常用 Tag | annotations-and-tags.md |
| 复制正确示例或识别反例 | examples-good-bad.md |
| 新增独立插件模块或维护多插件仓 | multi-module-repository.md |
| 配 Maven、manifest、LibrarySet、ClassLoader | packaging-and-classloading.md |
| 写 nodes YAML、i18n 或 preset | metadata-and-presets.md |
| 测试、安装、Reload、排错、迁移 V1 | testing-and-troubleshooting.md |
| 使用 Git tag 构建并发布所有插件 | multi-module-repository.md |
只读取当前任务需要的 reference;需要跨主题时按表中顺序读取。
- 先读正反例和打包文档,以
plugins/starter-demo为公开骨架,交付最小目录、POM、manifest、一个 Payload/Gadget 和契约测试。 - 第一版不引入非必要依赖、shade、默认出网或命令执行 preset。
- 先写下游真实类型,再从
Bytecode/BytecodeConvertTag/TemplatesImplChain中选语义正确的 Tag。 - 用
Sleep.second做无出网冒烟,不得为了通过 next/validate 添加与返回类型无关的 Tag。
- 同时检查 Maven 编译依赖、jar 内
libraries/<setId>/、manifestlibraries[]与节点libraries={...}。 - 增加真实 ClassLoader 测试;类加载改用
PluginClasses,不用宿主偶然可见的 victim 类。
- 先手工证明整条链的 Tag 和参数可用,再把稳定链形写入
metadata/presets/*.yaml。 - 节点 id 使用注解真实 id,
args使用 Java 字段名;source由宿主归属,不手写猜测值。
- 用“当前节点的 outgoing 条件”对“右邻节点的 provides/id/类名/alias”逐段列表。
- 分别检查 Payload
gadgetTags、普通节点accepts/expression和叶子END,不把 Catalog 标签当链 Tag。
- 先列出旧包名、旧注解、
thirdLib/third-libs、类加载和打包差异,然后逐项替换。 - 不保留新插件不需要的兼容门面;迁移后重写 manifest、YAML、测试和安装验收。
- 先报告会造成无法加载、无法接链或类污染的问题,再报元数据和可维护性问题。
- 每个结论指向具体注解、字段、资源路径或 jar 条目,并给出最小修复。
- 给出可直接执行的文件、命令、断言或修复,同时说清与
deps/api/VERSION和安装目标版本有关的假设。 - 不确定的 API、Tag 或字段名必须回到公开宿主源码核对,不用记忆补齐。
- 确认版本。 读取
deps/api/VERSION和安装目标公开java-chains-plugin-api;POM 与 manifestapiVersion必须一致。 - 选择 pluginId。 使用稳定小写短名;manifest id 与 preset 前缀一致。Java 包段移除
-等非法字符,并在文档中写明映射。 - 选择骨架。 无第三方 jar 从
plugins/starter-demo开始;需要 victim jar 再参考plugins/finereport增加 LibrarySet。 - 先画类型流。 写出每个节点的返回类型和右邻节点产物,再选择 Tag。
- 写注解。 Gadget 用
@GadgetMeta + @ChainSpec;Payload 用@PayloadAnnotation;输入字段加@Param。 - 写执行逻辑。 中间 Gadget 先
chain.doCreate(context)再包装;Payload 优先只 overridemarshal。 - 补资源。 写 manifest、
metadata/nodes/<Id>.yaml;常用链增加metadata/presets/*.yaml。 - 补测试。 校验 id、Tag、LibrarySet、YAML、preset、字段名和 jar 布局。
- 构建。 先运行
./scripts/install-api-deps.sh,再运行mvn clean verify和./build.sh;拒绝 host API/common/core/server/nodes、旧目录和旧包名。 - 安全冒烟。 在临时宿主 Reload,确认 Catalog 与 preset,再用 Sleep 链 generate。
推送任意 tag 会触发 .github/workflows/tag-build.yml。workflow 使用 JDK 8
运行完整 ./build.sh,分别收集每个 PluginUnit jar,生成 SHA256SUMS 和
BUILD-INFO.txt,上传名为 java-chains-plugins-<tag> 的 Actions artifact,
并创建同名 GitHub Release 的长期下载附件;beta/rc tag 标记为 prerelease。
./build.sh
git tag 2.0.0-beta7.1
git push origin main
git push origin 2.0.0-beta7.1发布 tag 使用 <deps/api/VERSION>.<plugin-release>:末段插件发布序号从 1
开始并逐次递增,例如 2.0.0-beta7.1、2.0.0-beta7.2。tag 只标识构建
批次,不会改写插件版本。打 tag 前必须先同步根/子模块 POM、所有
META-INF/chains-plugin.json 的插件 version、preset/文档中的版本,并确认宿主
apiVersion 仍与 deps/api/VERSION 一致。workflow 会拒绝不符合规则的 tag,
也会拒绝 manifest version 与 tag 不一致的产物。任一模块构建或 PluginUnit 边界校验失败时,
workflow 不会上传 artifact 或 Release 附件。已有 tag 尚无 Release 时,可通过
workflow_dispatch 输入 tag 补发;必须检出该 tag 构建,不得拿 main 的产物冒充
旧 tag 发布,也不得自动覆盖已经发布的同名 Release 附件。
- Fork 完整仓库,不要只复制
plugins/;保留根 POM、deps/api/、build.sh、 本 skill 以及.github/workflows/tag-build.yml。 - 要求 AI 先完整读取
AGENTS.md和本SKILL.md,再从plugins/starter-demo创建或修改独立 PluginUnit。 - AI 完成后运行
mvn clean verify与./build.sh,扫描公开性并同步插件版本。 - 将 main 推送到 Fork,创建符合
<apiVersion>.<plugin-release>的 tag,再推送 tag;GitHub Actions 会自动构建,并将 jar、校验和与构建信息发布到同名 Release。 - 对外分发只使用 GitHub Release 附件;Actions artifact 仅用于构建排查。
- 使用 JDK 8;包名使用
org.vulhub.javachains.plugins.<pluginId>[.*]。 java-chains-plugin-api与可选java-chains-common使用provided;禁止 shade host API、core、server、nodes、all。- 节点真相是注解;YAML 只补 Catalog、i18n 和参数文案。
- Gadget id 使用简单类名且全局唯一。
- 用户链左→右,
doCreate执行右→左。 - Payload 用
gadgetTags匹配第一跳;普通节点用accepts匹配右邻节点provides。 - 叶子必须包含
END;Canonical next/validate 对空 outgoing tags 严格拒绝。 - Tag 必须与真实返回类型一致;不要为了过校验添加宽泛 Tag。
- manifest id 表示来源;宿主自动注入
plugin:<id>。禁止把它写进链 Tag 或手写进catalogTags。 catalogTags只写产品/场景;@Dependency只做展示,不加载 jar。- victim jar 必须完成
libraries/<setId>/、manifestlibraries[]和注解libraries={...}三处绑定。 - victim 类使用
PluginClasses.forName,代理使用PluginClasses.contextLoader()。 @Param标 public 实例字段;CLI、YAML、preset 使用 Java 字段名。- 运行 clean 构建;单元测试通过不代表插件 ClassLoader 下 generate 通过。
- 只使用本仓内容和公开宿主 API;不得加入未公开仓库、代码、路径或实现细节。
- 多插件仓坚持“一模块、一 jar、一个 manifest id”;根聚合 POM 不放插件类、metadata 或 LibrarySet。
- 公开编译依赖只从
deps/api/获取并校验 SHA-256;禁止从非公开仓库复制代码、jar、路径或说明。 - 构建 tag 前显式更新插件版本;不得假设 tag 会自动修改 POM、manifest 或 jar 文件名。
- 发布 tag 必须是
<apiVersion>.<从1递增的插件发布序号>,且所有插件 manifest version 与 tag 一致。
用户选择: Payload → G1 → G2 → Leaf
执行返回: Payload ← G1 ← G2 ← Leaf
Payload.gadgetTags ∩ G1.provides
G1.accepts ∩ G2.provides
G2.accepts ∩ Leaf.provides
匹配也接受右邻节点 id、简单类名和 alias;当前节点 expression 非空时表达式优先。最终节点仍必须含 END。
| 右侧返回 | 当前节点常用 accepts |
典型右侧 |
|---|---|---|
类文件 byte[] |
BytecodeConvertTag |
BytecodeConvert → Sleep |
TemplatesImpl |
TemplatesImplChain |
TemplatesImpl → BytecodeConvert → Sleep |
JDBC URL String |
JdbcUrlChains / JdbcUrlWithSQLChains |
JDBC URL 节点 |
JNDI Reference |
Reference |
Reference 构造节点 |
表达式 String |
Expression 或具体 *_Expr |
表达式叶子 |
如果 Java 类型与 Tag 语义不一致,先修设计。
最小冒烟:
DemoPayload → DemoLeaf(END)
直接吃处理后字节码:
JavaNativePayload → ProductGadget → BytecodeConvert → Sleep
先构造 TemplatesImpl:
JavaNativePayload → ProductGadget → TemplatesImpl → BytecodeConvert → Sleep
Sleep 的真实参数字段是 second:CLI 使用 --arg Sleep.second=2,preset 使用 args: {second: 2}。
- API 版本来自安装目标,不猜版本。
-
deps/api/VERSION、两个公开 jar、POM 与 manifestapiVersion对齐。 - manifest id/version/apiVersion/libraries 正确。
- Gadget/Payload id 等于简单类名且无冲突。
- 每段 Tag 与 Java 类型一致;叶子含 END。
- 没有手写
plugin:<id>。 - Param、YAML、preset 使用同一个字段名。
- LibrarySet 四段闭环完整。
- 契约、ClassLoader、
mvn clean verify与./build.sh通过。 - jar 不含 host API/core/server/nodes、
third-libs/或旧包名。 - 临时宿主 Reload、Catalog、preset、安全 generate 通过。
- 公开工作树没有本机绝对路径或仓库外实现引用。
- 发布 tag 为
<apiVersion>.<plugin-release>,序号从 1 递增,且所有 manifest version 与 tag 一致。 - tag workflow 将独立 jar、SHA256SUMS 和 BUILD-INFO 上传,并以 GitHub Release 作为对外下载入口。