Я новичок в Java и только начинаю понимать концепцию загрузчиков классов. Прямо сейчас у меня возникают некоторые проблемы с log4j, связанные с использованием загрузчика классов контекста потока.
Я получаю следующие ошибки: A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable. The class "org.apache.log4j.Appender" was loaded by [java.net.URLClassLoader@105691e] whereas object of type "org.apache.log4j.ConsoleAppender" was loaded by [sun.misc.Launcher$AppClassLoader@16930e2]. Could not instantiate appender named "CONSOLE".
Мое приложение работает примерно так: при инициализации создается URLClassLoader # 1 и загружает некоторые классы, эти классы используют log4j. Позже создается URLClassLoader # 2 (который имеет URLClassLoader # 1 в качестве родительского) и загружает еще несколько классов, эти классы также используют log4j. Когда URLClassLoader # 2 используется для загрузки этих классов, появляется указанное выше сообщение об ошибке (есть еще пара с такой же проблемой).
Текущий обходной путь, который я сделал, заключался в том, чтобы установить текущий загрузчик классов контекста потока на URLClassLoader # 2 перед загрузкой проблемных классов и затем сбросить его на старый:
ClassLoader urlClassLoader; // this is URLClassLoader #2
Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();
thread.setContextClassLoader(urlClassLoader);
try {
urlClassLoader.loadClass(...)
} finally {
thread.setContextClassLoader(loader);
}
Хотя это работает, я не уверен, что это правильный подход.
Мы будем благодарны за любое понимание этого вопроса. Кроме того, почему log4j заставляет меня возиться с загрузчиком классов контекста потока? Почему бы мне не передать загрузчик классов (и использовать загрузчик по умолчанию, когда я этого не делаю) вместо использования загрузчика потока?