ClassCircularityError выбрасывается, когда getCanonicalName - PullRequest
9 голосов
/ 22 июля 2011

Стеки исключений.

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

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)

ОБНОВЛЕНИЕ После некоторых исследований я обнаружил, что при определении класса вы должны сначала загрузить его родительский класс.Но это тяжело.Когда я пишу в двоичный файл, они просто упорядочены по последовательности в папке файлов.Поэтому, когда я загружу их, они не будут заказывать классом иерархии.Это немного раздражает. Пока я просто зацикливаю классы, затем снова загружаю класс ошибок.Это обходной путь, но не очень хороший.

1 Ответ

2 голосов
/ 13 сентября 2011

Причина, по которой я решил эту проблему, заключается в том, что я пытаюсь сделать что-то, что JVM не разрешено.Я загружаю один дочерний класс с помощью пользовательского загрузчика классов, но загружаю родительский класс с помощью другого загрузчика классов.Это вызовет проблему при вызове getCanonicalName, думаю, на этот раз JVM попытается найти родительский класс, но это не удалось из-за того, что родительский класс загружен другим загрузчиком классов.Таким образом, это исключение выдается.

Что я сделал, чтобы исправить это, так это поместил весь родительский класс (за исключением класса Object :-)) и дочерний класс для загрузки одним и тем же загрузчиком классов, а интерфейс не 'не должен быть загружен тем же загрузчиком классов.Что касается порядка загрузки, я решил его, добавив метод findClass, в этом методе он будет искать класс зависимостей с помощью этого пользовательского findClass() метода.Перед вызовом findClass(), я сначала посмотрю на класс зависимостей родительским загрузчиком классов.

Последовательность вызовов этого загрузчика классов является пользовательским загрузчиком классов loadClass() => super (загрузчик классов веб-приложения) loadClass() => findClass() Загрузчик классов веб-приложения метода веб-приложения устанавливается конструктором пользовательского загрузчика классов.

Так что теперь все решено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...