background image

Java 应用在运行时常见的一些问题,总结了运行时黑盒方式的一些排查方法,也希望看
到的同学能给予补充,无论是补充碰到的问题,还是补充解决方法。
  类装载的相关问题
 

 

Java

ClassNotFoundException/NoClassDefFoundError/NoSuchMethodException( 还 有
一个常见的 ClassCastException 就不在这里说了)。
  当碰到 ClassNotFoundException/NoClassDefFound 时,如果很确定这个 class
应该是从哪个路径装载的,则可以去相应的路径找下是否有对应的 class 文件存在,例
如 web 应用通常会在*.war(ear)/WEB-INF/lib 或 classes 目录下,对于 lib 下的 jar 包,
可通过写个小脚本 jar -tvf 的方式找找;
  如不确定 class 是从哪装载的,则可以先看看日志里是否有堆栈信息,如果有的话
则 可 以 看 到 具 体 是 哪 个 ClassLoader 实 现 在 装 载 class , 之 后 则 可 以 通 过
www.grepcode.com 或 jar 包反编译(推荐一个挺好用的反编译工具)看看具体是从哪装
载的 class;
  如日志中没有,则可以用 btrace 来跟踪下抛出以上两个异常的堆栈信息,btrace
脚本类似如下:
  ?
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class Trace{
   @OnMethod(
       clazz="java.lang.ClassNotFoundException",
       method="<init>"
   )
   public static void traceExecute(){
        jstack(); 
   }
}
  拿到堆栈信息后,可以继续使用上面的方法进行排查,在确认了 class 装载的位置
后,则可将相应的 class/jar 加上即可。
  这里还有个 NoClassDefFoundError 排查的 case,感兴趣的话可以看看。
  当碰到 NoSuchMethodException 时,通常是由于不存在需要的 class 版本或
class 版 本 冲 突 造 成 的 , 在 这 种 情 况 下 , 可 通 过 在 启 动 参 数 上 增 加 -XX:
+TraceClassLoading,重启后在日志里看看此 class 是在哪 load 的,然后可以在对应
的路径下用 jar -tvf 找找是不是有正确的版本的 jar 存在,通常可能会发现是版本冲突造
成的,对于版本冲突的问题通常需要删掉有冲突的版本的 jar,对于没有正确版本的,则
需要用正确版本的 jar 替换掉(当然,这种通常还会出现一些恶心的问题,例如和容器/框
架的 jar 冲突等)。