近期公司内部使用jenkins进行了升级设置中也增加了JDK8的环境选项
使用jdk8 来lanch maven,执行job构建时发现部分job无法正常通过编译,报错为:
初步排查是jdk8中不符合doclint规范的javadoc无法正常生成
将job设置中jdk切换成低版本jdk7后繼续构建发现以下异常:
使用博客的方法来查看机器jenkins版本情况
显然,本机运行jenkins是需要jdk8支持的所以这个问题不能简单粗暴的通过降低jdk版本來解决。
转向搜索如何禁用jdk8 doclint的相关问题stackoverflow的问题解答中给出了三种解决办法:
内部jenkins主要是测试部署和CI集成使用,线上环境均使用jdk7运行为减少对源码的修改,这里选择第三种方案即修改job build pom.xml的goals设置为:
设置成功后,重新构建job,项目可以使用jdk8 正常构建。
在测试环境B上执行相关测试时client连接到server后未收到任何响应,客户端长时间处于等待状态打开debug日志,发现相關异常信息
NoSuchMethodError报错信息比较异常因为项目正常编译通过了,而且本地debug时能正常执行。
google 搜索发现简书博客记录了相同的异常信息,结论為jdk8高版本编译低版本执行的问题。
对应到本项目该项目对应的job在jenkins升级之后执行过部署操作,使用的jdk 确为JDK8导致基于JDK 8的bootstrap class编译而成的keySet()方法,其返回值是JDK 8中ConcurrentHashMap$KeySetView这个新增内部类在jdk7上执行时加载不到该新方法而抛出异常,而开发代码中未捕到该异常并做异常处理导致服务端逻辑無法走到response client这一步,又client端超时时间设置比较长所以观察到client一直处于等待状态,服务端一直未响应
所以,导致异常现象出现的原因其实有兩个第一是高版本编译低版本运行的问题,第二是开发代码异常处理不到位第一个问题是根源,所以本文关注第一个问题
值得关注嘚一点是,其实项目中maven compiler 中指定了source 和 target的编译级别都是jdk7的但正如博客中所说,source参数指的是源代码级别的语法兼容而target参数指的是生成release版本的兼容性的class文件,降低版本号来编译会导致生成class文件被标识为较低版本以供指定的JVM加载,但基于bootstrap class 编译的class文件依然是基于默认jdk的无法保证運行时的正确性。
这点在apache maven官网文档 中有详细说明
在博客中,作者给出了两种解决办法:
第二种方案对代码有侵入直接放弃掉。第┅种方法对单个类的示例操作不能直接使用于maven compiler项目中。于是还是转向官网寻找解决办法
还好,apache maven 官网文档很直接地给出了两种解决方案:
指定的javac仅作用于maven compiler插件,不作用于其他插件 javac_path可以写成硬编碼,不过建议最好做成可配置项具体如下:
个人更倾向方案1
具体到当前的场景,解决方法为: