当前位置: 首页 > 科技观察

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

时间:2023-03-22 16:22:52 科技观察

大家好,我是悟空。本文主要内容如下:目录前言最近遇到一个需求:写一个工具类JAR包,然后提供给第三方调用里面的类方法。(前提:第三方不能共享我们项目的私有仓库)这期间遇到了一些问题:第三方引入JAR包后无法导入。第三方引入JAR包后,JAR包中的其他依赖缺失。本文为记录,希望对其他朋友有所帮助。由于本文涉及Maven,这里总结一下Maven的常用命令。熟悉Maven命令的同学可以跳过本节。一、Maven常用命令当我们创建一个Maven项目时,Maven命令会自动出现在IDEA开发工具的右侧。Maven操作可以用鼠标双击运行,也可以通过命令行执行。下面介绍这些命令的区别。clean(常用)删除项目路径下的目标文件,但不删除本地maven仓库生成的JAR文件。validate验证项目的正确性以及所需信息是否完整。编译编译。在你的项目路径下会生成一个target目录,里面有一个classes文件夹,里面全是生成的class文件。test执行单元测试。package(常用)将项目文件打包成指定的格式,如JAR、WAR等(查看你项目的pom文件,其中packaging标签用于指定打包类型)。该命令会在你的项目路径下创建一个target目录,并具有compile命令的功能进行编译,并会在target目录下生成项目的jar/war文件。如果项目a依赖于项目b,那么在打包项目b时,只会打包到项目b的target下,编译项目a时会报错,因为找不到依赖的项目b,说明项目a在本地仓库中没有找到它所依赖的b项目,此时使用install命令。verify验证主要是检查包是否有效,是否符合标准。install(常用)将包安装到本地仓库,以便其他项目可以依赖它。该命令包含package命令功能,不仅会在项目路径下生成class文件和jar包,还会在你本地的maven仓库中生成jar文件供其他项目使用(如果你没有搭建maven本地仓库,一般在user/.m2目录下。如果a项目依赖b项目,那么在安装b项目时,会在本地仓库中同时生成pom文件和jar文件,解决了上述package打包错误的问题)。构建构建。功能和compile类似,不同的是编译整个工程。与compile的区别和特点:是对整个工程进行彻底的重新编译,不管是否编译过。构建过程往往会生成一个发布包,这取决于IDE的配置。build在实际中很少用到,因为开发的时候基本不用,生产的时候一般都是用ANT之类的工具来release。构建需要很长时间,因为它需要编译所有内容并执行打包等额外工作。site生成项目的站点文档。部署(常见)部署。将jar包部署到远程仓库,一般是私有仓库。并包括安装命令的功能。2.打包后无法导入?下面介绍一下我用常规打包方式遇到的问题。我通过IDEA工具创建了一个SpringBoot项目,然后pom.xml文件中会自动引入一个打包插件,如下图:然后我执行mavenpackage命令,会生成一个JAR包在项目的目标目录中。如下图所示:然后我做了以下操作:我复制了JAR包并发送给了第三方。让第三方copy到自己本地的项目中。这里在项目的根目录下创建一个libs目录,然后将jar包放到libs目录下。让第三方在pom依赖中引入这个依赖包。范围指定为system,即导入指定路径下的jar包(systemPath配置)。这样做似乎没有问题,但是当我们导入这个JAR包下的类时,就会报错。如下图:很奇怪,为什么这里会报错??首先检查是否导入了JAR包。如下图,可以看到确实导入正确,没有报错。通过研究发现,该打包插件产生的JAR包是用来执行的,即JAR包可以通过java-jar命令运行,不能被第三方引用。解决方法:换一个打包插件maven-compiler-plugin。org.apache.maven.pluginsmaven-compiler-plugin3.8.11.81.8UTF-8再次打包发送给第三方,发现导入不报错。但是又报错了,我们往下看。3.缺少其他Jar包依赖?报错信息如下:java.lang.NoClassDefFoundError:org/apache/commons/codec/binary/Base64通过这些信息可以想到我提供的JAR包中是否引入了commons-codec依赖,JAR包文件不包含此依赖项。查看这个JAR文件的大小,只有14KB,而commons-codec的包大小是339KB,说明这个JAR包不包含common-codec的依赖。解决方法:将其他依赖包放入这个JAR包中(推荐)。第三方自行引入其他依赖包。(第三方比较麻烦,需要第三方一一介绍)那怎么把依赖包打包到这个JAR包里呢?这里还介绍了一个打包插件:maven-assembly-plugin,如下图。(省略部分标签)org.apache.maven.pluginsmaven-assembly-plugin3.0.0org.apache.maven.pluginsmaven-assembly-plugin2.4.1jar-with-dependencies然后使用插件打包方式:assembly:assembly然后目标目录下会多出一个包,后缀为:jar-with-dependenciesdecryption-0.0.1-SNAPSHOT-jar-with-dependencies.jar这个包比较大,有15.4M,发给第三方重新引入后,就不会再报错了。让我们来看看这个包里有什么。在META-INF/maven目录下可以看到commons-codec依赖包,说明确实已经进入了这个依赖包。之前玩的包没有这个目录。至此,调查结束。参考资料:https://blog.csdn.net/Shangxingya/article/details/114810454https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html关于我8年互联网开发经验,擅长微服务、分布式、架构设计。目前在一家大型上市公司从事基础设施和性能优化工作。InfoQ签约作者,蓝桥签约作者,阿里云专家博主,名人。