我有一个具有静态final方法的类。(说A, B, C)。
C调用另一个类D[D的包在C中导入]。
我拥有的maven程序集jar[比如M.jar]没有包D。在运行时,当我尝试调用类路径中有M.jar的A时,得到noclasdef error,说D不存在。
为什么我得到这个?
package TEST1
import test.CHECK.TestA;
import test.CHECK.TestB;
class Factory
{
final static A()
{
//some ref to test.CHECK.TestA
}
static B()
{
//some ref to test.CHECK.TestB
}
static C()
{
}
我有一个包含这个类的jar和一个包test.CHECK.TestB。但是,这个jar不包含test.CHECK.TestA.
现在,我的客户端程序有这个jar调用C()
。然后,为TestA获取ClassNotFoundException,尽管我们没有调用A()。为什么会这样呢?
No class def found error表示找到了类,但JVM在运行时未能加载它。大多数情况下,问题是类D没有加载到调用它的类加载器中。另一个问题可能来自D类初始化失败,由于一些模糊的原因…我们需要你提供完整的堆栈跟踪,如果你需要一些帮助。
为什么你得到ClassNotFoundException:
当JVM在内存中加载一个类时,它也会尝试加载它的依赖项(这个类代码所依赖的其他类)。因为你的类有对test.CHECK的引用。首先,JVM尝试加载这个丢失的类(参见Java虚拟机规范,第12章,还有this: ClassLoader:可能配置使用惰性而不是静态解析?)。
如何使JVM不尝试加载丢失的类?:
这是不可能的,至少在Oracle的JVM
可能的解决方案:
尝试在Google/Bing/Whatever中搜索丢失的类的全名(包括包名),看看是否可以找到丢失的类并将其添加到类路径
另一个可能的解决方案(非常丑陋的解决方法——孩子,不要在家里这样做):
如果你找不到这样的类,如果你非常想让这个运行,并且你完全确定方法A从来没有被使用过,即使是你使用的方法C,然后尝试通过"mock"(写"空"替代品)缺失的包,缺失的类和缺失的方法;这将涉及编译/执行/error_thrown/edit_again的试错过程。我知道这很难看,但是在一天结束的时候,你可以让你的课运行。
我认为问题是当你调用C()
静态方法时,你的代码将第一次引用Factory
类(假设它没有加载在内存中)。
所以当你的Factory
类被加载时,它会尝试加载所有的static
方法,而当时JVM由于某种原因无法加载TestA
类,这就是为什么这个错误出现的原因。
尝试从调用C()
的类中调用A()
方法,看看是否成功。