SpringBoot项目,引了一个内部的工具包,竟然导致启动失败,报找不到freemarker Configuration类的一个属性,网上的解法都大同小异,最终用了自己的办法解决,花点时间记录下来,希望能帮助到别人。

关键词:SpringBoot,AutoConfiguration,freemarker,NoSuchFiledError

问题背景

最近在开发过程中由于要用到公司内部的一个工具类,所以添加了common-util.jar到工程的maven依赖中,功能开发完了,打算本地调试一下,但悲剧的是应用启动失败了。查看堆栈信息,并没有我新添加的代码,是Spring初始化失败了,堆栈信息如下:

初步分析

对照着堆栈来看,错误很明确,就是在运行时缺少freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS 这个field导致,但是怎么解决呢?度娘上基本都是下面这两种解决办法:

图片来源于https://www.cnblogs.com/geekdc/p/9243069.html

我并没有采用这两种办法,因为这并不是一个新搭建的工程,而且我这次也没有做过任何版本升级,唯一的可能就是引入的新jar包有问题。

再看异常堆栈

从堆栈来看是缺少了一个Field导致,那什么情况下会造成这种情况呢,我第一时间猜测应该是jar包冲突了,因为之前遇到过一次,有兴趣的可以看这里,我查看了新引入jar包内部的pom文件,确实是依赖了freemarker(2.3.16)的jar包,而且scope是compile,就这样,这个低版本的freemarker被传递依赖进来了,至于最终使用哪个,就由maven的仲裁机制决定了,很明显我这个工程最终用了老版本,所以导致运行时找不到Field,解决方案很简单,使用exclusion将老版本的freemarker排除就好了。一般故事到这儿就结束了,但是我这个人手贱,偏要看看项目以前依赖的freemarker是什么版本的,结果看完又不能按时睡觉了(题外话:白天老是这事那事,晚上才有时间写代码)。

意外收获

我使用mvn dependency:tree将所有依赖都输出到文本文件里,然后搜索freemarker,结果意外的发现居然没有依赖freemarker,这是什么情况,刚刚不是还j说ar包冲突了吗,难道是自我冲突了?

一时间没有了头绪,想百度都不知道关键字写什么。一般这个时候我会点根烟开始复盘,从头到尾反复看案发现场,总能发现蛛丝马迹。终于灵光一下,我脑子里闪过这么一段话“之前没有freemarker.jar的时候不报错,现在有了也应该不报错才对,除非SpringBoot具有自动发现功能,可以实现组件可插拔”,就这样,我尝试搜索“SpringBoot自动发现”,看看百度给我的结果:

我很自然的过滤了第二条搜索内容,因为我知道那不是我想要的,我内心想表述的其实是“自动转配、自动配置”。

根因分析

了解了自动装配的大概原理后,我梳理出了这次启动失败的根本原因,如下:

  1. SpringBoot启动的时候触发自动配置;
  2. spring-boot-autoconfigure-1.5.11.RELEASE.jar\META-INF\spring.factories里面是需要自动配置的Bean,里面就有FreeMarkerAutoConfiguration;
  3. 自动配置一般会有一些约束条件,满足条件才会自动配置,条件通过@Condition***这类注解来声明;
  4. FreeMarkerAutoConfiguration的自动配置约束条件为@ConditionalOnClass({freemarker.template.Configuration.class, FreeMarkerConfigurationFactory.class}),意味着只有freemarker.template.Configuration.class, FreeMarkerConfigurationFactory.class这两个类都存在的时候才会自动配置;
  5. 如果第四步满足条件,最终会触发FreeMarkerConfigurationFactory.newConfiguration这个方法,这个方法内部用到了Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS这个Field,它来源于freemarker.jar,就是堆栈中报NoSuchFiledError的主角;
  6. 如果第四步不满足条件,就不触发FreeMarkerAutoConfiguration的自动配置,进而不会用到Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS这个Field;

FreeMarkerConfigurationFactory来源于spring-context-support-4.3.15.RELEASE.jar,这个jar包之前就依赖了,而Configuration来源于freemarker.jar,是common-util.jar传递依赖进来的,所以正好满足了上面的第四步,进而触发了第五步,最终导致SpringBoot启动失败。

汇总解决办法

通过上面的一些分析,我认为这个问题一共有以下几种办法:

  1. 如果你的项目中没有用到freemarker的话可以禁用freemarker的自动配置,像初步分析那里提到的;
  2. 升级freemarker到高版本;
  3. 像我遇到的问题一样,确实不需要freemarker功能,可以将freemarker.jar排除;

总结

虽然是个很小的问题,但是解决过程确实让我收获不少,之前对于SpringBoot只停留在简单使用阶段,通过这次排查过程,也算是了解了SpringBoot自动配置的大体思想,这种可插拔的设计真的是非常巧妙。

如果觉得有用,请您点个推荐。

参考资料:

https://www.cnblogs.com/nijunyang/p/12051770.html

https://blog.csdn.net/ZYC88888/article/details/84245127

