Maven版本特性、传递依赖、命名规范在实际工作中的应用

文章目录

          • 前言
          • 问题概述
          • 问题解决
          • 被隐蔽的问题
            • 稳定版本本地不会自动更新
            • 稳定版本的变更没有变换版本号
            • 包路径和类路径规范命名
          • 最佳实践
            • 本地仓库是不可靠的
            • jar包变更更换版本号,自己依赖的包没必要传递下去
            • 自己写的类命名要规范

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好

问题概述

gitlab 上 cicd(持续集成) 打包,在代码没有变更的情况下,开始可以正常运行,后来就启动报错了,报错内容如下
本地代码是不会报错的

Apr 01, 2019 4:27:49 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'springServlet'
2019-04-01 16:27:49,625 ERROR org.springframework.web.servlet.DispatcherServlet [localhost-startStop-1] - APP[ymf-boss] - GUID[5b70655d2f6043cea9873c04be32328c] - TYPE[TASK] Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [resources]
Offending resource: class path resource [demo-dispatcher-servlet.xml]
	at org.springframework.beans.factory.parsing.FailFastProblemReporter.fatal(FailFastProblemReporter.java:59) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:68) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:55) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.NamespaceHandlerSupport.findParserForElement(NamespaceHandlerSupport.java:84) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:73) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1438) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1428) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:195) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:139) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:108) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180) ~[spring-beans-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130) ~[spring-context-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537) ~[spring-context-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:451) ~[spring-context-3.2.9.RELEASE.jar:3.2.9.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:443) ~[org.springframework.web.servlet-3.0.0.RELEASE.jar:3.0.0.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:459) ~[org.springframework.web.servlet-3.0.0.RELEASE.jar:3.0.0.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:340) ~[org.springframework.web.servlet-3.0.0.RELEASE.jar:3.0.0.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307) [org.springframework.web.servlet-3.0.0.RELEASE.jar:3.0.0.RELEASE]
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127) [org.springframework.web.servlet-3.0.0.RELEASE.jar:3.0.0.RELEASE]
	at javax.servlet.GenericServlet.init(GenericServlet.java:158) [servlet-api.jar:3.0.FR]
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284) [catalina.jar:7.0.54]
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197) [catalina.jar:7.0.54]
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087) [catalina.jar:7.0.54]
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5210) [catalina.jar:7.0.54]
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5493) [catalina.jar:7.0.54]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.54]
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) [catalina.jar:7.0.54]
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) [catalina.jar:7.0.54]
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632) [catalina.jar:7.0.54]
	at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1247) [catalina.jar:7.0.54]
	at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1898) [catalina.jar:7.0.54]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_172]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_172]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_172]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_172]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172]
Apr 01, 2019 4:27:49 PM org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
问题解决

说一下问题最终的解决方案:一般这种都是配置文件有问题,但是我的代码没有修改,而负责cicd的部门也明确表示他们没有修改,最后的原因也的确不是我们两个的原因。
由于我的项目依赖了一个jar包的稳定版本(这里暂时称其为jarA-1.0.jar),但是jarA-1.0.jar 其实更新了,由于Maven的机制导致我本地仓库并不会拉取相同稳定版本的jar,所以我的本地一直没有感知到这个更新
但是生产上感知到了
通过比对cicd 打包结果发现,正常启动的包比不能正常启动的包小,然后根据依赖树(mvn dependency:tree)分析,多出的包都是 jarA-1.0.jar传播依赖引入的
问题找到了,一个稳定版的jar包变更了自己的内容,而没有变更自己的版本号,间接影响到我的代码
那么问题就简化为去除多余的jar包
从新看报错,org.springframework.web.servlet-3.0.0.RELEASE.jar ,这个包在依赖树中居然不是Spring体系的jar,而是jarA-1.0.jar 自己内部从新写了一个和Spring很类似的包 org.springframework.web.servlet-3.0.0.RELEASE.jar
显然,这里出现了Maven jar包冲突的第二种,即同包路径、同名类,由于先出现而被认为是Spring的类
接着解决问题
在引用jarA-1.0.jar 下排除这个类即可 org.springframework.web.servlet-3.0.0.RELEASE.jar

<exclusion>                  
	<groupId>com.yeepay.posgroupId>
    <artifactId>org.springframework.web.servletartifactId>
exclusion>
被隐蔽的问题
稳定版本本地不会自动更新

Maven 的机制导致本地仓库版本落后,既不能在启动代码时发现问题,也不能通过依赖树直接发现问题所在

稳定版本的变更没有变换版本号

由于 jarA-1.0.jar 是公司内部jar包,而其在变更后没有变更版本号,导致引用这个包的项目间接受到类影响

包路径和类路径规范命名

由于依赖包命名不规范,直接导致其在运行时取代类Spring的类

最佳实践
本地仓库是不可靠的

遇到本地启动正常,测试环境启动不正常,可以尝试产出本地仓库,拉取最新的jar包

jar包变更更换版本号,自己依赖的包没必要传递下去

变更版本号就不说了
不要将自己依赖的包传递给下游,增加下面的配置

true
自己写的类命名要规范

Maven 命名是有规范的,一般是 com.公司官网.包功能,理论上都是唯一的

你可能感兴趣的:(maven)