适用读者:要给团队做 IDE 工具、或要把自己的开源中间件发到
central让人dependency引的人。
前置:S01-J08(制品发布)、J03(Maven 依赖与仓库)。
覆盖旧文:A-3197(第 1 节:IDEA 插件怎么开发)、A-3195(发布 Jar 包到 Maven 中央仓库)→ 2 篇 / 约 7.2 千字符。
扩展点:E-S01-038(插件工程的三件套:plugin.xml/ Action / ToolWindow)、E-S01-039(中央仓库发布 6 步链:GPG→工单→DNS→deploy→release→同步)、E-S01-040(发布失败的五个常见点)。
上一篇:S01-J09 · 环境搭建四条路:Windows 本机、macOS、云服务器、在线 IDE
下一篇:S01-X02 · SSH 与数据库客户端工具清单。
1. 一句话结论
插件开发是"挂载点"问题,不是"写功能"问题:功能用普通 Java 写,难点是挂在哪(菜单/ToolWindow/编辑器)和怎么拿到工程模型。发布同理:打得好包不算完成,签名、工单、DNS、Release 四道关都过了才算进了中央仓库。
出处:
A-3197(小傅哥,IDEA 插件 + 字节码插桩案例)、A-3195(DCSchedule 中间件发布)。
2. 插件工程的三件套(E-S01-038)
| 件 | 作用 | 位置 |
|---|---|---|
plugin.xml |
声明插件元信息与扩展点 | src/main/resources/META-INF/ |
Action |
一个可执行命令(菜单项/快捷键) | 继承 AnAction |
ToolWindow |
侧边/底部常驻面板 | ToolWindowFactory |
<!-- plugin.xml 最小骨架(IntelliJ Platform,版本敏感,按 SDK 文档核对) -->
<idea-plugin>
<id>com.example.myplugin</id>
<name>My Plugin</name>
<vendor>example</vendor>
<depends>com.intellij.modules.platform</depends>
<extensions defaultExtensionNs="com.intellij">
<toolWindow id="MyPanel" anchor="right" factoryClass="com.example.MyToolWindowFactory"/>
</extensions>
<actions>
<action id="MyAction" class="com.example.MyAction" text="Run Me"/>
</actions>
</idea-plugin>
// 一个最小 Action:拿到当前工程 → 做点事
public class MyAction extends AnAction {
@Override public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
if (project == null || files == null) return;
// 业务逻辑:扫描、插桩、导出……
}
}
判据:先定挂载点,再写功能。 挂载点决定线程模型(EDT 还是后台)与可见范围,写反了会得到"界面卡死"或"按钮点了没反应"。
2.1 开发方式二选一
| 方式 | 命令 | 适合 |
|---|---|---|
| IntelliJ Platform Plugin 模板 | IDE 新建工程 | 快速试 |
| Gradle 构建 | gradle init + intellij { version } |
要 CI、要发版 |
3. 发布到 Maven 中央仓库:六步链(E-S01-039)
原文的链路可以压缩成一条单向前提链——任何一环没过,后面都做不了:
① GPG 密钥(签名)
↓
② Sonatype JIRA 工单(申请 groupId 资格)
↓
③ DNS TXT 验证(证明你拥有该域名,如 bugstack.cn)
↓
④ mvn deploy 到 oss.sonatype.org(暂存 staging)
↓
⑤ 在 Nexus 控制台 Close → Release
↓
⑥ 同步到 search.maven.org / mvnrepository / 阿里云镜像
| 步 | 关键动作 | 常见坑 |
|---|---|---|
| ① | gpg --gen-key,公钥上传 hkp://keyserver.ubuntu.com:80 |
私钥丢了 → 无法重复发布 |
| ② | 建 issue,groupId 填域名反写 | 用 com.github.xxx 也要证明 |
| ③ | 加 TXT 记录,值为工单号 | 只加 A 记录不算 |
| ④ | distributionManagement 指向 staging |
少 sources/javadoc 包 |
| ⑤ | Close 时跑规则校验 | 缺签名/缺 POM 字段 → 失败 |
| ⑥ | 等 几小时 | 急着搜不到 |
<!-- pom.xml 关键片段(示意,坐标按自己的改) -->
<distributionManagement>
<snapshotRepository>
<id>ossrh</id><url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id><url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
# 发布(示意)
mvn clean deploy -P release -Dgpg.passphrase=***
判据:"能 deploy" 不等于 "能 release"。 staging 仓库里的东西对使用者不可见,必须 Close→Release。
版本与平台现状待核:Sonatype 的 OSSRH 已迁移到 Central Portal(
central.sonatype.com),新项目走的流程与上文工单制不同。原文写于 2019 年,具体入口按当前官方文档核对。
4. 发布失败的五个常见点(E-S01-040)
| # | 现象 | 原因 | 处理 |
|---|---|---|---|
| 1 | Invalid signature |
GPG 私钥/口令不对 | 重签,确认 gpg.passphrase |
| 2 | Missing: javadoc |
没生成 -javadoc.jar |
加 maven-javadoc-plugin |
| 3 | Missing: sources |
没生成 -sources.jar |
加 maven-source-plugin |
| 4 | groupId not allowed |
域名未验证 | 补 DNS TXT |
| 5 | Close 卡在规则校验 | POM 缺 name/description/url/licenses/developers/scm |
补齐必填项 |
判据:中央仓库的校验是"元数据完整性"检查。 代码能跑没用,POM 少一个 licenses 就过不去。
5. 常见误区
| 误区 | 纠正 |
|---|---|
| "插件功能写完就完了" | 挂载点、线程、可见性才是主体 |
| "用 UI 设计器画界面" | IntelliJ 插件 UI 是 Swing/AWT,没有可视化拖拽的正路 |
| "deploy 成功就发布了" | 还要 Close→Release→等同步 |
| "groupId 随便填" | 必须证明域名归属 |
| "私钥丢了再生成一个" | 已发布版本无法用新钥重发,只能换版本号 |
6. 自测
- 插件三件套分别是什么?
plugin.xml里声明什么? - 中央仓库发布链的六步,哪一步是"对使用者仍不可见"的?
Missing: sources说明缺哪个插件?- 换机器后 GPG 私钥丢失,同版本还能重发吗?
答案
plugin.xml(元信息+扩展点)、Action、ToolWindow。- ④ deploy 之后、⑤ Release 之前——staging 里的包对使用者不可见。
maven-source-plugin。- 不能,同版本不可覆盖,只能发新版本号。
7. 下一篇
S01-X02 · SSH 与数据库客户端工具清单 —— 终端类(WindTerm/Electerm/Termius)与数据库类(DBeaver/Sequel Ace/DataGrip)的取舍,以及"公司环境不能用破解版"的合规选择。
本篇属于系列《S01 · 开发环境与工具链》。旧文来源:A-3197/3195;扩展点 E-S01-038/039/040。原文为 2023–2024 版本快照,具体版本号属待核。