Java无异常崩溃排查:编译器与运行时版本不兼容问题
Java 7/8编译运行环境不兼容导致ConcurrentHashMap调试异常问题及解决
原始代码
class MyClass { public void myMethod(HashMap<String, String> inputMap) { try { ConcurrentHashMap<String, String> cm = new ConcurrentHashMap<>(); cm.putAll(inputMap); try { for (Object key : cm.keySet()) { cm.put(key.toString(), ""); } } catch (Exception e) { e.printStackTrace(); } System.out.println("After try catch"); } finally { System.out.println("In finally"); } } }
遇到的异常现象
- 调试时代码执行到
for (Object key : cm.keySet())行直接跳转到finally块,既不进入catch块,也不执行try/catch后的System.out.println("After try catch");代码 cm对象非空,包含约30个元素- 运行环境为Java 7(版本1.7.0_85)
- 调试器中手动调用
cm.keySet()提示“No such instance method: 'keySet'”,但ConcurrentHashMap的JavaDoc显示该方法存在,且通过cm.getClass().getDeclaredMethods()能检索到该方法 - 代码在非主线程运行,控制台无错误输出,异常无法被
Exception捕获
问题原因及解决方案
原因
问题并非代码本身逻辑错误,而是编译器已升级到Java 8但未被察觉,而服务器运行环境是Java 7,导致编译后的字节码在Java 7环境下运行出现兼容性问题。
修改后的兼容代码
class MyClass { public void myMethod(HashMap<String, String> inputMap) { try { ConcurrentHashMap<String, String> cm = new ConcurrentHashMap<>(); cm.putAll(inputMap); try { Enumeration<String> keys = cm.keys(); while(keys.hasMoreElements()) { String key = keys.nextElement(); cm.put(key, ""); } } catch (Exception e) { e.printStackTrace(); } System.out.println("After try catch"); } finally { System.out.println("In finally"); } } }
定位关键
感谢@cyberbrain建议捕获Throwable而非Exception,才得以发现并定位到环境不兼容的问题。
内容的提问来源于stack exchange,提问作者Xiidref
相关产品推荐
相关产品推荐

