Динамическая загрузка классов в 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 ответ:
Вы можете использовать DynamicImport-Package:*. Это позволит узлу видеть все классы. Проблема в том, что у вас нет реального контроля над тем, что именно подвергается воздействию. Так что это обычно последнее средство, а не рекомендуемый способ.
Вы должны сначала попробовать использовать поток.currentThread ().setContextClassLoader () и установите его в classloader класса, который вы предоставляете платформе. Иногда фреймворки также консультируются с этим загрузчиком классов.
Еще лучший способ-найти метод в фреймворке, позволяющий предоставить пользователю classloader.
Если у вас есть контроль над кодом, то избегайте класса.forname (). Вместо этого пусть пользователь либо даст вам объект класса вместо имени класса, либо даст вам комбинацию имени класса и загрузчика классов для использования. Оба способа прекрасно работают как внутри, так и вне OSGi.