Когда вы вызываете Class.forName(className, initialize, classLoader)
, вы просите JVM загрузить класс, используя этот пользовательский загрузчик классов. Если вы не укажете ClassLoader
- например, просто позвонив Class.forName(className)
, тогда JVM будет использовать ClassLoader
, известный как «контекстный классLoader» для потока. Каждый поток имеет один из них, и ваш код может изменить код.
Если у вас есть код, который вызывает класс должен быть загружен - что-то вроде этого:
MyClass foo = new MyClass();
MyClass
класс будет загружен в ClassLoader
, если он еще не загружен. Невозможно вызвать конструктор и поставить ClassLoader
, чтобы загрузить класс, если он еще не загружен. В этом случае контекст потока ClassLoader
является пользователем.
Кроме того, если вы вызываете какой-либо код, который вы не контролируете, существует много способов, которыми этот код может привести к загрузке других классов, и поскольку у вас нет контроля над этим кодом, контекст потока ClassLoader
также будет использоваться.
Итак, как вы устанавливаете контекст нити ClassLoader
? Легко:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ClassLoader myClassLoader = ...; // You figure this out
try
{
Thread.currentThread().setContextClassLoader(myClassLoader);
// Do work that requires your ClassLoader to work
}
finally
{
// Always restore the previous CCL after work is done
Thread.currentThread().setContextClassLoader(cl);
}
Еще одна вещь, которую вы хотите сделать, это убедиться, что ваш заказ ClassLoader
делегатов любые просьбы о классовой нагрузки на родителей ClassLoader
. Этот родитель ClassLoader
должен, вероятно, быть ClassLoader
, который, естественно, будет использоваться, если вы не пытаетесь использовать свои собственные: контекст потока ClassLoader
.
Таким образом, вы, вероятно, хотите что-то вроде следующего:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ClassLoader myClassLoader = new MyClassLoader(cl); // Try 'cl' before your custom class loading
try
{
Thread.currentThread().setContextClassLoader(myClassLoader);
// Do work that requires your ClassLoader to work
}
finally
{
// Always restore the previous CCL after work is done
Thread.currentThread().setContextClassLoader(cl);
}
Вы можете найти более подробную информацию о ClassLoader
с, и, в частности, TCCL, в эти несколько ссылок:
Что такое 'classLoader'? Это пользовательский 'ClassLoader', который вы написали? Какие ресурсы вы добавили в этот класс ClassLoader, чтобы он мог загружать классы? Где собственно библиотека JSON, и какой класс ClassLoader вы ожидаете загрузить? –
Я использую URLClassLoader, и я добавляю баночки в мой загруженный пакет для этого загрузчика классов. Библиотека json является частью этих баннеров (мой загруженный пакет содержит в основном список баннеров) – Zizou
Я попытался отладить мой пользовательский загрузчик классов см классов, пытаемся загрузить: 'общественного класса CustomClassLoader расширяет URLClassLoader { \t общественного CustomClassLoader (URL [] URLs, ClassLoader родительского) { \t \t супер (URLs, родительский); \t} \t @Override \t защищенный класс > loadClass (имя String, логическое решительность) бросает ClassNotFoundException { \t \t System.out.println ("пытаетесь загрузить:" + имя); \t \t return super.loadClass (имя, разрешение); \t} \t } ' Но я обнаружил, что мой загрузчик классы не пытаются даже загрузить ** de.odysseus.staxon.json.stream.impl.JsonStreamFactoryImpl ** – Zizou