一、聚合工程

如图所示:

SpringCloud_CH3为聚合工程,eurekaclientarticleservice为被聚合工程。

聚合工程为一个maven工程:聚合类的pom.xml文件为:

<parent>标签为整个工程使用的springboot版本;<modules>标签中的值,每次新建一个Maven Modules,都会新增一个<module>标签。

聚合工程的pom.xml文件最重要的是定义项目用到的依赖以及版本,在被聚合工程根据需要引用(不需要版本号直接引用聚合工程中声明好的包),被聚合工程可以根据需要引用。聚合工程中仅仅是对包的声明,并没有真正引入 jar包。

如果在聚合工程中的pom文件中没有使用<dependencyManagement>,使用的是<dependencies></dependencies>

dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承,被动继承)

这样做的好处:统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,才能保证测试的和发布的是相同的成果,因此,在顶层pom中定义共同的依赖关系。同时可以避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个版本号时,只需要在dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。

在pom.xml文件中引入插件的方法及作用:

1)资源拷贝插件

在执行maven编译的时候,如果我把mybatis的mapper.xml和java类文件放在一起,会导致xml文件不会被复制过去,可能就会报mybatis的unbind异常

所以这个时候会用到这个插件:

配置需要拷贝的文件(注意:如果配置了复制src/main/java下面的配置文件,src/main/resources下面的配置文件也需要手动配置)

2)Maven给我们提供了一个插件: JDK编译插件,在工程pom文件中引入该插件可以使用指定版本的JDK,我们在 pom 文件中添加如下配置信息:

保存pom文件,等待工程自动更新完毕,注意:如果更新完毕后,工程仍然显示错误的红叉,我们需要手动更新工程,手动更新工程的操作步骤为:

在工程上右键,选择 “Maven-->Update Project...”在弹出的窗口中,勾选我们的工程,点击 "OK" 即可。

Maven中另外一种切换JDK版本的方式

除了上述使用插件切换JDK版本的方式,Maven还提供了另外一种常用的方式:在pom文件中通过<properties>元素的方式进行配置,配置方式是在 pom 文件中添加如下信息:

    <properties<maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties>

3)Maven中tomcat插件的配置使用

springboot内嵌tomcat可以不使用这个插件。

https://blog.csdn.net/qq_32534441/article/details/87028863

二、解决jar包冲突问题

简介:处理jar包依赖冲突,首先,对于多个jar包都引用同一jar包的情况,最好是在程序中显式定义被共同引用的jar包的依赖,来统一版本号,方便维护

如果A和B都依赖同一jar包C,可能会出现两种情况

1.A和B引用的C版本相同,这时按照pom定义顺序选择第一个即可,没有冲突问题,如果在项目的maven中显示定义了C依赖,那么用选择项目定义的依赖,反正version都一样,没有影响

2.A和B依赖的C版本不同,选择版本高的那个,这时会出现两种结果

(1) 高版本兼容低版本,所以不会出现问题

(2)高版本不兼容低版本,假如A依赖C2版本,B依赖C3版本,C3不兼容C2,maven选择了高版本C3,对A来说会出现问题

有3种解决方法

  [1]提升A版本,找到依赖C3的A版本

  [2]如果B版本也可依赖C2,在项目的maven中显示定义对C2的依赖,这样所有都使用C2版本

  [3]如果B版本不支持C2版本,只能降低B版本,找到依赖C2的B版本

  从功能性和可维护性考虑,高版本提供的功能更多,bug更少,优先考虑1

  再考虑2

  最后考虑3

搞懂这7个Maven问题,带你吊打面试官!

jar包产生冲突的原因:

在以上依赖关系中项目除了会引入B、C还会引入X、Y、M的依赖包,但是如果B依赖的X版本会1.0而C依赖的X版本为2.0时,那最后项目使用的到底是X的1.0版本还是2.0版本就无法确定了。这是就要看ClassLoader的加载顺序,假设ClassLoader先加载1.0版本那就不会加载2.0版本,反之同理
使用mvn -Dverbose dependency:tree排查冲突

