JDBC / OSGi и как динамически загружать драйверы без явного указания зависимостей в комплекте? - PullRequest
6 голосов
/ 25 апреля 2010

Это важная персона.

У меня хорошо структурированная, но монолитная кодовая база с примитивной модульной архитектурой (все модули реализуют интерфейсы, но имеют один и тот же путь к классам). Я осознаю глупость этого подхода и проблемы, которые он представляет при развертывании на серверах приложений, которые могут иметь разные конфликтующие версии моей библиотеки.

Сейчас я нахожусь в зависимости от 30 банок, и я на полпути, хотя сгибаю их. Теперь некоторые из моих модулей легко объявить версионными зависимостями, такими как мои сетевые компоненты. Они статически ссылаются на классы в JRE и других библиотеках BNDded, но мои компоненты, связанные с JDBC, создаются через Class.forName (...) и могут использовать один из любого количества драйверов.

Я разбиваю все на пакеты OSGi по областям обслуживания.

  • Мои основные классы / интерфейсы.
  • Отчетность связанных компонентов.
  • Компоненты, связанные с доступом к базе данных (через JDBC).
  • и т.д ....

Я хочу, чтобы мой код можно было использовать без OSGi через один файл jar со всеми моими зависимостями и вообще без OSGi (через JARJAR), а также чтобы он был модульным через метаданные OSGi и гранулированные пакеты с зависимостями информация.

  • Как настроить пакет и мой код, чтобы он мог динамически использовать любой драйвер на путь к классам и / или в OSGi контейнерная среда (Felix / Equinox / и т.д.)

  • Существует ли метод времени выполнения, чтобы определить, работаю ли я в контейнере OSGi, совместимом между контейнерами (Felix / Equinox / и т.д.)?

  • Нужно ли использовать другой механизм загрузки классов, если я нахожусь в контейнере OSGi?

  • Требуется ли импортировать классы OSGi в мой проект, чтобы иметь возможность загружать неизвестный драйвер JDBC во время пакета через мой модуль базы данных?

  • У меня также есть второй способ получения драйвера (через JNDI, который действительно применим только при работе на сервере приложений). Нужно ли менять код доступа JNDI для серверов приложений, поддерживающих OSGi?

Ответы [ 3 ]

7 голосов
/ 29 апреля 2010
  • Для использования любого драйвера в среде OSGi необходимо использовать инструкцию DynamicImport-Package: *, чтобы ваш пакет мог разрешать эти пакеты при загрузке драйвера с Class.forName (..).
  • Вероятно, самый простой способ - это попытаться получить доступ к классу, который находится в пакете org.osgi.framework. По крайней мере, они должны быть всегда в среде OSGi (см. Фрагмент ниже). Есть более сложные механизмы, поэтому дайте мне знать, если вам нужно что-то более продвинутое. Кроме того, взгляните на спецификацию ядра OSGi R4.2, параграф 3.8.9, в которой показаны некоторые методы поиска Bundle и BundleContext класса и, следовательно, косвенно помогает определить, находитесь ли вы в платформе или нет.
  • Это зависит от того, что вы делаете, здесь нет общего ответа «да» или «нет». OSGi использует загрузчики классов и делает это не «типично» для стандартного Java-приложения, но в зависимости от того, что вы делаете, вы можете не заметить.
  • номер
  • Взгляните на недавно выпущенные спецификации OSGi для предприятий. У них есть глава об интеграции JNDI в OSGi, которая, вероятно, позволяет оставить ваш код (в основном) без изменений.

Простой пример фрагмента:

 public static boolean inOSGi() {
  try {
   Class.forName("org.osgi.framework.FrameworkUtil");
   return true;
  }
  catch (ClassNotFoundException e) {
   return false;
  }
 }

Просто убедитесь, что если вы поместите этот код в пакет, пакет должен импортировать org.osgi.framework (иначе он никогда не найдет этот класс).

0 голосов
/ 28 июля 2016

pax-jdbc может использоваться для делегирования источников данных с помощью декларативного способа, что означает, что вы можете создать запись конфигурации в службе ConfigAdmin, а к источнику данных можно получить доступ через JNDI. Драйвер JDBC развернут как пакет. (большинство из них имеют версию OSGi)

Например:

PID записи конфигурации: org.ops4j.datasource-test

Особенности:

osgi.jdbc.driver.name=H2
databaseName=test
user=sa
password=
dataSourceName=testds-h2

Служба идентифицируется данным dataSourceName. Таким образом, вы можете отфильтровать его с помощью (& (objectClass = javax.sql.DataSource) (dataSourceName = test2)).

И вы можете получить доступ к источнику данных через JNDI:

osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=test2)
0 голосов
/ 22 июля 2016

Я создал диспетчер драйверов JDBC для OSGI в Eclipse RCP, и я покажу вам, как хорошо играть с OSGI. Во-первых, забудьте о DynamicImport-Package. Единственный хороший способ использовать OSGI - это установить / запустить / остановить пакеты и использовать механизм OSGI так, как он был спроектирован.

  1. У вас есть пакет JDBC, и вы создаете еще один «Пакет драйверов», который инициализирует DriverClass, логику подключения и добавляет необходимые библиотеки общих ресурсов, такие как dbcp2 и pool2.

  2. Экспортируйте комплект драйверов в виде JAR / ZIP и включите его в комплект JDBC в качестве ресурса.

  3. Позвольте вашему комплекту JDBC разархивировать комплект драйверов в его рабочей области.

    String workdir= Platform.getStateLocation(jdbc_bundle).toPortableString();
    
  4. Программно добавлять файлы драйверов и соответствующим образом изменять файл MANIFEST.MF комплекта драйверов.

  5. Программная загрузка комплекта драйверов из рабочей области

    getBundleContext().installBundle("file:/"+workdir);
    
  6. Используйте bundle.start (), stop (), uninstall () при необходимости при программном изменении списка драйверов.

...