Динамическая загрузка классов в OSGi


У меня есть целая куча модулей фреймворка, которые прекрасно работают на OSGi, все службы и компоненты находят друг друга и работают просто отлично.

Однако есть одна структура, которая делает некоторые динамические вещи относительно классов. В принципе, в какой-то момент Вы даете ему имя класса, и он выполняет класс.forName (), а затем происходит магия отражения.

Это отлично работает при работе в стандартном jvm и использовании SPI для соединения фреймворков, но это не удается в OSGi из-за конечно, этот случайный тест класса.MyTest" , к которому вы пытаетесь подойти через фреймворк, не виден для упомянутого фреймворка.

Он бросит "java.яз..ClassNotFoundException: тест.MyTest не найден фреймворком "

Итак, мой вопрос: как я могу решить эту проблему отсутствия видимости для фреймворка, который должен видеть все? Import-Package: *?

Обновить

Предполагая, что OSGi не сильно изменился с 2010 года на этом фронте, статья http://njbartlett.name/2010/08/30/osgi-readiness-loading-classes.html Это очень интересно. В настоящее время я добавил поддержку как для активно регистрирующихся классов, так и для фабрики доменов, вводимой через OSGi.

Кроме того, разрешение по умолчанию использует context classloader в любом случае, так что если все остальное не удается, что будет использоваться, чтобы попытаться загрузить класс.

Обновить

Я добавил поддержку для предложенного DynamicImport-Package, который легче для малых проекты.

1 2

1 ответ:

Вы можете использовать DynamicImport-Package:*. Это позволит узлу видеть все классы. Проблема в том, что у вас нет реального контроля над тем, что именно подвергается воздействию. Так что это обычно последнее средство, а не рекомендуемый способ.

Вы должны сначала попробовать использовать поток.currentThread ().setContextClassLoader () и установите его в classloader класса, который вы предоставляете платформе. Иногда фреймворки также консультируются с этим загрузчиком классов.

Еще лучший способ-найти метод в фреймворке, позволяющий предоставить пользователю classloader.

Если у вас есть контроль над кодом, то избегайте класса.forname (). Вместо этого пусть пользователь либо даст вам объект класса вместо имени класса, либо даст вам комбинацию имени класса и загрузчика классов для использования. Оба способа прекрасно работают как внутри, так и вне OSGi.