mvn 命令上传文件到 Maven 仓库

针对一个 Maven 的 Java 项目,我们执行 mvn deploy 命令时想要把生成的 jar 包上传到 Maven 仓库(本文将使用私有的 Nexus 仓库)中去。所要用到的插件 Maven Deploy Plugin ,本文实际就是讲述如何用该插件上传 jar 包到 Maven  仓库,更多用法请参考该插件的官方文档。

本文关键性的两个配置文件是 pom.xml 和 settings.xml。前者配置仓库的地址,后者中配置用户名和密码。要确定 Maven 使用了哪个 settings.xml 文件,用 mvn -X 查看,比如下面的输出

 [DEBUG] Reading global settings from /usr/local/Cellar/maven/3.8.3/libexec/conf/settings.xml  [DEBUG] Reading user settings from /Users/yanbin/.m2/settings.xml 

Maven 还允许在执行 mvn 命令时用  -s 或 --settings 参数指定 settings.xml 文件,如 mvn deploy --settings setting.xml

所以对于 settings.xml 文件的修改,可修改全局的,用户的或参数 --settings 指定的。

来一个实际的应用场景,假如我们要上传 jar 包(根据是否为 SNAPSHOT 包) 到下方相应的仓库中

  1. https://nexus.example.com/repository/maven-releases: release 包,即版本号不是 *-SNAPSHOT
  2. https://nexus.example.com/repository/maven-snapshots: snapshot 包,即版本号为 *-SNAPSHOT

瞧瞧可采用的几种方式

基本的操作方式

下面是一个完整的 pom.xml 文件

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>blog.yanbin</groupId>
    <artifactId>kafka-common</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>kafka-common</name>

    <distributionManagement>
        <repository>
            <id>private-release</id>
            <url>http://nexus.example.com/repository/maven-releases</url>
        </repository>
        <snapshotRepository>
            <id>private-snapshot</id>
            <url>http://nexus.example.com/repository/maven-snapshots</url>
        </snapshotRepository>
    </distributionManagement>

</project>

< project xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://maven.apache.org/POM/4.0.0"

         xsi : schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" >

     < modelVersion > 4.0.0 < / modelVersion >

     < groupId > blog . yanbin < / groupId >

     < artifactId > kafka - common < / artifactId >

     < version > 1.0.0 - SNAPSHOT < / version >

     < name > kafka - common < / name >

     < distributionManagement >

         < repository >

             < id > private - release < / id >

             < url > http : //nexus.example.com/repository/maven-releases</url>

         < / repository >

         < snapshotRepository >

             < id > private - snapshot < / id >

             < url > http : //nexus.example.com/repository/maven-snapshots</url>

         < / snapshotRepository >

     < / distributionManagement >

< / project >

由于 version 是 1.0.0-SNAPSHOT,所以将会部署到 distributionManagement/snapshotRepository 指示的仓库中,该仓库的 id 是 private-snapshot。如果我们执行 mvn deploy,Maven 将从 settings.xml 中找到该 id 对应的用户名和密码。因此我们须在 setting.xml 文件中预先配置

假如我们修改用户的 settings.xml 文件 ~/.m2/setting.xml

<?xml version="1.0"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
  <servers>
    <server>
      <id>private-snapshot</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
  </servers>
</settings>

<? xml version = "1.0" ?>

< settings xmlns = "http://maven.apache.org/SETTINGS/1.2.0"

           xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance"

           xsi : schemaLocation = "http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd" >

   < servers >

     < server >

       < id > private - snapshot < / id >

       < username > admin < / username >

       < password > admin123 < / password >

     < / server >

   < / servers >

< / settings >

现在我们来执行 mvn deploy, 这里跳过 test 和 install 这两步

