我目前遇到的问题是,我有一个(部分)程序正在尝试加载一个类,但由于找不到该类而失败。查看堆栈跟踪,我无法看到虚拟机首先尝试加载此特定类的任何特定原因。是否有任何工具可以让我弄清楚为什么要加载特定的类?
提示: 我已经在JVM尝试加载类的确切点处(通过代理)得到了堆栈跟踪。但是,堆栈跟踪不包含行号。因此,我只知道哪个方法触发了类的加载,而不知道哪个语句。即使了解了语句,有时候也可能不够。单个语句可以以多种方式导致类被加载,因为有时虚拟机需要加载类的传递闭包的一部分。
我目前遇到的问题是,我有一个(部分)程序正在尝试加载一个类,但由于找不到该类而失败。查看堆栈跟踪,我无法看到虚拟机首先尝试加载此特定类的任何特定原因。是否有任何工具可以让我弄清楚为什么要加载特定的类?
提示: 我已经在JVM尝试加载类的确切点处(通过代理)得到了堆栈跟踪。但是,堆栈跟踪不包含行号。因此,我只知道哪个方法触发了类的加载,而不知道哪个语句。即使了解了语句,有时候也可能不够。单个语句可以以多种方式导致类被加载,因为有时虚拟机需要加载类的传递闭包的一部分。
使用-XX:+TraceClassLoading
和-XX:+TraceClassResolution
标志运行您的程序。这将创建大量输出,看起来像以下内容:
[Loaded com.kdgregory.example.memory.PermgenExhaustion$MyClassLoader from file:/home/kgregory/Workspace/Website/programming/examples/bin/]
RESOLVE com.kdgregory.example.memory.PermgenExhaustion$MyClassLoader java.net.URLClassLoader
RESOLVE java.net.URLClassLoader java.lang.Class URLClassLoader.java:188
你需要跟踪一个特定类的解析消息链。或者更有可能的是,在程序尝试加载该类时,您会看到一个错误,其前面是加载它的类的解析消息。
类加载器
如果是多个类加载器同时存在的环境(比如Web应用程序),你需要小心处理。请告诉我们这个应用程序的情况。
资源
告诉我们JAR包的位置(文件/目录结构)以及哪个类正在加载。你是使用Class.forName动态加载它吗?还是使用Spring或其他IOC框架?它是主类吗?
一些先前的测试(帮助我们)
也许你可以在main方法中使用Class.getResource()测试一些东西。如果你的类是foo.bar.Clazz,尝试使用Class.getResource("/foo/bar/Clazz.class")来查看是否返回有效结果。尝试使用加载失败的类所在的类来做同样的事情,看看它是否符合你的预期。