发布个人项目jar包到maven中央仓库详解

1、在sonatype提交发布工单(Issue)

  • sonatype是由社区支持的开源项目托管服务(Open Source Project Repository Hosting,简称OSSRH),它免费,开发者可以将自己的开源项目生成的jar包托管到这里
  • 当项目打包部署到这里之后,它将自动同步到maven中央仓库
  • 使用maven或者gradle构建项目生成的jar发布到maven中央仓库都需要OSSRH账号

1.1 OSSRH账号注册

立即注册

发布jar包到nexus仓库 发布jar到maven私人仓库_发布jar包到nexus仓库

完成注册后会跳转到登录界面,立即登录即可

1.2 新建问题

新建问题实际上是发起了一个新建项目审核的审核工作流,会有人审核你所填写的信息

发布jar包到nexus仓库 发布jar到maven私人仓库_jar_02

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_03

发布jar包到nexus仓库 发布jar到maven私人仓库_发布jar包到nexus仓库_04

1.3 域名认证

  • 新建问题之后,查看问题中的活动日志

发布jar包到nexus仓库 发布jar到maven私人仓库_发布jar包到nexus仓库_05

  • 在自己的域名下添加一条解析

发布jar包到nexus仓库 发布jar到maven私人仓库_java_06

  • 域名解析记录值添加完成之后,回到sonatype JIRA管理平台,点击问题后的responsed按钮

发布jar包到nexus仓库 发布jar到maven私人仓库_gradle_07

  • 如果没有域名,也可以将Group Id填写为github的用户域,如: com.github.<gihub用户名> ,填写github用户域,验证方式也不一样,需要你在github中新建一个空的仓库,仓库的名称是 OSSRH-84194

2、安装GnuPG软件,并生成签名

2.1 下载安装GnuPG

下载地址 windows直接下载 傻瓜式安装

2.2 创建密钥

我们打开windows的 CMD命令行,执行如下命令:

# 生成密钥
C:\Users\MC123>gpg --full-generate-key
# 查看密钥
C:\Users\MC123>gpg --list-key
# 密钥对生成完成之后,将其公钥发往sonatype认可的keyserver
C:\Users\MC123>gpg --keyserver keyserver.ubuntu.com --send-keys  98700D239EA4BD1092B749640CC20CE1E836B7B3
# 校验公钥的字符串发往服务器是否成功
C:\Users\MC123>gpg --keyserver keyserver.ubuntu.com --recv-keys 98700D239EA4BD1092B749640CC20CE1E836B7B3

发布jar包到nexus仓库 发布jar到maven私人仓库_gradle_08

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_09

发布jar包到nexus仓库 发布jar到maven私人仓库_gradle_10

3、项目配置及打包

此处介绍使用gradle构建的项目的配置方式

3.1 添加配置信息

打开已经安装的GnuPG软件Kleopatra

发布jar包到nexus仓库 发布jar到maven私人仓库_jar_11

导出私钥

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_12

发布jar包到nexus仓库 发布jar到maven私人仓库_jar_13

复制私钥到项目路径下

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_14

创建全局变量配置

  • 项目根目录下新建gradle.properties
# sonatype username
ossrhUsername=asdf
# sonatype 密码
ossrhPassword=Sonatypeuserpwd

# gpg公钥指纹的最后8位
signing.keyId=WW1A82WW   
# 设置的密钥密码
signing.password=reeee21  
# gpg私钥的路径
signing.secretKeyRingFile=machao (15009421862)_0xE836B7B3_SECRET.gpg
  • 编译脚本 build.gradle
plugins {
    id 'java'
    id 'maven' // 为了产生pom.xml文件
    id 'signing'  // 组件签名插件
}

// 项目组和版本
group = 'top.mstudy'
archivesBaseName = "commons-tool"
version = "0.0.2"

apply plugin: 'maven-publish'

// 指定所使用的的仓库
repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url = uri('http://maven.aliyun.com/nexus/content/groups/public/')
    }
}

/**
 * gradle工程所有的jar包的坐标都在dependencies属性内放置
 * 每一个jar包的坐标都有三个基本元素组成:group,name,version
 * testCompile表示该jar包在测试的时候起作用,该属性为jar包的作用域
 * 我们在gradle里面添加坐标的时候都要带上jar包的作用域
 */
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web:2.4.13'
    ......
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

// java的版本和编码集等信息,这里记得和idea中配置的一样,都使用你自己的java版本
compileJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    [compileJava]*.options*.encoding = 'UTF-8'
}

compileTestJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    [compileTestJava]*.options*.encoding = 'UTF-8'
}

test {
    exclude '**/*.class'
}

publishing {
    publications {
        maven(MavenPublication) {
            from(components.java)
        }
    }
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}
//对于典型的 Java 项目,您可以添加一个javadocJar以及一个 sourcesJar任务
task javadocJar(type: Jar) {
    classifier = 'javadoc'
    from javadoc
}

task sourcesJar(type: Jar) {
    classifier = 'sources'
    from sourceSets.main.allSource
}