D:\code\spring-cloud-master\spring-cloud-master\Spring-Cloud-Book-Code-2\ch-2\SpringCloud_CH3>mvn dependency:tree -Dverbose -Dincludes=commons-collections
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for esshop:esshop:war:0.0.1-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 621,
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building esshop Maven Webapp 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ esshop ---
[INFO] esshop:esshop:war:0.0.1-SNAPSHOT
[INFO] +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] +- org.hibernate:hibernate:jar:3.2.2.ga:compile
[INFO] |  \- (commons-collections:commons-collections:jar:2.1.1:compile - omitted for conflict with 3.2.1)
[INFO] +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile
[INFO] |  \- org.hibernate:hibernate-core:jar:3.3.0.SP1:compile
[INFO] |     \- (commons-collections:commons-collections:jar:3.1:compile - omitted for conflict with 3.2.1)
[INFO] +- org.springframework.security:spring-security-core:jar:2.0.4:compile
[INFO] |  \- (commons-collections:commons-collections:jar:3.2:compile - omitted for conflict with 3.2.1)
[INFO] +- org.apache.velocity:velocity:jar:1.5:compile
[INFO] |  \- (commons-collections:commons-collections:jar:3.1:compile - omitted for conflict with 3.2.1)
[INFO] \- net.sf.json-lib:json-lib:jar:jdk15:2.4:compile
[INFO]    \- (commons-collections:commons-collections:jar:3.2.1:compile - omitted for duplicate)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

这里需要总结一下什么是版本冲突、重复依赖但不影响工程启动的。

omitted for duplicate  为重复依赖但版本号一致的。

omitted for conflict with *** 为版本号冲突的。

若发现有jar包冲突则使用<exclusions><exclusion></exclusion></exclusions>将多余的jar包去掉。

举个例子:

但显示出来的东西太多,头晕目眩,有没有好法呢?当然有了,加上Dincludes或者Dexcludes说出你喜欢或讨厌,dependency:tree就会帮你过滤出来:
引用
Dincludes=org.springframework:spring-tx
过滤串使用groupId:artifactId:version的方式进行过滤,可以不写全啦,如:

mvn dependency:tree -Dverbose -Dincludes=asm:asm

就会出来asm依赖包的分析信息:

