项目

一般

简介

aasv9 javax.servlet.ServletException: java.lang.ClassCastException 异常问题分析记录

佘 肃徽大约 3 年 之前添加

在某项目中。正常运行运行一段时间后会发生 javax.servlet.ServletException: java.lang.ClassCastException 的异常,仔细看强制转换的两个类,类名完全一样。

推断是由于两个类是由两个类加载器加载的,通过用arthas 的classloader命令显示,

发生异常的两个类,分别有两个  ReloadableClassLoader 加载。

进一步排查,是由于aasv9会监控应用目录,当class文件变动时(时间戳),aas会创建新的ReloadableClassLoader去加载更新过的class以及以后要需要加载的class,而之前已经加载的class如果依旧被引用的情况下,是不会被销毁的。

这个时候内存中其实是存在两个完全相同的类名的两个类,由于jdk里对于不同类的判定为类的全限定名+classloader,那么自然这两个类就会被当作两个不同的类,这样的话当执行以下代码时会发生javax.servlet.ServletException: java.lang.ClassCastException的异常,

异常产生的代码示例: User user=(User)Session.getAttribute("user"); ///由于session里的是旧的classloader 创建的User,而当前要赋值的User是由新的classLoader加载的,所以产生类转换异常。

由此需要注意的是,日常运维中,如果要更新class文件,需要立即重启中间件避免产生类似异常。