getCanonicalName时引发ClassCircularityError [英] ClassCircularityError is thrown when getCanonicalName

查看:96
本文介绍了getCanonicalName时引发ClassCircularityError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

异常堆栈。

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,那一切都很好,这很奇怪。这些已加载的类将使用自定义的ClassLoader进行加载。像 cl = defineClass(name,byteArray,0,byteArray.length);

Below is the code which cause the error. It's very strange if I change the getCanonicalName to getName then everything is fine. These loaded classes are loaded with customized ClassLoader. like cl = defineClass(name, byteArray, 0, byteArray.length);

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;        
}

任何人都可以告诉我为什么这里的getCanonicalName会引发此错误?
(JDK 1.6.0_20)

Any one can tell me why getCanonicalName here will throw this error? (JDK 1.6.0_20)

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

UPDATE After some research, I find that when you define the class you must load the its parent class first. But it's hard. When I write to the binary, they are just ordered by the sequence in the file folder. So when I load them, they will not order by the class hieriarchy. It's a bit annoying here.For now I just loop the classes , then load the error class again. This is workaround but not a good one.

推荐答案

我遇到此问题的原因是我试图做一些JVM而不是允许的。
我正在使用自定义类加载器加载一个子类,但使用另一类加载器加载父类。这将在您调用getCanonicalName时引起问题,我想这一次,JVM将
尝试查找其父类,但是由于父类由另一个类加载器加载而失败。
因此引发了此异常。

The reason why I hit this issue is I am trying to do something JVM not allowed. I am loading one child class using a custom classloader, but load the parent class using another classloader. This will cause issue when you call getCanonicalName, I guess this time, JVM will try to find its parent class, but it failed due to the parent class is loaded by another classloader. So this exception is thrown.

我要解决的问题是,将所有父类(对象类除外:-)和由相同的类加载器和接口加载的子类不需要由相同的类加载器加载。关于加载顺序,
我通过添加findClass方法解决了,在此方法中,它将通过此​​自定义 findClass()方法查找依赖项类。在调用 findClass()之前,我将首先由父类加载器查找依赖项类。

What I did to fix it, is to put all the parent class(Except the Object class:-)) and the child class to be loaded by the same classloader and interface doesn't need to be loaded by same classloader. About the loading order, I solved it by adding a findClass method, in this method, it will look for the dependency class by this custom findClass() method. Before calling findClass(), i will firstly look for the dependency class by the parent classloader.

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

The call sequence of this classloader is custom classloader loadClass() => super (webapp's classloader) loadClass()=> findClass() method webapp's classloader is set by the constructor of custom classloader.

现在一切都解决了。

这篇关于getCanonicalName时引发ClassCircularityError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