Maven的包管理

java的包管理简单学习记录:

jvm的工作被设计的相当简单:

执行一个类的字节码,若碰到了新的类便加载它,在类路径(-classpath /-cp)里可以找到类,类的全限定类名(目录层级路径)可以唯一地确定了一个类

包就是把许多类放在一起打包的压缩包。

 

maven的包管理

在运行程序时,maven会从中央仓库自动帮你下载依赖的包,每个项目所依赖的包写在该项目中的pom.xml文件中,通常就是

pom.xml文件中如下面这种的dependency中的字段,通过groupId和artifactId可以确定第三方包中的唯一位置,加上版本号便可以唯一确定所需的包

 
<dependency>
    <groupId>org.kohsuke</groupId>  <!-- 一般是组织名 -->
    <artifactId>github-api</artifactId> <!-- 一般是项目的模块名 -->
    <version>1.95</version> <!-- 版本号 -->
    <scope>test</scope><!-- 和构建项目的生命周期相关 -->
</dependency>

pom.xml文件中的scope语句可以指定依赖只在scope中生效,最常见的是用于在

test中运行test所需类
即 <scope> test<scope> 第三方依赖只在test中可见
若写成<scope>compile<scope>则在main,test中都可见
若写成<scope>provided<scope>:在编译时可见,但运行时不可见(因为有时候别人会提供)

 

mvn包冲突的发生:

运行程序,抛出如下异常时,即发生了包冲突:

AbstractMethodError
NoClassDefFoundError
ClassNotFoundException
LinkageError

 

mvn包冲突发生的原因:

正常情况下,maven会根据你文件中所导入的包自动去帮你寻找你的项目的依赖库,
以及依赖文件的依赖库
一个比较常见的包冲突是你的项目里的不同文件依赖了一个相同的库,这个库在
不同文件里的版本还不相同,此时在Classpath 上就出现了多个同名类(他们只是版本不同)
同时出现在Classpath中,


当出现同名的库时,maven选用库的原则是
优先选择离项目最近的那个库(即层级结构最短的那个库)
这种做法有时可以解决掉问题,但有时却会发生问题(即选择了那个我不想用的旧库,而我新版本
的新库由于类名相同但可能层级目录稍远却被丢弃了),
此时就需要人工干预

mvn解决包冲突:

方法一:根据依赖树与给出的依赖库寻找差异

在idea的maven 下面,idea会列出当前项目所依赖的库,你可以直接查看你所依赖的
的文件,当依赖库较少时,你可以直接通过肉眼查看是否有冲突发生,
当然也可以在idea的终端窗口运行

mvn dependenty:tree 

查看项目所列出的依赖库,但是使用mvn dependenty:tree列出的是冲突
解决后的依赖库,它自动丢弃了发生冲突的那个库中的一个库,这里也就是运行异常发生的原因
你可以对比maven中列出的依赖(冲突解决前的依赖)和
依赖树中列出的依赖(冲突解决后的依赖)的差异
寻找是哪里冲突了

 

方法二:使用maven helper插件

从IDEA的Plugins中下载maven helper插件,重启终端即可使用
在pom.xml文件内容下,会多出一个dependency analyzer窗口
窗口内会自动列出当前冲突的文件,右键即可查看依赖处源码或是将该库排除

 

posted @ 2020-03-06 13:30  pathjh  阅读(978)  评论(0编辑  收藏  举报