// javadoc 配置,这里是自定义了 java doc 的一些配置
javadoc {
    description = "Generates project-level javadoc for use in -javadoc jar"

    options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
    options.author = true
    options.version = true
    options.header = project.name
    options.addStringOption('Xdoclint:none', '-quiet')

    // suppress warnings due to cross-module @see and @link references;
    // note that global 'api' task does display all warnings.
    logging.captureStandardError LogLevel.INFO
    logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
    options.encoding = "UTF-8"  //编码一定要配置否则直接出错
    options.charSet = 'UTF-8'
}

// 并将它们与项目 jar 本身一起连接到 artifacts 集合中:
artifacts {
    archives javadocJar, sourcesJar
}

// 将构建的包签名
signing {
    sign configurations.archives
}

//元数据定义和上传︎
uploadArchives {
    repositories {
        mavenDeployer {
            beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }

            repository(url: "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") {
                authentication(userName: ossrhUsername, password: ossrhPassword)
            }

            snapshotRepository(url: "https://s01.oss.sonatype.org/content/repositories/snapshots/") {
                authentication(userName: ossrhUsername, password: ossrhPassword)
            }

            pom.project {
                name 'Example Application'
                packaging 'jar'
                // optionally artifactId can be defined here
                description "A application used as an example on how to set up pushing  its components to the Central Repository."
                url 'http://www.example.com/example-application'

                scm {
                    connection 'scm:svn:http://foo.googlecode.com/svn/trunk/'
                    developerConnection 'scm:svn:https://foo.googlecode.com/svn/trunk/'
                    url 'http://foo.googlecode.com/svn/trunk/'
                }

                licenses {
                    license {
                        name 'The Apache License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }

                developers {
                    developer {
                        id 'manfred'
                        name 'Manfred Moser'
                        email 'manfred@sonatype.com'
                    }
                }
            }
        }
    }
}

allprojects {
    tasks.withType(Javadoc).all { enabled = false }
}

description = '项目描述'

3.2 打包上传

发布jar包到nexus仓库 发布jar到maven私人仓库_发布jar包到nexus仓库_15

输出上面的日志表示上传成功

4、CLOSE&RELEASE

使用sonatype的账号和密码进入到 nexus repository manager

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_16

4.1 close仓库

close实际是检测仓库的一个过程,检测没问题才可以发布

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_17

发布jar包到nexus仓库 发布jar到maven私人仓库_java_18

4.2 release仓库

release就是将仓库发布到maven中央仓库,这也是我们要做的最后一步

发布jar包到nexus仓库 发布jar到maven私人仓库_发布jar包到nexus仓库_19

发布jar包到nexus仓库 发布jar到maven私人仓库_gradle_20

release之后我们会收到一封report邮件

发布jar包到nexus仓库 发布jar到maven私人仓库_maven_21

此时我们已经可以在中央仓库搜索到我们提交的jar包了

发布jar包到nexus仓库 发布jar到maven私人仓库_java_22

release之后,需要四个小时左右才能在 search.maven.org 上找到你的jar包,如果需要在 mvnrepository.com 上找到,则需要更长的时间

发布jar包到nexus仓库 发布jar到maven私人仓库_gradle_23

5、项目中验证结果

maven中央仓库同步到国内的源是需要时间的,要保证项目里maven中央仓库的优先级在上面

repositories {
   mavenLocal()   
   maven {
      url = uri('https://repo1.maven.org/maven2/')
   }
   maven {
      url = uri('https://maven.aliyun.com/repository/public')
   }
}

引入依赖

dependencies {
    implementation 'top.mstudy:commons-tool:0.0.2'
}

发布jar包到nexus仓库 发布jar到maven私人仓库_jar_24

6、拓展知识

将gradle构建的项目jar包添加到本地maven仓库

  • 编辑脚本 build.gradle
group = 'top.mstudy'
archivesBaseName = "commons-tool"
version = "1.0.0"

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('D:/Program Files/IntelliJ IDEA/Maven/apache-maven-3.6.1/repository'))
        }
    }
}
  • 添加jar到本地maven仓库

发布jar包到nexus仓库 发布jar到maven私人仓库_发布jar包到nexus仓库_25

发布jar包到nexus仓库 发布jar到maven私人仓库_gradle_26

打包成功~

  • gradle项目中使用
# 设置本地仓库地址
repositories {
    maven {
        url = uri('D:/Program Files/IntelliJ IDEA/Maven/apache-maven-3.6.1/repository')
    }
}

# 引用依赖
dependencies {
    implementation 'top.mstudy:commons-tool:1.0.0'
}
  • maven项目中使用
# 设置本地maven仓库的镜像
<mirrors>
  	<mirror>
		<id>central</id>
		<name>Maven Repository Switchboard</name>
		<url>https://repo1.maven.org/maven2/</url>
		<mirrorOf>central</mirrorOf>
	</mirror>
</mirrors>
# 单独在maven项目中设置
<repositories>
   <repository>
      <id>central</id>
      <name>Maven Repository Switchboard</name>
      <url>https://repo1.maven.org/maven2/</url>
   </repository>
</repositories>
# 引用依赖
<dependency>
    <groupId>top.mstudy</groupId>
    <artifactId>commons-tool</artifactId>
    <version>1.0.0</version>
</dependency>