背景

之前做的小工具一个jsqlparse+git做的小工具帮我节省时间摸鱼昨天突然停止工作,看了下jvm并没有退出,但是看日志确实有不少Error输出,虽说是一个普通的NPE,但是分析了一下却疑点重重,所以花点时间来一探究竟,最终又掌握一个jvm知识点,还是比较有意思。

错误现场

以下是示例代码,为了说明问题做了简化,大概意思是使用CCJSqlParserUtil去解析一段sql语句,如果解析出错了以后从JSQLParserException.getMessage()中利用正则提取出具体的行和列。

Statements statements = null;
Set<Integer> sqlSet = new HashSet<>();
String sql ="alter table test add column varchra(4)";
try {
statements = CCJSqlParserUtil.parseStatements(sql);
} catch (JSQLParserException e) {
Pattern pattern = Pattern.compile("line (\\d+), column (\\d+)");
String message = e.getMessage();
Matcher m = pattern.matcher(message);
int line = -1;
int column = -1;
while(m.find()){
int groupCount = m.groupCount();
if(groupCount > 0){
line = Integer.parseInt(m.group(1));
column = Integer.parseInt(m.group(2));
break;
}
}
}

上面那个错误sql解析出错了以后的异常信息如下:

Encountered unexpected token: "varchra" <S_IDENTIFIER>
at line 1, column 29. Was expecting: "COMMENT"

那个诡异的NPE 栈如下:

java.lang.NullPointerException: null
at java.util.regex.Matcher.getTextLength(Matcher.java:1283)
at java.util.regex.Matcher.reset(Matcher.java:309)
at java.util.regex.Matcher.<init>(Matcher.java:229)
at java.util.regex.Pattern.matcher(Pattern.java:1093)
at xxx.ScriptUtil.sqlParse(ScriptUtil.java:41)

很显然是e.getMessage()返回了null导致pattern.matcher(message)失败,但是e.getMessage()理论上来讲不会是null,有点玄学的味道,一般解决玄学的首要方法是重启大法(个人观点,欢迎来喷,哈哈)。果然,重启了以后竟然好了,好奇心一下就被激发了。

错误原因

网上一通搜索确实类似的案例不少,大概的意思是jvm对异常处理这块做了优化,如果频繁抛出某种异常jvm会对这些异常做一些处理,使用JVM初始化的时候创建的那些异常对象来替代本应该新建的异常对象,因此这些异常栈和Message是空的,这一特性受OmitStackTraceInFastThrow参数的管控,可以通过-XX:+OmitStackTraceInFastThrow开启,或者-XX:-OmitStackTraceInFastThrow关闭,看完确实恍然大悟,但是并没有找到官方的一些说明,还是心有不甘,决定在openjdk源码中找找答案,全局在openjdk8的源码中搜索OmitStackTraceInFastThrow关键字,确实得到了想要的答案,一起来看下。

结合网上的一些结论和源码来看只有以下几类异常才会触发OmitStackTraceInFastThrow,分别是NullPointerException、ArithmeticException、ArrayIndexOutOfBoundsException、ArrayStoreException、ClassCastException,最终发现是有一个脚本文件的内容为空,会触发jsqlparse发生ArrayIndexOutOfBoundsException,进而触发了OmitStackTraceInFastThrow特性,导致工具代码中e.getMessage()返回null而触发NPE造成工具停止运行的假象。

修复办法

  1. 使用-XX:-OmitStackTraceInFastThrow关闭这一特性;

  2. 对执行逻辑优化,如果发现脚本文件内容为空就直接返回,不再继续执行;

推荐阅读

https://opts.console.heapdump.cn/result/query/Ex13k

https://heapdump.cn/topic/OmitStackTraceInFastThrow

一个jsqlparse+git做的小工具帮我节省时间摸鱼

  

  

  

