各命令作用
https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
validate
- validate the project is correct and all necessary information is availablecompile
- compile the source code of the projecttest
- test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployedpackage
- take the compiled code and package it in its distributable format, such as a JAR.verify
- run any checks on results of integration tests to ensure quality criteria are metinstall
- install the package into the local repository, for use as a dependency in other projects locallydeploy
- done in the build environment, copies the final package to the remote repository for sharing with other developers and projects.maven install
install的作用是把本地工程打成jar发布到本地仓库。
maven获取依赖的步骤是先找寻本地仓库,再找寻远程仓库。
一个实例的例子:
Quartz clone下来后,本地首次跑测试用例时报错。提示图中框起来的类找不到。该类位于另一个Bundle下(quartz-stubs)。
依赖关系在pom文件中有管理
所以,需要首先执行maven install, 将各个Bundle打成jar包到本地仓库。weblogic bundle就能找到stubs中的类了。
注意:当maven install时会编译测试类,测试类可能编译出错导致install失败。此时可以跳过测试类:mvn install -Dmaven.test.skip=true 这个命令总是记不住,记忆方法:maven.test为宾语,skip为谓语,宾语在前面,谓语在后面,这在英语中叫宾语前置
各scope作用
https://blog.csdn.net/u011191463/article/details/68066656
compile
默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去。
test
scope为test表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。比较典型的如junit。
runntime
runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中,和compile区别不是很大。比较常见的如JSR×××的实现,对应的API jar是compile的,具体实现是runtime的,compile只需要知道接口就足够了。Oracle jdbc驱动架包就是一个很好的例子,一般scope为runntime。另外runntime的依赖通常和optional搭配使用,optional为true。我可以用A实现,也可以用B实现。
provided
provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。
scope的依赖传递
A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?答案是:
当C是test或者provided时,C直接被丢弃,A不依赖C;
否则A依赖C,C的scope继承于B的scope。
如果更新了一个sdk版本号遇到拉不到包的情况
尝试 删除本地仓库的历史sdk,并重新再root pom执行 mvn package
打包方式都有哪些
- 打成一个完整的jar包,包含所有依赖。比如:guava包,就包含所有实现以及相关依赖的实现。 比如打一个mapreduce的jar包,也需要包含所有相关依赖。
如上:相关实现和依赖的实现都会jar里。
方式:添加plugin
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass></mainClass> // jar命令执行时,默认按这个类作为入口函数
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 打一个pom定义,不包含依赖。比如:内部系统开发打的二方包,只会包含当前的module的代码(只有接口定义)以及其pom文件。对方引用时,会自行根据pom依赖去仓库拉。这个时候就有可能出现jar包冲突的问题。比如对方和引用的二方包里都有某个依赖的引用,并且版本不同。可能会冲突,这个时候就需要排包(exclude二方包里的相关依赖,使用自己的依赖)
问题
解决IntelliJ Compilation Error zip END header not found
https://blog.csdn.net/qq_40875308/article/details/108503061
如何解决jar包冲突
场景:log包冲突,打印不出日志
工程里引入了一个jar后,发现机器日志不能打印出来了。排查启动报错日志,发现stderr能打印,也就是控制台类型的能打印出来,但log4j日志框架的打印不出来。
解决方法:
- 由于不是自己引入的jar包,一开始不确定什么原因,按上面报错日志的红框部分排查jar包冲突问题
https://blog.csdn.net/CoreyXuu/article/details/108705398
原因:一个接口,被两个实现类实现了。然后,程序在启动获取时,只想获取一个。
这个接口是:org.apache.logging.slf4j.Log4jLoggerFactory
两个实现类分别是:
查看:idea中 command + O 查看;然后输入StaticLoggerBinder,即可定位到两个实现类。然后在实现类中,按alt + f1 再回车,便可以定位到引用的包。
定位两个包如下:
和:
发现两个实现类,都是maven替我们引入的,所以需要在maven的配置文件上下手,排除一个。
如何排除呢?要找到这个jar包根源是哪个pom引入进来的。
https://blog.csdn.net/ygy162/article/details/106339708
命令行方式:
在具体bundle(一般为启动bundle,比如start 或者bootstrap)下,执行:
mvn dependency:tree -Dverbose -Dincludes=org.apache.logging.log4j:log4j-slf4j-impl
分析结果
idea图形化方式
1导出整体的依赖图
2搜索jar包比如(mybaits)
3一层一层网上找出依赖
但最终还没解决日志打印不出的问题
同事排查出来,增加了一个log4j.xml就好了。原工程里是log4j2-spring.xml。 不知道什么原因。同事百度出来的,这也算是排查问题的经验比较强吧,或百度能力比较强。我整了两三个小时没搞定。