项目总结之maven冲突

作者: Java面试官 | 来源:发表于2017-05-25 02:01 被阅读3277次

描述

今天遇见了一个相对而言有点奇葩的问题,一个pom文件的依赖配置,如果是以下配置的话:

image.png

则发布成功,一点问题都没有,如果是以下配置的话:

image.png

则会抛出以下异常:

java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252) [na:1.7.0_17]
    at java.util.concurrent.FutureTask.get(FutureTask.java:111) [na:1.7.0_17]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:939) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:872) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [na:1.7.0_17]
    at java.util.concurrent.FutureTask.run(FutureTask.java:166) [na:1.7.0_17]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_17]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_17]
    at java.lang.Thread.run(Thread.java:722) [na:1.7.0_17]
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.14.jar:8.5.14]
    ... 7 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [Pipeline[StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5117) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.14.jar:8.5.14]
    ... 7 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.authenticator.NonLoginAuthenticator[]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:182) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.14.jar:8.5.14]
    ... 9 common frames omitted
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
    at org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1141) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.14.jar:8.5.14]
    ... 11 common frames omitted

通过师兄的指点加上多方查证了解到是依赖冲突了,现在具体描述下查证的过程:

image.png

由以上的堆栈异常可以看出,在加载依赖的时候javax.servlet.ServletContext少了个getVirtualServerName()函数,于是我定位到tomcat-embed-core-8.5.14.jar这个依赖下

image.png

发现tomcat-embed-core-8.5.14.jar这个依赖下的ServletContext是有getVirtualServerName函数的,那么为什么这里还提示找不到呢?我猜测是因为jar包冲突,在加载tomcat-embed-core-8.5.14.jar下的ServletContext之前就先加载了其他jar包的ServletContext了,于是查找了相关的依赖,在:

image.png

找到了ServletContext接口,确实是没有getVirtualServerName这个函数,跟我上面的预想基本一致。


那么问题来了,为什么反过来就可以了?

于是我又去谷歌了,得知以下两个知识点:
1、依赖路径最短优先原则
一个项目Demo依赖了两个jar包,其中A-B-C-X(1.0) , A-D-X(2.0)。由于X(2.0)路径最短,所以项目使用的是X(2.0)。
2、pom文件中声明顺序优先
如果A-B-X(1.0) ,A-C-X(2.0) 这样的路径长度一样怎么办呢?这样的情况下,maven会根据pom文件声明的顺序加载,如果先声明了B,后声明了C,那就最后的依赖就会是X(1.0)。

于是我总结到,应该是依赖路径长短一样,导致跟pom文件中声明的顺序有关。

相信很多人和我一样,在犹豫如何查找依赖路径,以下推荐一种:

使用Intellij idea,想看看它的maven依赖图,打开的pom.xml文件,在pom文件内容上右键Diagrams–Show Dependencies,就可以看到了。如:

image.png

由图也可以看出,依赖路径也确实一样。

总结:遇见问题要大胆的去请教,通过系统反馈的异常深入的研究问题出在哪里,而不只是解决了问题就好!


Note:发布的这些文章全都是自己边学边总结的,难免有纰漏,如果发现有不足的地方,希望可以指出来,一起学习咯,么么哒。
开源爱好者,相信开源的力量必将改变世界:
** osc :** https://git.oschina.net/xi_fan

相关文章

  • 项目总结之maven冲突

    描述 今天遇见了一个相对而言有点奇葩的问题,一个pom文件的依赖配置,如果是以下配置的话: 则发布成功,一点问题都...

  • Maven基础

    Maven介绍 可以管理项目jar包的构建,解决jar包之间的冲突;可以对项目进行管理,比如项目打包等,maven...

  • Maven解决jar包冲突

    一、Maven中jar包冲突产生原因 MAVEN项目运行中如果报如下错误: Caused by:java.lang...

  • Maven 相关概念总结

    Maven 相关概念总结 构建原理 Maven 构建项目的规则是约定大于配置,约定指 Maven 提倡项目应遵循标...

  • maven包冲突及解决思路

    maven包冲突 前情提要:原项目为spring项目,现需要改为Springboot项目。将pom依赖copy过来...

  • 如何解决maven冲突?

    如何解决maven冲突 maven冲突分两类:显示冲突和隐式冲突。 显示冲突:maven文件中直接以

  • 3.Maven - 配置tomcat自动发布

    参考: Maven创建servlet webapp项目并在Tomcat上部署 Maven学习总结(11)——Mav...

  • guava版本冲突解决办法--maven项目

    maven项目解决jar包冲突的四种方式 guava版本冲突解决办法 ------场景:grpc-all 和 es...

  • Maven解决依赖冲突

    maven依赖冲突以及解决方法 什么是依赖冲突 依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类...

  • maven踩坑-解决依赖冲突

    maven的主要功能是:项目构建,项目依赖管理,软件项目持续集成,版本管理,项目站点描述信息管理 依赖冲突产生的原...

网友评论

    本文标题:项目总结之maven冲突

    本文链接:https://www.haomeiwen.com/subject/wndaxxtx.html