案例分享-Exception.getMessage突然为null的更多相关文章

  1. ArcGIS Add-in插件开发从0到1及实际案例分享

    同学做毕设,要求我帮着写个ArcGIS插件,实现功能为:遍历所有图斑,提取相邻图斑的公共边长及其他属性(包括相邻图斑的ID),链接到属性表中.搞定后在这里做个记录.本文分两大部分: ArcGIS插件开 ...

  2. 性能调优案例分享:jvm crash的原因 1

    性能调优案例分享:jvm crash的原因   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq: ...

  3. 前端案例分享(一):CSS+JS实现流星雨动画

    目录 引言 1.效果图 2.源码 3.案例解析 4.小问题 5.结语 引言        平常会做一些有意思的小案例练手,通常都会发到codepen上,但是codepen不能写分析.        所 ...

  4. Elasticsearch Sliced Scroll分页检索案例分享

    面试:你懂什么是分布式系统吗?Redis分布式锁都不会?>>>   The best elasticsearch highlevel java rest api-----bboss ...

  5. 【案例分享】在 React 框架中使用 SpreadJS 纯前端表格控件

    [案例分享]在 React 框架中使用 SpreadJS 纯前端表格控件 本期葡萄城公开课,将由国电联合动力技术有限公司,资深前端开发工程师——李林慧女士,与大家在线分享“在 React 框架中使用 ...

  6. Office 2010 KMS激活原理和案例分享

    Office 2010 KMS激活原理和案例分享     为了减低部署盗版(可能包含恶意软件.病毒和其他安全风险)的可能性,Office 2010面向企业客户推出了新的批量激活方式:KMS和MAK.这 ...

  7. Office 2010 KMS激活原理和案例分享 - Your Office Solution Here - Site Home - TechNet Blogs

    [作者:葛伟华.张玉工程师 ,  Office/Project支持团队, 微软亚太区全球技术支持中心 ] 为了减低部署盗版(可能包含恶意软件.病毒和其他安全风险)的可能性,Office 2010面向企 ...

  8. 老李案例分享:Weblogic性能优化案例

    老李案例分享:Weblogic性能优化案例 POPTEST的测试技术交流qq群:450192312 网站应用首页大小在130K左右,在之前的测试过程中,其百用户并发的平均响应能力在6.5秒,性能优化后 ...

  9. 性能调优案例分享:Mysql的cpu过高

    性能调优案例分享:Mysql的cpu过高   问题:一个系统,Mysql数据库,数据量变大之后.mysql的cpu占用率很高,一个测试端访问服务器时mysql的cpu占用率为15% ,6个测试端连服务 ...

  10. 老李案例分享:MAT分析应用程序服务出现内存溢出过程

    老李案例分享:MAT分析应用程序服务出现内存溢出过程   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loa ...

随机推荐

  1. 洛谷题解 | AT_abc321_c Primes on Interval

    目录 题目翻译 题目描述 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 样例 #2 样例输入 #2 样例输出 #2 样例 #3 样例输入 #3 样例输出 #3 题目简化 题目思路 A ...

  2. 其它——MyCat实现分库分表

    文章目录 MyCat实现分库分表 一 开源数据库中间件-MyCat 二 MyCat简介 三 MyCat下载及安装 3.1 MySQL安装与启动 3.2使用docker启动多个数据库 3.3 MyCat ...

  3. PostgreSQL学习笔记-6.基础知识:ALTER、TRUNCATE 、View(视图)、TRANSACTION 事务、LOCK 锁

    ALTER TABLE 命令 在 PostgreSQL 中,ALTER TABLE 命令用于添加,修改,删除一张已经存在表的列. 另外你也可以用 ALTER TABLE 命令添加和删除约束. 语法 用 ...

  4. Go函数介绍与一等公民

    Go函数介绍与一等公民 函数对应的英文单词是 Function,Function 这个单词原本是功能.职责的意思.编程语言使用 Function 这个单词,表示将一个大问题分解后而形成的.若干具有特定 ...

  5. 二进制部署k8s高可用

    一.前置知识点 部署中遇到问题请参考:http://blog.ctnrs.com/post/k8s-binary-install/ 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部 ...

  6. 【2023年更新】git 常用口令

    1.已关联远程 fatal: remote origin already exists.   先输入$ git remote rm origin(删除关联的origin的远程库)   2.关联新远程 ...

  7. QT(7)-初识委托

    @ 目录 1 简介 2 QT中的委托类 2.1 函数 2.1.1 关键函数 2.1.2 其他函数 3 例子 3.1 官方例子 3.2 修改官方例子 4 设想 1 简介 委托是Qt中的一种机制,用于在Q ...

  8. 彻底搞懂CAP理论(电商系统)

    1.理解CAP CAP是 Consistency.Availability.Partition tolerance三个词语的缩写,分别表示一致性.可用性.分区容忍性. 下边我们分别来解释: 为了方便对 ...

  9. 支持C#的开源免费、新手友好的数据结构与算法入门教程

    前言 前段时间完成了C#经典十大排序算法(完结)然后有很多小伙伴问想要系统化的学习数据结构和算法,不知道该怎么入门,有无好的教程推荐的.今天给大家推荐一个支持C#的开源免费.新手友好的数据结构与算法入 ...

  10. 多数元素 (3.12 leetcode每日打卡)

    给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [3,2,3] ...