[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ ridge-test ---
[INFO] com.ridge:ridge-test:jar:1.0.2-SNAPSHOT
[INFO] +- asm:asm:jar:3.2:compile
[INFO] \- org.unitils:unitils-dbmaintainer:jar:3.3:compile
[INFO]    \- org.hibernate:hibernate:jar:3.2.5.ga:compile
[INFO]       +- cglib:cglib:jar:2.1_3:compile
[INFO]       |  \- (asm:asm:jar:1.5.3:compile - omitted for conflict with 3.2)
[INFO]       \- (asm:asm:jar:1.5.3:compile - omitted for conflict with 3.2)
[INFO] ------------------------------------------------------------------------

对asm有依赖有一个直接的依赖(asm:asm:jar:3.2)还有一个传递进入的依赖(asm:asm:jar:1.5.3)

承上,假设我们不希望asm:asm:jar:1.5.3出现,根据分析,我们知道它是经由org.unitils:unitils-dbmaintainer:jar:3.3引入的,那么在pom.xml中找到这个依赖,做其它的调整:

   <dependency>  <groupId>org.unitils</groupId>  <artifactId>unitils-dbmaintainer</artifactId>  <version>${unitils.version}</version>  <exclusions>  <exclusion>  <artifactId>dbunit</artifactId>  <groupId>org.dbunit</groupId>  </exclusion>  <!-- 这个就是我们要加的片断 -->  <exclusion>  <artifactId>asm</artifactId>  <groupId>asm</groupId>  </exclusion>  </exclusions>  </dependency>  

再分析一下,你可以看到传递依赖没有了:

[INFO]  [INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ ridge-test ---  [INFO] com.ridge:ridge-test:jar:1.0.2-SNAPSHOT  [INFO] \- asm:asm:jar:3.2:compile  [INFO] ------------------------------------------------------------------------  [INFO] BUILD SUCCESS

有时,你以为解决了,但是偏偏还是报类包冲突(典型症状是java.lang.ClassNotFoundException或Method不兼容等异常),这时你可以设置一个断点,在断点处通过下面这个我做的工具类来查看Class所来源的JAR包:

public class ClassLocationUtils {public static String where(final Class clazz) {if (clazz == null) {throw new IllegalArgumentException("null input: cls");}URL result = null;final String clazzAsResource = clazz.getName().replace('.', '/').concat(".class");final ProtectionDomain protectionDomain = clazz.getProtectionDomain();if (protectionDomain != null) {final CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource != null) result = codeSource.getLocation();if (result != null) {if ("file".equals(result.getProtocol())) {try {if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) {result = new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clazzAsResource));} else if (new File(result.getFile()).isDirectory()) {result = new URL(result, clazzAsResource);}} catch (MalformedURLException ignore) {}}}}if (result == null) {final ClassLoader clsLoader = clazz.getClassLoader();result = clsLoader != null ? clsLoader.getResource(clazzAsResource) : ClassLoader.getSystemResource(clazzAsResource);}return result.toString();}
}

随便写一个测试,设置好断点,在执行到断点处按alt+F8动态执行代码(intelij idea),假设我们输入:
Java代码  收藏代码

ClassLocationUtils.where(org.objectweb.asm.ClassVisitor.class)

即可马上查出类对应的JAR了:

这就是org.objectweb.asm.ClassVisitor类在运行期对应的JAR包,如果这个JAR包版本不是你期望你,就说明是你的IDE缓存造成的,这时建议你Reimport一下maven列表就可以了,如下所示(idea):

Reimport一下,IDE会强制根据新的pom.xml设置重新分析并加载依赖类包,以得到和pom.xml设置相同的依赖。(这一步非常重要哦,经常项目组pom.xml是相同的,但是就是有些人可以运行,有些人不能运行,俗称人品问题,其实都是IDE的缓存造成的了
idea清除缓存,为了提高效率不建议采用reimport重新起开启项目的方式,建议采用idea自带的功能,File->Invalidate Caches 功能直接完成清除idea cache

三、使用mvn helper插件

1)Maven Helper插件安装:

打开pom文件,在左下角的tab页的Dependency Analyzer(安装成功Maven Helper才会出现这个tab页)。

Conflicts  为筛选出jar包重复或者版本冲突;

All Dependencies as List(列表形式查看所有依赖)

All Dependencies as Tree(树结构查看所有依赖)

点击筛选出的包右键

点击Exclude,实现的工程跟<exclusion>是一样的,如果出现问题,可以直接在pom文件界面ctrl+z。

附加:

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的动作。

system

从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。

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。

下面是一张nexus画的图。

