关于处理第三方jar包的maven攻略

643 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

0.背景

当我们进行开发时,如对接第三方应用平台,通常会得到第三方平台提供的jar包。如果仅仅是添加到路径下,有时又会因为类找不到而运行失败,所以通常我们会将jar包安装到本地或上传到私有maven服务器。

1.本地安装方式

1.1.查看jarmaven相关信息

比如,我们有一个jar包叫zjfire-sdk-0.01.jar,一般来说,maven打包,jar包内都会有这么一个目录META-INF/maven/...

多说两句,这里的META-INF就是指元数据,maven呢就是maven相关,都是直译,别紧张。

image.png

将这两个文件解压出来,我们看到pom.properties文件如下:

#Generated by Maven
#Fri Jan 14 15:18:21 CST 2022
groupId=com.hikvision
artifactId=zjfire-sdk-0.01
version=1.0-SNAPSHOT

1.2.根据pom.properties的信息本地安装

image.png

于是我们依据此信息安装到本地,执行命令:

mvn install:install-file -Dfile=./zjfire-sdk-0.01.jar -DpomFile=./pom.xml -DgroupId=com.hikvision -DartifactId=zjfire-sdk-0.01 -Dversion=1.0-SNAPSHOT -Dpackaging=jar

然后我们就可以看到本地仓库中已经有了此依赖,依赖关系的pom文件也在,其实这个文件就是pom.xml

image.png

我们可以打开它,发现依赖关系是存在的。这样才能正确获得依赖关系,减少类找不到的奇怪错误。

在我们项目中,使用正常的依赖方式进行依赖即可,当然了,要按照我们安装时指定的-DgroupId-DartifactId-Dversion

也就是:

<dependency>
   <groupId>com.hikvision</groupId>
   <artifactId>zjfire-sdk-0.01</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>

当然了,你也可以按照你的需要去设定-DgroupId-DartifactId-Dversion,只要你依赖时保持一致即可。

1.3.直接使用Maven插件来自动安装

一般情况下,我们拥有开发项目,可以在项目中直接添加Maven插件指定项目中的文件安装到本地仓库,比如我们安装opencv的包到本地仓库。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-install-plugin</artifactId>
    <version>2.5.2</version>
    <executions>
        <execution>
            <id>install-opencv</id>
            <phase>clean</phase>
            <configuration>
                <file>${project.basedir}/lib/opencv/opencv-451.jar</file>
                <repositoryLayout>default</repositoryLayout>
                <groupId>org.openpnp</groupId>
                <artifactId>opencv</artifactId>
                <version>4.5.1</version>
                <packaging>jar</packaging>
                <generatePom>true</generatePom>
            </configuration>
            <goals>
                <goal>install-file</goal>
            </goals>
        </execution>
    </executions>
</plugin>

这样我们在填写依赖的时候,就可以非常干净地指定:

<dependency>
    <groupId>org.openpnp</groupId>
    <artifactId>opencv</artifactId>
    <version>4.5.1</version>
</dependency>

这样其他工程师下载完项目之后就可以直接 clean install 了,不会报错。这个插件类似于我们手动将jar包安装到本地仓库,这样更加便捷一些。但是如果开发人员都能连接到Maven私有服务器,还是推荐下面的方式:

2.通过命令行上传到maven私服

讲通了本地上传,如果你的公司有maven私服,那再好不过。我们首先保证maven对于本机电脑用户配置的setting.xml文件中关于服务的配置已经配置正确。

2.1.检查Mavensettings.xml中的配置是否正确

servers (服务器仓库的id)的属性对:

<servers>
    <!-- server
     | Specifies the authentication information to use when connecting to a particular server, identified by
     | a unique name within the system (referred to by the 'id' attribute below).
     |
     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
     |       used together.
     |
    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    -->

    <server>
      <id>3rd_part</id>
      <username>Sonatype Nexus Repository Manager中的用户名</username>
      <password>Sonatype Nexus Repository Manager中的用户名对应的密码</password>
    </server>
  </servers>

服务器仓库的信息对应到maven的属性即可,也就是 <profiles> 标签下:

为了书写方便,我们假设maven仓库的地址是:192.168.8.88:8888

<profiles>
    <profile>
      <id>nexus3</id>
      <repositories>
        <repository>
          <id>3rd_part</id>
          <url>http://192.168.8.88:8888/repository/3rd_part/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </repository>
      </repositories>
    </profile>
</profiles>

如果你要上传快照版本的文件,别忘了把快照对应的xml配置设置为true。新建Repositories的时候选上Mixed

image.png

虽然我说明了此种情况,但我不建议您保存第三方的快照版本的jar包,您可以自己为它们编制发布版本以进行区分!

2.2.使用mvn deploy上传第三方jar

由于之前在第一节中,我们已经说明了关于包基本信息的内容,在发布到maven私服时只说明私服相关的配置:

在需要传到maven私服的jar包的同级目录运行命令

mvn deploy:deploy-file -Dfile=./zjfire-sdk-0.01.jar -DpomFile=./pom.xml -DgroupId=com.hikvision -DartifactId=zjfire-sdk-0.01 -Dversion=1.0-SNAPSHOT -Dpackaging=jar -DrepositoryId=3rd_part -Durl=http://192.168.8.88:8888/repository/3rd_part/

如果您的仓库不允许快照版本上传,报出如下错误,您可以讲SNAPSHOT去除,自行编码:

400 Repository version policy: RELEASE does not allow metadata in path:

此时我们应该运行成功,且私服中已有了对应的jar包

image.png

我们还需要最后一步检验,浏览器中查看pom文件是否正确,若正确,可以在他人电脑中引用依赖,查看是否正常。

image.png

3.特殊的情况-有源码

我们如何得知一个命令的所有可以使用的-D参数呢?可以去官网查看,例如 install:install-file

  mvn install:install-file -Dfile=your-artifact-1.0.jar \
  [-DpomFile=your-pom.xml] \
  [-Dsources=src.jar] \
  [-Djavadoc=apidocs.jar] \
  [-DgroupId=org.some.group] \
  [-DartifactId=your-artifact] \
  [-Dversion=1.0] \
  [-Dpackaging=jar] \
  [-Dclassifier=sources] \
  [-DgeneratePom=true] \
  [-DcreateChecksum=true]

我们发现,我们可以指定-Dsources-Djavadoc来指定源码和Javadoc文档。也就是说,如果您情况很特殊,拥有了源码包,可以这样指定一下:

mvn install:install-file -Dfile=./zjfire-sdk-0.01.jar -DpomFile=./pom.xml -DgroupId=com.hikvision -DartifactId=zjfire-sdk-0.01 -Dversion=1.0-SNAPSHOT -Dpackaging=jar -Dsources=./zjfire-sdk-0.01-sources.jar

image.png

这样您本地仓库就有源码了,IDEA中也可以打开源码了,但一般来说,第三方jar包不会给出源码。

同理,我们可以看到 deploy:deploy-file 有一个sources的可选参数配置。

思考题

最后,我们留一道思考题,由于安装或上传jar包时没有上传pom文件导致的依赖关系缺失而使程序运行时类找不到,属不属于依赖冲突呢?欢迎在评论区留下你的观点。