SpringBoot突报java.lang.NoSuchFieldError分析的更多相关文章

  1. springboot启动异常java.lang.NoSuchFieldError: DEFAULT_INCOMPATIBLE_IMPROVEMENTS

    解决办法一 yml或者Properties文件中配置 spring.freemarker.check-template-location=false 解决办法二 @SpringBootApplicat ...

  2. 【原创】大叔问题定位分享(2)spark任务一定几率报错java.lang.NoSuchFieldError: HIVE_MOVE_FILES_THREAD_COUNT

    最近用yarn cluster方式提交spark任务时,有时会报错,报错几率是40%,报错如下: 18/03/15 21:50:36 116 ERROR ApplicationMaster91: Us ...

  3. java.lang.NoSuchFieldError: VERSION_2_3_0 报错解决方案

    java.lang.NoSuchFieldError: VERSION_2_3_0 at org.apache.struts2.views.freemarker.FreemarkerManager.c ...

  4. springBoot集成Elasticsearch抛出Factory method 'restHighLevelClient' threw exception; nested exception is java.lang.NoSuchFieldError: IGNORE_DEPRECATIONS

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restHighLeve ...

  5. jenkins执行构建任务报错之java.lang.NoSuchFieldError: DEFAULT_USER_SETTINGS_FILE

    在执行创建工作空间时候,创建不成功,出现错误?? ......... java.lang.NoSuchFieldError: DEFAULT_USER_SETTINGS_FILE ......... ...

  6. java报错:Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE

    Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE at org.apache.http.conn.ss ...

  7. java.lang.NoSuchFieldError 异常原因

    一般都是因为 class 或 jar 包重复 导致的 , 也有可能是编译器的问题. 我碰到的问题是,在项目api 接口jar包里定义了一个Config.java,然后在业务层service 项目 的相 ...

  8. Java.lang.NoSuchFieldError: INSTANCE异常

    解决方案: java.lang.NoSuchFieldError: INSTANCE异常. 1.jar包重复了. 2.版本还不相同,如果包的版本不同也会报相应的错,不过一般情况自己导入的jar包主要看 ...

  9. java.lang.NoSuchFieldError: RAW_XML_FILE_HEADER,调用XWPFTemplate动态合并生成一个新的docx文档时报错

    在使用 org.apache.poi 对office文件  根据表单内容和已上次的附件 动态合并成一个新的文档时,本地调试完全ok 但是发布倒Linux环境上就老是报这个错误java.lang.NoS ...

随机推荐

  1. CAD安装错误1625:系统策略禁止这个安装,请与系统管理员联系。

    在安装Autodesk CAD/3DMAX/Maya/Revit/Inventor等的时候,出现“安装错误1625:系统策略禁止这个安装,请与系统管理员联系.”,或是Error 1625,同时还会提示 ...

  2. Java IO: 字符流的Piped和CharArray

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本章节将简要介绍管道与字符数组相关的reader和writer,主要涉及PipedReader.Pip ...

  3. 线程、volatile与synchronized、Lock

    目录 线程 1.概念: 2.线程生命周期: 3.线程调度 4.线程实现 4.1.实现方式 4.2.之间的区别: 5.线程安全 5.1.volatile与synchronized 5.1.synchro ...

  4. 详解js面向对象编程

    转自:http://segmentfault.com/a/1190000000713346 基本概念 ECMA关于对象的定义是:”无序属性的集合,其属性可以包含基本值.对象或者函数.“对象的每个属性或 ...

  5. 关于js中的比较时遇到的坑

    关于JavaScript中比较遇到的坑 当你的要比较数字的大小但是你的数字确是字符串时,就会出错比如说: console.log('5' > '6') // fasle consloe.log( ...

  6. POJ 2112 Optimal Milking 最短路 二分构图 网络流

    题意:有C头奶牛,K个挤奶站,每个挤奶器最多服务M头奶牛,奶牛和奶牛.奶牛和挤奶站.挤奶站和挤奶站之间都存在一定的距离.现在问满足所有的奶牛都能够被挤奶器服务到的情况下,行走距离的最远的奶牛的至少要走 ...

  7. 3名程序员被抓!开发“万能钥匙”APP,撬走3个亿

    来自:程序员头条 报道 又有 3 名程序员被抓!开发"万能钥匙"APP,撬走 3 亿! 前几天,据央视新闻报道,上海公安机关接到共享单车企业报案,随后破获了一起共享单车万能解锁 A ...

  8. PDCA理念融入软件测试

    PDCA理念融入软件测试    摘要:软件测试作为软件质量保障的重要手段,PDCA循环是全面质量管理所应遵循的科学程序.本文结合软件测试工作的特点,通过文档规范的方式,将PDCA的理念融入软件测试,提 ...

  9. 什么是AWVS

    什么是AWVS Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行安全漏洞,现已更新到10.(下 ...

  10. Bitstream or PCM?

    背景 提问 讨论精选 一 二 三 四 五 最后 电视上同轴输出的做法. 背景 USB通道下播放声音格式为AAC的视频文件,同轴输出设置为Auto,功放没有声音,设置成PCM,有声音. 提问 Auto/ ...