maven 多模块项目如何导入其他模块的第三方 jar 包

1,803 阅读2分钟

背景

写了半年的 Vue 前端,今天对整个前后端项目结构进行了一下梳理,在打包项目时,碰到一个 maven 多模块依赖的问题,本文将记录一下这个问题及其解决办法。

问题描述

整个工程是基于 maven 的多模块项目,由一个父模块和 N 个子模块组成。其中有一个 common 模块,被所有子模块依赖,打包模式为 jar 。

它包含了一个 system scope 的第三方 jar 包 ,是跟国密加密算法相关的:

<dependency>
     <groupId>SM4Crypto</groupId>
     <artifactId>SM4Crypto</artifactId>
     <version>1.0.0</version>
     <scope>system</scope>
     <systemPath>${project.basedir}/lib/SM4Crypto.jar</systemPath>
   </dependency>

我需要对子模块 B 进行打包,它是一个 web war 项目,依赖于 common 模块。打包一直失败,提示编译错误,主要是 common 模块中依赖的公共 jar,如 fastjson 、common-lang 等类找不到。

使用 mvn clean install -X 查看打包信息时,错误信息显示依赖的 common 模块有问题:

The POM for xxx-common:jar:4.0.0 is invalid
[ERROR] 'dependencies.dependency.systemPath' for 
SM4Crypto:SM4Crypto:jar must specify an absolute path but is 
${project.basedir}/lib/SM4Crypto.jar

解决办法

按照模块依赖的打包流程,先对 common 模块执行了 install ,再对模块 B 执行 install 。报错信息说明模块 B 在解决 common 的依赖时,认为其 pom.xml 无效,原因是SM4Crypto.jar 的路径是相对路径。

据我猜测,应该是 common 模块在 install 之后,已经脱离原工程、被安裝到仓库中了,这个相对路径就没办法计算出确切的值,导致编译失败。

解决办法有两种

  1. 把 common 模块对 SM4Crypto.jar 的依赖路径改成绝对路径,保证 install 之后,模块 B 解决依赖时能找到它;
<dependency>
     <groupId>SM4Crypto</groupId>
     <artifactId>SM4Crypto</artifactId>
     <version>1.0.0</version>
     <scope>system</scope>
     <systemPath>E:/myproject/ModuleB/lib/SM4Crypto.jar</systemPath>
   </dependency>
  1. SM4Crypto.jar 作为独立模块安裝到本地仓库,然后 common 模块中正常引用仓库包,不需要用 system 方式引用第三方 jar 包。
<dependency>
     <groupId>SM4Crypto</groupId>
     <artifactId>SM4Crypto</artifactId>
     <version>1.0.0</version>
 </dependency>

启示录

maven 多模块开发有两点值得注意,第一,如果是 war 项目,依赖第三方 jar 可以通过 scope 为 system 的方式处理,但这里是普通的 jar 模块,就会出现本文的问题。如果公司私服中安裝了这个第三方 jar ,就不会有问题啦;否则只能由开发人员自行解决依赖了。

第二,模块的安裝顺序,理论上是先 install root 模块的。但是,如果子模块过多,就会很慢,有一个快捷方法是注释掉子模块后再 install 父模块,空跑很快。

然后只对需要的模块打包就可以了,基本顺序是:

父模块——>依赖模块——> 目标模块