当我在调试时遇到了ClassNotLoadedException该如何处理?

28

我正在使用Eclipse远程调试一个Java/JBoss应用程序,逐行进行调试。在某个点上,通过方法调用创建了一个GridSquare对象的数组(GridSquare是一个相当简单、独立的类,包含一些属性和方法),如下所示:

GridSquare[] squares = this.theGrid.getSquares(14, 18, 220, 222);

...当我实际执行代码时,squares数组确实会被GridSquare对象填充,但是在进行调试时,当我在上面显示的分配语句后紧接着的断点处尝试查看squares数组时,我得到了以下奇怪的结果:

org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.

...有人知道这是什么意思吗?

6个回答

27

基本上意味着类加载器没有加载 GridSquare[] 类。话虽如此,听起来像是调试器有某种bug。断点与代码的关联似乎略微出了些问题。你需要重新编译代码以同步行号,或者有其他问题正在发生。在代码的这一点(赋值之后),它需要被加载。除非 getSquares实际返回一个子类(GridSquareSubclass[]),在这种情况下,JVM 可能尚未加载它,因为它还不需要它。


有没有什么方法可以强制 JVM 在特定时刻加载一个类?类似于编译器指令的东西? - DanM
14
你可以在代码中加载类,以强制其发生(比如创建一个与上一行相同类型的新数组等显式地加载该类)。你也可以尝试通过调试器中的“评估表达式”发送指令(例如Class.forName()或Array.newInstance())。 - Yishai
请问您能否指导一下这个问题的解决方法:https://dev59.com/8Zrga4cB1Zd3GeqPs9g6? - PAA

1
我遇到了这个错误,因为我在对使用反射的代码运行单元测试。我专门为测试代码的所有功能创建了一个特殊的类。Junit显然为测试类使用了一个单独的类加载器(这是很有道理的),所以我的代码不能在那个类上使用反射。我得到的堆栈跟踪非常通用(java.lang.InstantiationException),但当我在调试模式下检查异常对象本身时,有更多详细信息(org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException),这导致我得出了这个结论。
所以我把特殊的类移动到主类加载器中(通过将文件从src/test/java移动到src/main/java),它工作得很好。我不喜欢这个解决方案,但我找不到其他的替代方法。在我的情况下,这不算大问题,但我可以看出这可能会成为其他人的问题。

0
//Give a SIZE to the array:
GridSquare[] squares = GridSquare[this.theGrid.size()];

//Fill each element of the array with the object constructor to avoid the null value
for(int i=0; i<this.theGrid.size(); i++){
    squares[i] = new GridSquare();
    squares[i] = this.theGrid.getSquares(14, 18, 220, 222);
}

0
我在使用Eclipse时也遇到过这种情况,当你子类的类变量隐藏了父类的变量时,它会出现这种情况。不知道为什么这会让Eclipse混淆(通常来说,这个想法本身就不是一个好主意:)。例如:
class A {
   private String a;
}

class B extends A {
   public String a;
}

-1
通过初始化GridSquare将解决问题。 squares = new GridSquare();

-3

我遇到了同样的问题,我只是创建了一个公共的静态void main方法,创建了相同类型的对象并运行为Java应用程序,然后我删除了main方法,现在它可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接