Skip to content

Latest commit

 

History

History
194 lines (148 loc) · 11.1 KB

File metadata and controls

194 lines (148 loc) · 11.1 KB
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 插件、写插件、链标签、预设链、第三方依赖或插件打包。

Java Chains V2 插件编写

使用公开 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。

增加 LibrarySet

  • 同时检查 Maven 编译依赖、jar 内 libraries/<setId>/、manifest libraries[] 与节点 libraries={...}
  • 增加真实 ClassLoader 测试;类加载改用 PluginClasses,不用宿主偶然可见的 victim 类。

编写 preset

  • 先手工证明整条链的 Tag 和参数可用,再把稳定链形写入 metadata/presets/*.yaml
  • 节点 id 使用注解真实 id,args 使用 Java 字段名;source 由宿主归属,不手写猜测值。

排查 Tag 校验

  • 用“当前节点的 outgoing 条件”对“右邻节点的 provides/id/类名/alias”逐段列表。
  • 分别检查 Payload gadgetTags、普通节点 accepts/expression 和叶子 END,不把 Catalog 标签当链 Tag。

V1 → V2 迁移

  • 先列出旧包名、旧注解、thirdLib/third-libs、类加载和打包差异,然后逐项替换。
  • 不保留新插件不需要的兼容门面;迁移后重写 manifest、YAML、测试和安装验收。

审查已有插件

  • 先报告会造成无法加载、无法接链或类污染的问题,再报元数据和可维护性问题。
  • 每个结论指向具体注解、字段、资源路径或 jar 条目,并给出最小修复。

交付要求

  • 给出可直接执行的文件、命令、断言或修复,同时说清与 deps/api/VERSION 和安装目标版本有关的假设。
  • 不确定的 API、Tag 或字段名必须回到公开宿主源码核对,不用记忆补齐。

10 分钟工作流

  1. 确认版本。 读取 deps/api/VERSION 和安装目标公开 java-chains-plugin-api;POM 与 manifest apiVersion 必须一致。
  2. 选择 pluginId。 使用稳定小写短名;manifest id 与 preset 前缀一致。Java 包段移除 - 等非法字符,并在文档中写明映射。
  3. 选择骨架。 无第三方 jar 从 plugins/starter-demo 开始;需要 victim jar 再参考 plugins/finereport 增加 LibrarySet。
  4. 先画类型流。 写出每个节点的返回类型和右邻节点产物,再选择 Tag。
  5. 写注解。 Gadget 用 @GadgetMeta + @ChainSpec;Payload 用 @PayloadAnnotation;输入字段加 @Param
  6. 写执行逻辑。 中间 Gadget 先 chain.doCreate(context) 再包装;Payload 优先只 override marshal
  7. 补资源。 写 manifest、metadata/nodes/<Id>.yaml;常用链增加 metadata/presets/*.yaml
  8. 补测试。 校验 id、Tag、LibrarySet、YAML、preset、字段名和 jar 布局。
  9. 构建。 先运行 ./scripts/install-api-deps.sh,再运行 mvn clean verify./build.sh;拒绝 host API/common/core/server/nodes、旧目录和旧包名。
  10. 安全冒烟。 在临时宿主 Reload,确认 Catalog 与 preset,再用 Sleep 链 generate。

Git tag 自动构建与发布

推送任意 tag 会触发 .github/workflows/tag-build.yml。workflow 使用 JDK 8 运行完整 ./build.sh,分别收集每个 PluginUnit jar,生成 SHA256SUMSBUILD-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.12.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 + AI 推荐流程

  1. Fork 完整仓库,不要只复制 plugins/;保留根 POM、deps/api/build.sh、 本 skill 以及 .github/workflows/tag-build.yml
  2. 要求 AI 先完整读取 AGENTS.md 和本 SKILL.md,再从 plugins/starter-demo 创建或修改独立 PluginUnit。
  3. AI 完成后运行 mvn clean verify./build.sh,扫描公开性并同步插件版本。
  4. 将 main 推送到 Fork,创建符合 <apiVersion>.<plugin-release> 的 tag,再推送 tag;GitHub Actions 会自动构建,并将 jar、校验和与构建信息发布到同名 Release。
  5. 对外分发只使用 GitHub Release 附件;Actions artifact 仅用于构建排查。

硬规则

  1. 使用 JDK 8;包名使用 org.vulhub.javachains.plugins.<pluginId>[.*]
  2. java-chains-plugin-api 与可选 java-chains-common 使用 provided;禁止 shade host API、core、server、nodes、all。
  3. 节点真相是注解;YAML 只补 Catalog、i18n 和参数文案。
  4. Gadget id 使用简单类名且全局唯一。
  5. 用户链左→右,doCreate 执行右→左。
  6. Payload 用 gadgetTags 匹配第一跳;普通节点用 accepts 匹配右邻节点 provides
  7. 叶子必须包含 END;Canonical next/validate 对空 outgoing tags 严格拒绝。
  8. Tag 必须与真实返回类型一致;不要为了过校验添加宽泛 Tag。
  9. manifest id 表示来源;宿主自动注入 plugin:<id>。禁止把它写进链 Tag 或手写进 catalogTags
  10. catalogTags 只写产品/场景;@Dependency 只做展示,不加载 jar。
  11. victim jar 必须完成 libraries/<setId>/、manifest libraries[] 和注解 libraries={...} 三处绑定。
  12. victim 类使用 PluginClasses.forName,代理使用 PluginClasses.contextLoader()
  13. @Param 标 public 实例字段;CLI、YAML、preset 使用 Java 字段名。
  14. 运行 clean 构建;单元测试通过不代表插件 ClassLoader 下 generate 通过。
  15. 只使用本仓内容和公开宿主 API;不得加入未公开仓库、代码、路径或实现细节。
  16. 多插件仓坚持“一模块、一 jar、一个 manifest id”;根聚合 POM 不放插件类、metadata 或 LibrarySet。
  17. 公开编译依赖只从 deps/api/ 获取并校验 SHA-256;禁止从非公开仓库复制代码、jar、路径或说明。
  18. 构建 tag 前显式更新插件版本;不得假设 tag 会自动修改 POM、manifest 或 jar 文件名。
  19. 发布 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 与 manifest apiVersion 对齐。
  • 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 作为对外下载入口。