Java, проблемы с кастомным загрузчиком классов - PullRequest
0 голосов
/ 01 ноября 2011

Я пишу специальный загрузчик классов для загрузки некоторых из моих классов (не всех).

Загрузчик классов очень прост:

public Class loadClass(String className, boolean resolve) throws ClassNotFoundException {
    Class cls=findLoadedClass(className);
    if(cls!=null) {
        return cls;
    }
    // Search first for encrypted classes
    cls=decryptClass(className);
    if(cls==null) {
        // Then try with default system classloader
        cls=super.loadClass(className, resolve);
    }
    return cls;
}

И вот как я его использую:

// In my Launcher class
public static void main(String[] args) {
    MyClassLoader loader=new MyClassLoader();
    try {
        final Class main=loader.loadClass("com.MyAppMain");
        Method toInvoke=main.getMethod("main", args.getClass());
        toInvoke.invoke(main, new Object[]{args});
    }
    catch(Exception ex) {
    }
}

В моем небольшом тестовом проекте все в порядке, но когда я использую этот загрузчик в моем большом проекте (клиент-серверное приложение, использующее spring + hibernate и IoC), не работает.У меня нет отдельного исключения в моем загрузчике классов, но, например, новый экземпляр Socket вызывает «java.net.ConnectException: Соединение отказано» без реальной причины ...

Другие проблемы - моя основная форма нестановятся видимыми ... и другие странные проблемы, подобные этой.

Итак, вопрос, эти проблемы вызваны тем, что мой загрузчик классов по-разному загружает классы другого типа?


Редактировать 1

В моем проекте используется пружина, поэтому я использую @Autowired или иногда

springApplicationContext.getBean(clazz);

для введения компонента.

Проблема в том, что пружина не может найти мои компоненты, если ониклассы зашифрованы (поэтому они должны быть загружены моим загрузчиком классов).Есть обходной путь для этой ошибки?Спасибо.


Edit 2

Я установил свой загрузчик классов весной ClassPathXmlApplicationContext, и теперь я замечаю, что spring использует мой загрузчик классов для загрузки класса бобов, но, несмотря на это, он вызывает org.springframework.beans.factory.NoSuchBeanDefinitionException, поскольку он не может найти бины ... что я могу сделать?Спасибо

Ответы [ 2 ]

0 голосов
/ 08 ноября 2011

Я не очень хорош в загрузчиках классов, но из вашего кода можно только предположить, что если ваш загрузчик классов не сможет найти класс, он будет перенаправлен в системный загрузчик классов.Он может нормально работать, когда вы запускаете приложение автономно, как в вашем примере, но если это веб-приложение, которое запускается на сервере приложений, оно не будет работать.

Серверы приложений обычно создают большую иерархию загрузчиков классов и имеютотдельный загрузчик классов, используемый для загрузки классов вашего приложения.В этом случае системный загрузчик классов ничего не знает о ваших связанных с Spring классах и, следовательно, не может их загрузить.

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

В вашем случае я бы установил родительский загрузчик классов в конструкторе MyClassLoader.В качестве загрузчика родительского класса вы можете использовать MyClassLoader.class.getClassLoader () Я думаю.

public class MyClassLoader extends ClassLoader
{
    public MyClassLoader()
    {
       super(MyClassLoader.class.getClassLoader());
    }

    // other code
}

Надеюсь, это может помочь:)

0 голосов
/ 01 ноября 2011

Я вижу две вещи, которые стоит исследовать:

  • Код делает загрузчик класса родительским последним. Всегда существует риск, что это вызовет незначительные проблемы с загрузкой классов.
  • Может быть, это просто загрузчик класса контекста потока, который установлен неправильно.
...