之前提到我写了一个读取ply格式的工具放到了Github上,想要引用这个库可以用 mvn package 把 jar 打包出来,但是我习惯了在 pom.xml 中引入依赖项,我就想能否直接把那个库提交到Maven仓库上,断断续续弄了几天最后真的放上去了。其实整个过程还算简单,主要就参考了一篇中文博客,这里大概把遇到的问题记一下。
申请创建 Project
第一步是去 Sonatype 上注册一个账号。完成注册进入 Dashboard 后点击最上方的 Create :
页面会弹出一个模态框,把该填的填上,所有描述性的输入我都用英文,至于 Usernames 那一栏,虽然我估计不用填,但还是把自己在 Sonatype 上的用户名给填进去了。
然后就等待审核,我大概等了 5 天左右,不必每天登录上去看,审核通过后会有邮件通知。
审核通过后,我啥也没管,也没有像别的博客里提到的 close issue 之类的操作。
补全项目 pom.xml 中的信息
先不说如何部署到仓库上,先说几个必要的步骤。
pom.xml 中有些信息是必须的:
- 项目描述(description)
- 开源许可 (license)
- 开发者信息(developers)
- 去哪提 issue(issueManagement)
- 版本控制(scm)
当时我不知道,缺了好多,提交上去就报了错。后来就照葫芦画瓢把信息补上去了:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.jimmiez</groupId>
<artifactId>pcutil</artifactId>
<version>0.0.3</version>
<description>A 3d point cloud utility.</description>
<name>pcutil</name>
<url>http://www.jimmiez.cn/pcu/</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<packaging>jar</packaging>
<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<email>cquzjl@gmail.com</email>
<name>Jianling Zhou</name>
<url>https://github.com/Jimmie00x0000</url>
<id>Jimmie00x0000</id>
</developer>
</developers>
<issueManagement>
<url>https://github.com/Jimmie00x0000/PointCloudUtil/issues</url>
<system>GitHub Issues</system>
</issueManagement>
<scm>
<url>https://github.com/Jimmie00x0000/PointCloudUtil</url>
<connection>scm:git:https://git@github.com/Jimmie00x0000/PointCloudUtil.git</connection>
</scm>
<distributionManagement>
<snapshotRepository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<dependencies>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<keyname>${gpg.keyname}</keyname>
<passphraseServerId>${gpg.keyname}</passphraseServerId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
文档信息
这一部分我不是很确定,因为我怀疑 javadoc 不是必须的。
我第一次提交出了错,除了 pom.xml 中缺了信息外,Nexus 系统还告诉我没有附上 source 和 javadoc。
格式
然后我就研究了下,首先,你需要确保你的 JavaDoc 没有格式上的错误,对于你的库的API,你可以不写doc,但是一定要保证没有格式上的错误。常见的错误:
- 写了 @param ,忘了 @return
/**
* this is another api, bala bala
* @param foo is to xxx
**/
public int api1(String foo) {
// ....
return 0;
}
- 在标签以外的地方乱用尖括号 > 和 <
/**
* this is an api , you can refer to -> cn.edu.cqu.xxx.
* @param foo is to xxx
* @return status code
**/
public int api2(String foo) {
// ....
return 0;
}
像 IntelliJ IDEA 这样的 IDE会在你 doc 错误的地方提示的,所以不要忽视 IDE 的警告。
附上 doc
为此我去翻了 apache maven-doc plugin 的文档,最后发现的简单的办法好像就是在 pom.xml 中声明插件就 OK了:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
想要验证能否无错误地生成javadoc的话,可以在项目的根目录下执行
mvn site
之后根目录下的 target 目录下就会出现 site 目录,点击进去就可以看到根据你的 doc 生成的网页了。注意生成site这个目录只是一个调试行为,并不是上传到Maven仓库所需要的命令。
在这里我踩了一个坑,就是我用 IDEA 的自带工具,结果并不能生成 javadoc ,不知何故。
签名
想要上传到仓库,jar 包必须被签名,这一步略麻烦。首先要下载 gpg4win,下载地址。
安装好后,需要生成签名所需要的公私钥对,进入命令行,输入
gpg --gen-key
之后需要输入一些信息,像名字之类的,可以和 Sonatype 里的不一样,之后会弹个框让你设置一个密码,这个密码一定要记住,之后部署的时候需要输入。
安装了 gpg4win 后应该还会装上一个 Kleopatra 的客户端,打开这个软件,右键你刚才生成证书,点击“在服务器上发布”。
之后在 Maven 的 setting.xml 的 servers 标签下插入如下信息
<server>
<id>sonatype</id>
<username>你在sonatype上的用户名</username>
<password>你在sonatype上的密码</password>
</server>
部署到仓库
搞定了上述步骤后,在项目根目录下输入如下命令。如果最后看到了 BUILD SUCCESS,基本就没有太大问题了。
mvn deploy -X
使用 Sonatype 的用户名和密码,进入仓库的管理页面。注意上传成功后这次提交在Nexus Repo Manager 只会处于一个暂存的状态。
想要发布到中央仓库,先通过包名找到你的仓库(如果找不到说明没有上传成功,回去看看是不是忘了在 pom.xml 里指定 distributionManagement),选中仓库,上面有 close 可选。先close,再release。但是点击close不一定会成功,因为系统会检查你这次提交,比如javadoc有没有问题,有没有签名,有没有缺少信息之类的,检查的结果可以在下方的 Activity 标签页看到。
如果 close 失败,可以点击 drop 放弃这次提交,记得当时我还犹豫了会,在想这个 drop 会不会直接把 Project 给 drop 掉,事实证明不会。
如果 close 成功了,点击 release。不出啥意外的话大概等待五六个小时就可以在中央仓库上查到你的库了。