你好,我是悟空。
本文主要内容如下:
目录
最近遇到一个需求:
写一个工具类的 JAR 包,然后提供给第三方调用其中的类方法。(前提:第三方无法共用我们项目的私有仓库)
期间遇到了一些问题:
本篇做个记录,希望能帮助到其他小伙伴。
本篇既然涉及到 Maven,这里先总结下 Maven 的常用命令。对 Maven 命令比较熟悉的同学可以跳过这小节。
当我们创建好一个 Maven 工程时,IDEA 开发工具的右侧就会自动出现 Maven 命令。
Maven 操作
我们用鼠标双击下就可以运行了,也可以通过命令行来执行
下面介绍这几种命令的区别。
删除项目路径下的 target 文件,但是不会删除本地的maven仓库已经生成的 JAR 文件。
验证工程正确性,所需信息是否完整。
编译。会在你的项目路径下生成一个target目录,在该目录中包含一个classes文件夹,里面全是生成的class文件。
执行单元测试。
将工程文件打包为指定的格式,例如 JAR,WAR 等(看你项目的 pom文件,里面packaging 标签就是来指定打包类型的)。
这个命令会在你的项目路径下一个target目录,并且拥有compile命令的功能进行编译,同时会在target目录下生成项目的 jar/war文件。
如果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出错的问题)。
建造。功能类似compile,区别是对整个项目进行编译。
与 compile区别及特点:是对整个工程进行彻底的重新编译,而不管是否已经编译过。
Build过程往往会生成发布包,这个具体要看对 IDE 的配置了,Build在实际中应用很少,因为开发时候基本上不用,发布生产时候一般都用ANT等工具来发布。Build 因为要全部编译,还要执行打包等额外工 作,因此时间较长。
生成项目的站点文档。
部署。将 jar 包部署到远程仓库,通常是私有仓库。而且包含了 install 命令的功能。
下面介绍一下我用常规打包方式遇到的问题。
我通过 IDEA 工具创建了一个 SpringBoot 项目,然后 pom.xml 文件中会自动引入一个打包插件,如下图所示:
然后我执行 maven package 命令,会在项目的 target 目录生成一个 JAR 包。如下图所示:
然后我做了以下事情:
把这个 JAR 包拷贝出来,发给了第三方。
让第三方拷贝到他们自己的本地项目中。这里是在项目的根目录创建了一个 libs 目录,然后将 jar 包放到 libs 目录中。
让第三方在 pom 依赖中引入这个依赖包。
scope 指定为 system,表示引入指定路径(systemPath配置)下的 JAR 包。
看起来这么做没问题了,但是当我们 import 这个 JAR 包下的类时,就会报错。如下图所示:
很奇怪,这里为什么会报错呢??
先看下这个 JAR 包是否引入了。如下所示,可以看到确实是正确引入了,没有报错。
通过 research,发现这个打包插件打出来的 JAR 包,是供执行的,也就是可以通过 java -jar 命令来运行这个 JAR 包,并不能给第三方来引用使用。
解决方案:换一个打包插件 maven-compiler-plugin。
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
UTF-8
再次打包发给第三方,发现 import 不报错了。
但是又报另外一个错,我们接着往下看。
报错信息如下:
java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64
通过这个信息,可以想到是不是我提供的 JAR 包中引入了这个 commons-codec 依赖,而 JAR 包文件中又不包含这个依赖。
看下这个 JAR 文件的大小,只有 14 KB, 而 commons-codec 的包大小为 339 KB,说明这个 JAR 包确实不包含 common-codec 依赖。
解决方案:
将其他依赖包打入到这个 JAR 包里面(推荐)。
第三方自己引入其他依赖包。(麻烦了第三方,要第三方一个个引入)
那如何将依赖的包打进这个 JAR 包里面呢?
这里还要引入一个打包插件:maven-assembly-plugin,如下所示。(省略了部分标签)
org.apache.maven.plugins
maven-assembly-plugin
3.0.0
org.apache.maven.plugins
maven-assembly-plugin
2.4.1
jar-with-dependencies
然后还要用插件打包的方式:assembly:assembly
然后target目录下会多出一个包,带了一个后缀:jar-with-dependencies
decryption-0.0.1-SNAPSHOT-jar-with-dependencies.jar
这个包的文件的大小比较大,有 15.4 M。
发给第三方再次引入后,不再报错了。
我们来看下这个包里面有什么东西,在 META-INF/maven 目录下可以看到 commons-codec 依赖包,说明确实将这个依赖包打进去了。
而之前打的包,是没有这个目录的。
至此,排查结束。
https://blog.csdn.net/Shangxingya/article/details/114810454
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
8 年互联网开发经验,擅长微服务、分布式、架构设计。目前在一家大型上市公司从事基础架构和性能优化工作。
InfoQ 签约作者、蓝桥签约作者、阿里云专家博主、 红人。
当前名称:记一次Maven打包后,第三方无法使用的排查记录
分享链接:http://www.shufengxianlan.com/qtweb/news5/349805.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联