$ mvn deploy -Dmaven.test.skip -Dmaven.install.skip
......
[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ kafka-common ---
Downloading from private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml
Downloaded from private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml (773 B at 4.0 kB/s)
Uploading to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.jar
Uploaded to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.jar (1.9 kB at 13 kB/s)
Uploading to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.pom
Uploaded to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.pom (1.2 kB at 1.9 kB/s)
Downloading from private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml
Downloaded from private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml (283 B at 2.5 kB/s)
Uploading to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml
Uploaded to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml (773 B at 4.9 kB/s)
Uploading to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml
Uploaded to private-snapshot: http://nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml (283 B at 2.6 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
......

$ mvn deploy - Dmaven . test . skip - Dmaven . install . skip

. . . . . .

[ INFO ] -- - maven - deploy - plugin : 2.7 : deploy ( default - deploy ) @ kafka - common -- -

Downloading from private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml

Downloaded from private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml (773 B at 4.0 kB/s)

Uploading to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.jar

Uploaded to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.jar (1.9 kB at 13 kB/s)

Uploading to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.pom

Uploaded to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/kafka-common-1.0.0-20211114.001059-5.pom (1.2 kB at 1.9 kB/s)

Downloading from private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml

Downloaded from private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml (283 B at 2.5 kB/s)

Uploading to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml

Uploaded to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/1.0.0-SNAPSHOT/maven-metadata.xml (773 B at 4.9 kB/s)

Uploading to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml

Uploaded to private - snapshot : http : //nexus.example.com/repository/maven-snapshots/blog/yanbin/kafka-common/maven-metadata.xml (283 B at 2.6 kB/s)

[ INFO ] -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

[ INFO ] BUILD SUCCESS

[ INFO ] -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

. . . . . .

上传成功了,如果 version 不是 *-SNAPSHOT, 比如为 1.0.0 , 它将会上传到 id 为   private-release 仓库,在 ~/.m2/settings.xml 就要有对应 id 为 private-release 的 <server> 来配置用户和密码。

还可以其他多种传入用户名密码的方式

通过系统属性传入帐号信息

配置 ~/.m2/settings.xml 的 <server>

<servers>
    <server>
      <id>private-snapshot</id>
      <username>${CI_USERNAME}</username>
      <password>${CI_PASSWORD}</password>
    </server>
  </servers>

   < servers >

     < server >

       < id > private - snapshot < / id >

       < username > $ { CI_USERNAME } < / username >

       < password > $ { CI_PASSWORD } < / password >

     < / server >

   < / servers >

mvn 命令为

 $ mvn deploy -DCI_USERNAME=admin -DCI_PASSWORD=admin123 

通过环境变量传入帐号信息

配置 ~/.m2/settings.xml 的 <server>

<server>
      <id>private-snapshot</id>
      <username>${env.CI_USERNAME}</username>
      <password>${env.CI_PASSWORD}</password>
    </server>

     < server >

       < id > private - snapshot < / id >

       < username > $ { env . CI_USERNAME } < / username >

       < password > $ { env . CI_PASSWORD } < / password >

     < / server >

执行 mvn 命令前必须设置相应的环境变量

 $ export CI_USERNAME=admin  $ export CI_PASSWORD=admin123  $ mvn deploy 

配置用户名密码到 url 中

这种方式我们用不着 settings.xml 文件,测试前可把  settings.xml 文件删除。只需修改 pom.xml 文件, 给 distributionManagement 中的 <url> 中配置上用户名和密码

<distributionManagement>
        <repository>
            <id>private-release</id>
            <url>http://admin:admin123@nexus.example.com/repository/maven-releases</url>
        </repository>
        <snapshotRepository>
            <id>private-snapshot</id>
            <url>http://admin:admin123@nexus.example.com/repository/maven-snapshots</url>
        </snapshotRepository>
    </distributionManagement>

     < distributionManagement >

         < repository >

             < id > private - release < / id >

             < url > http : //admin:admin123@nexus.example.com/repository/maven-releases</url>

         < / repository >

         < snapshotRepository >

             < id > private - snapshot < / id >

             < url > http : //admin:admin123@nexus.example.com/repository/maven-snapshots</url>

         < / snapshotRepository >

     < / distributionManagement >

然后执行 mvn deploy 即能成功上传 jar 包。这种配置方式肯定不安全,绝对不应该把密码放到项目文件中去的,所以千万别采用。

直接上传一个 jar 文件

有时候拿到的是一个别人的 jar,没有源文件,想把它直接上传到 Maven 仓库中去供其它 Java 项目享用, 这时候我们要用到的命令是 mvn deploy:deploy-file。当然登陆 nexus Web 控制台手工上传也行,本文主要讲 mvn deploy 的使用。

回顾一下用 twine 把一个 Python 的 whl 包上传到 nexus 上的方式

 twine upload --repository-url=https://nexus.example.com/repository/pypi-hosted/ dist/bounded_executor-0.0.3-py3-none-any.whl 

直接上传一个 jar 文件与针对 Maven 项目执行 mvn deploy 并无多大区别,唯一不同的是 Maven 项目有一个 pom.xml 文件,在其中有 groupId, artifactId, version 等的描述,而使用 mvn deploy:deploy-file 的话就要在命令中给出相同的信息。 mvn deploy:deploy-file 也能用 -DpomFile 指定一个 pom.xml 文件, 如果该 jar 有传递的依赖也许是有必要用这个参数。

应用 settings.xml 的帐号信息

执行 deploy:deploy-file 依旧可以用 settings.xml 文件,配置方式与前面三种方式是一样的,帐户信息可明文配置,或从系统属性或环境变量中来。假如 jar 包文件名是 redis-common-1.0.0-SNAPSHOT.jar, ~/.m2/settings.xml 中配置的 server

<servers>
    <server>
      <id>private-snapshot</id>
      <username>${CI_USERNAME}</username>
      <password>${CI_PASSWORD}</password>
    </server>
  </servers>

   < servers >

     < server >

       < id > private - snapshot < / id >

       < username > $ { CI_USERNAME } < / username >

       < password > $ { CI_PASSWORD } < / password >

     < / server >

   < / servers >

上传该 jar 包到私有仓库的命令是

 mvn deploy:deploy-file -DCI_USERNAME=admin -DCI_PASSWORD=admin123 \    -DgroupId=blog.yanbin.redis -DartifactId=redis-common -Dversion=1.0.0-SNAPSHOT -Dpackaing=jar \    -DrepositoryId=private-snapshot \    -Durl=http://nexus.example.com/repository/maven-snapshots \    -Dfile=redis-common-1.0.0-SNAPSHOT.jar 

无需 settings.xml 文件

也可以完全不用 settings.xml 文件,而在 mvn 命令中的 URL 中带上用户名和密码。测试下面的命令前把 ~/.m2/settings.xml 文件先删除

 mvn deploy:deploy-file \    -DgroupId=blog.yanbin.redis -DartifactId=redis-common -Dversion=1.0.0-SNAPSHOT -Dpackaing=jar \    -Durl=http://admin:admin123@nexus.example.com/repository/maven-snapshots \    -Dfile=redis-common-1.0.0-SNAPSHOT.jar 

这种方式对于临时把一个 jar 包上传到私有仓库更快捷,反正是本机执行,不应有什么安全隐患。此时如果使用 settings.xml 配置了用户名和密码,那么 -Durl 中的用户名和密码将被忽略。

和任何 bash 命令一样,密码中带有特殊符号的要注意转义,比如密码是 aB!ak47%^ ,在 mvn deploy:deploy-file 命令的 -Durl 写成

 -Durl=http://admin:aB!ak47%^@nexus.example.com/repository/maven-snapshots 

在 zsh 中将会看到

 zsh: event not found: ak47 

在 bash 中看到的是

 bash: !ak47%^@nexus.example.com/repository/maven-snapshots: event not found 

原因是感叹号 ! 在 zsh 和 bash 中是唤起一个历史命令,如 !ak47 是从历史命令中查找一个以 ak47 开头的命令,没有的话就是 event not found .

所以我们必须对感叹号进行转义,在它前头加上反斜杠,完整的 mvn deploy:deploy-file 命令是

 mvn deploy:deploy-file \    -DgroupId=blog.yanbin.redis -DartifactId=redis-common -Dversion=1.0.0-SNAPSHOT -Dpackaing=jar \    -Durl=http://admin:aB\!ak47%^@nexus.example.com/repository/maven-snapshots \    -Dfile=redis-common-1.0.0-SNAPSHOT.jar 

实际的密码 aB!ak47%^ 被转义为 aB\!ak47%^ 。

如果把这个 mvn deploy:deploy-file 命令写到一个 deploy.sh 文件中的话,转义又多余了,其中 -Durl 部分写成 -Durl=http://admin: aB!ak47%^ @nexus.... ,然后用  sh deploy.sh 执行也不会有问题。

Maven effective-settings 插件

该插件能显示出 Maven  用到的 settings 信息,包括其中配置的用户名密码

 $ mvn help:effective-settings -DshowPasswords=true 
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务