Maven构建聚合工程以及jar包冲突解决使用总结相关推荐

  1. Maven的传递性依赖及其jar包冲突解决

    一.Maven简介 Maven是一个跨平台的项目管理工具.作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理. 二.Maven的依赖管理 1. ...

  2. Jar包冲突解决方法 Unknown lifecycle phase mvn Eclipse中执行maven命令

    1.如下图,右击需要执行maven命令的工程,选择"Debug As"或"Run As",再选择"Maven build..." 进行如上操 ...

  3. IntelliJ IDEA Maven jar包冲突解决,快速发现jar包冲突

    IntelliJ IDEA 自带的Diagrams 去查看jar包冲突相当费劲 ~ ,安装个插件即可快速解决该问题 打开Settings,搜索maven helper,并安装 安装完成后,直接打开po ...

  4. Jar包冲突解决方法

    前言 对于Jar包冲突问题,我们开发人员经常都会有碰到,当我们使用一些jar包中的类.方法等,或者有时遇到一些日志系统的问题(参考另一篇文章Jar包冲突导致的日志问题),我们会遇到ClassNotFo ...

  5. jar包冲突解决思路

    工作中,难免会因为各种原因需要对项目jar包进行升级,一升级,就会碰到各种jar包冲突问题,这时候就需要我们能很快定位冲突的位置,以及如何快速调整依赖. 首先,我们通常说的jar包冲突到底是指什么? ...

  6. maven工程servlet实例之jar包冲突解决

    依赖范围 A依赖B,需要在A的pom.xml文件中添加B的坐标,添加坐标时需要指定依赖范围,依赖范围包括: compile:编译范围,指A在编译时依赖B,此范围为默认依赖范围.编译范围的依赖会用在编译 ...

  7. Idea启动jar包冲突 解决

    启动报错 java.lang.NoClassDefFoundError: cn/hutool/core/util/NetUtil 查看了原因是找hutool-core-10.0.0.jar 下,但是它 ...

  8. 使用maven构建项目候,jar包错误的解决办法

    1.删除架包,重新下载,右键项目点击"run as"中的"maven clean",然后再maven中找到Update Project 2.可以在代码中,把鼠标 ...

  9. NoSuchMethodError 错误——包冲突解决办法

    包冲突的解决办法 注意所有关于maven的pom文件的改动,最后都要reimport一下,IDE会强制根据新的pom.xml设置重新分析并加载依赖类包,以得到和pom.xml设置相同的依赖.(这一步非 ...

最新文章

  1. ftp 信息服务器日常维护,Web Ftp Mail服务器的日常管理与维护
  2. STL priority_queue sort 自定义比较终极模板
  3. Alternating Least Squares(ASL) for Implicit Feedback Datasets的数学推导以及用Python实现
  4. gvim在windows下中文乱码的终极解决方案
  5. cesium鼠标控制键盘_Cesium中级教程3 - Camera - 相机(摄像机)
  6. 计算机操作系统读者和写者模型的简单介绍以及思考
  7. chage 用户密码管理
  8. 见过一个一个拉新地推没见过这么多一起推
  9. centos 6.7 ssh 免密码
  10. 我的成长笔记20210324(进度把控)
  11. PyTorch学习—19.模型的加载与保存(序列化与反序列化)
  12. Jersey学习笔记
  13. php排序orderby,云优CMS如何按orderby排序上一条下一条信息
  14. java 图片拼接_Java实现图片拼接
  15. java开发用固态还是机械硬盘_搭载固态硬盘的服务器究竟比搭机械硬盘快多少?...
  16. Latex 操作(3) beamer(PPT)
  17. 上海中专计算机学什么,职校毕业生自述:只有中专文凭,靠什么落户上海
  18. 网络流量分析 NetFlow是什么 详解 科普 ~互联网业务流量监测技术的应用和设计---perfect
  19. Vim内同时对多行增加或删除相同的内容
  20. 【2021.12.25】ctf逆向中常见加密算法和编码识别

热门文章

  1. 蓝牙4.0BLE之iBeacon 在ios上的应用-室内定位 [原创,多图,视频]
  2. 推荐最新网赚付费项目,让你实现半年赚20万!
  3. 【分布式数据网格】如何超越单片数据湖迁移到分布式数据网格
  4. dio设置自定义post请求_Flutter 使用dio来发起网络请求以及Cookie管理
  5. STM32 脉宽调制 (PWM):控制直流风扇的速度
  6. word方框中打对勾的方法
  7. 怎么使在一台电脑上同时双开一个程序
  8. IBMMQ linux版安装(五)
  9. opencv-图像金字塔
  10. 【C++之函数】引用符号、内联函数inline、函数重载