记一次 Maven 打包后,第三方无法使用的排查记录

网站建设3年前发布
46 0 0

你好,我是悟空。,本文主要内容如下:,20230306154432b431c945188e37d78aa068a144c3c861c6806a148,目录,最近遇到一个需求:,写一个工具类的 JAR 包,然后提供给第三方调用其中的类方法。(前提:第三方无法共用我们项目的私有仓库),期间遇到了一些问题:,本篇做个记录,希望能帮助到其他小伙伴。,本篇既然涉及到 Maven,这里先总结下 Maven 的常用命令。对 Maven 命令比较熟悉的同学可以跳过这小节。,当我们创建好一个 Maven 工程时,IDEA 开发工具的右侧就会自动出现 Maven 命令。,202303070149396873ec990c131a74a6b765321ae6068452c651329,Maven 操作,我们用鼠标双击下就可以运行了,也可以通过命令行来执行,20230307014939361ccd25415a5a00c08818406242a678793c3b281,下面介绍这几种命令的区别。,删除项目路径下的 target 文件,但是不会删除本地的maven仓库已经生成的 JAR 文件。,20230307014625267f1aa91e89b58d6e6380baf559b903cb6b4f762,验证工程正确性,所需信息是否完整。,编译。会在你的项目路径下生成一个target目录,在该目录中包含一个classes文件夹,里面全是生成的class文件。,执行单元测试。,将工程文件打包为指定的格式,例如 JAR,WAR 等(看你项目的 pom文件,里面packaging 标签就是来指定打包类型的)。,这个命令会在你的项目路径下一个target目录,并且拥有compile命令的功能进行编译,同时会在target目录下生成项目的 jar/war文件。,202303070146263864c9e326b3217b2c6962a8479fd60550929e804,如果a项目依赖于b项目,打包b项目时,只会打包到b项目下target下,编译a项目时就会报错,因为找不到所依赖的b项目,说明a项目在本地仓库是没有找到它所依赖的b项目,这时就用到 install 命令。,核实,主要是对 package 检查是否有效、符合标准。,将包安装至本地仓库,以让其它项目依赖。,该命令包含了 package 命令功能,不但会在项目路径下生成 class 文件和 jar 包,同时会在你的本地maven仓库生成 jar 文件,供其他项目使用(如果没有设置过maven本地仓库,一般在用户 /.m2 目录下。如果 a 项目依赖于 b 项目,那么 install b 项目时,会在本地仓库同时生成 pom 文件和 jar文件,解决了上面打包 package出错的问题)。,20230307014941c61caa67562af0860dd4684481d0e2d6256619202,建造。功能类似compile,区别是对整个项目进行编译。,与 compile区别及特点:是对整个工程进行彻底的重新编译,而不管是否已经编译过。,Build过程往往会生成发布包,这个具体要看对 IDE 的配置了,Build在实际中应用很少,因为开发时候基本上不用,发布生产时候一般都用ANT等工具来发布。Build 因为要全部编译,还要执行打包等额外工 作,因此时间较长。,生成项目的站点文档。,部署。将 jar 包部署到远程仓库,通常是私有仓库。而且包含了 install 命令的功能。,下面介绍一下我用常规打包方式遇到的问题。,我通过 IDEA 工具创建了一个 SpringBoot 项目,然后 pom.xml 文件中会自动引入一个打包插件,如下图所示:,20230307014628412f15c514c93a7444056736e0e64823537bd6958,然后我执行 maven package 命令,会在项目的 target 目录生成一个 JAR 包。如下图所示:,2023030701462858f00d429814cfa23cd5959e629d204cf28d22345,然后我做了以下事情:,把这个 JAR 包拷贝出来,发给了第三方。,让第三方拷贝到他们自己的本地项目中。这里是在项目的根目录创建了一个 libs 目录,然后将 jar 包放到 libs 目录中。,20230307014941129a15f9843ebffe0633404c38414db4fc3cc7619,让第三方在 pom 依赖中引入这个依赖包。,20230307014630e7b9e6093488b6cbd50387243c90938c108801888,scope 指定为 system,表示引入指定路径(systemPath配置)下的 JAR 包。,看起来这么做没问题了,但是当我们 import 这个 JAR 包下的类时,就会报错。如下图所示:,20230307014941252e861591619828702179984b86f6f0ae4212291,很奇怪,这里为什么会报错呢??,先看下这个 JAR 包是否引入了。如下所示,可以看到确实是正确引入了,没有报错。,2023030714121852d5647679f2d83c31d177da7be8b8f66550d9325,通过 research,发现这个打包插件打出来的 JAR 包,是供执行的,也就是可以通过 java -jar 命令来运行这个 JAR 包,并不能给第三方来引用使用。,解决方案:换一个打包插件 maven-compiler-plugin。,再次打包发给第三方,发现 import 不报错了。,但是又报另外一个错,我们接着往下看。,报错信息如下:,通过这个信息,可以想到是不是我提供的 JAR 包中引入了这个 commons-codec 依赖,而 JAR 包文件中又不包含这个依赖。,看下这个 JAR 文件的大小,只有 14 KB, 而 commons-codec 的包大小为 339 KB,说明这个 JAR 包确实不包含 common-codec 依赖。,20230307014630e54e8247403ffc039c9458060ecee38c719567771,解决方案:,将其他依赖包打入到这个 JAR 包里面(推荐)。,第三方自己引入其他依赖包。(麻烦了第三方,要第三方一个个引入),那如何将依赖的包打进这个 JAR 包里面呢?,这里还要引入一个打包插件:maven-assembly-plugin,如下所示。(省略了部分标签),然后还要用插件打包的方式:assembly:assembly,2023030701494329b197c19c8575a154a729fc081913e1c5f999228,然后target目录下会多出一个包,带了一个后缀:jar-with-dependencies,这个包的文件的大小比较大,有 15.4 M。,发给第三方再次引入后,不再报错了。,2023030701463134b4dd326e63ef91af541815dd853969ecd53c234,我们来看下这个包里面有什么东西,在 META-INF/maven 目录下可以看到 commons-codec 依赖包,说明确实将这个依赖包打进去了。,20230307014945540777f087e7c53fd414926e870d1e3121d383542,而之前打的包,是没有这个目录的。,20230307014633764fb89579455f12592947e57f25abc807cb6b127,至此,排查结束。,​​https://blog.csdn.net/Shangxingya/article/details/114810454​​,​​https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html​​,8 年互联网开发经验,擅长微服务、分布式、架构设计。目前在一家大型上市公司从事基础架构和性能优化工作。,InfoQ 签约作者、蓝桥签约作者、阿里云专家博主、51CTO 红人。

© 版权声明

相关文章