Java getCanonicalName时抛出ClassCircularTyerror

Java getCanonicalName时抛出ClassCircularTyerror,java,classloader,Java,Classloader,异常堆栈。 Exception in thread "main" java.lang.ClassCircularityError: plugins/agents/Agent at java.lang.Class.getDeclaringClass(Native Method) at java.lang.Class.getEnclosingClass(Class.java:1085) at java.lang.Class.getCanonicalN

异常堆栈。

Exception in thread "main" java.lang.ClassCircularityError: 
plugins/agents/Agent
        at java.lang.Class.getDeclaringClass(Native Method)
        at java.lang.Class.getEnclosingClass(Class.java:1085)
        at java.lang.Class.getCanonicalName(Class.java:1169)
        at agents.loader.AgentLoader.getPluginAgentFromCache(AgentLoader.java:288)
        at compiler.AgentCompiler.main(AgentCompiler.java:365)
下面是导致错误的代码。很奇怪,如果我将getCanonicalName更改为getName,那么一切都很好。这些加载的类是用定制的类加载器加载的。like
cl=defineClass(name,byteArray,0,byteArray.length)

公共类getPluginAgentFromCache(字符串名称)
{
如果(_loadedClasses==null)
返回null;
迭代器iter=_loadedClasses.Iterator();
while(iter.hasNext())
{
c类=iter.next();
if(c.getCanonicalName().equals(name))
返回c;
}
返回null;
}
任何人都可以告诉我为什么getCanonicalName会抛出这个错误? (JDK 1.6.0_20)

更新 经过一些研究,我发现当定义类时,必须首先加载它的父类。但这很难。当我写入二进制文件时,它们只是有序的 按文件夹中的顺序。因此,当我加载它们时,它们不会按类排序
等级制度。这里有点烦人。现在我只是循环类,然后再次加载错误类。这是一个解决办法,但不是一个好办法。

我遇到这个问题的原因是我试图做JVM不允许的事情。 我使用自定义类加载器加载一个子类,但使用另一个类加载器加载父类。当您调用getCanonicalName时,这会导致问题,我想这次JVM会 尝试查找其父类,但由于父类由另一个类加载器加载而失败。 所以抛出这个异常

我所做的是修复它,将所有父类(对象类除外:-)和子类放在同一个类装入器中,接口不需要由同一个类装入器装入。关于装货单, 我通过添加一个findClass方法解决了这个问题,在这个方法中,它将通过这个自定义的
findClass()
方法查找依赖类。在调用
findClass()之前,
我将首先通过父类加载器查找依赖类

此类加载器的调用顺序是自定义类加载器
loadClass()
=>super(webapp的类加载器)
loadClass()
=>
findClass()
方法 webapp的类加载器由自定义类加载器的构造函数设置


现在一切都解决了。

ClassCircularyError是由JVM而不是getCanonicalName()抛出的。根据API,当JVM检测到被加载类的超类层次结构中存在循环时,就会抛出它。你能显示你正在加载的类的定义吗?@Hunter我找到另一种方法。我也可以解决这个问题。也就是说,将导致此错误的类的父类放入同一文件夹中。也可以使用相同的类加载器来加载它。然后就修好了。但是这是否意味着我必须使用同一个类加载器来加载它的父类呢?你知道你将迎来一个特殊的日子,当你的Java错误的第一个Google命中是一个错误报告给Sun。不知何故,你已经设法将一个类定义为它自己的超类。至少这应该是导致这个错误的原因。@Hunter-实际上是从2006年开始的。我想我应该在我的评论之后加上一个笑脸:)
public Class getPluginAgentFromCache(String name)
{
    if (_loadedClasses == null)
        return null;

    Iterator <Class> iter = _loadedClasses.iterator();

    while (iter.hasNext())
    {
        Class c=iter.next(); 
        if (c.getCanonicalName().equals(name))
            return c;
    }

    return null;        
}