Hibernate, JDBC-драйвер и проблема OSGi - PullRequest
5 голосов
/ 25 марта 2009

Я столкнулся с несколько неприятной проблемой. Я использую Apache Felix в качестве моей платформы OSGi, и я также использую Hibernate для проблем постоянства.

Я использую версию Hibernate "osgi-bundle" (com.springsource.org.hibernate-3.2.6.ga.jar). Насколько я знаю, это Hibernate Core с некоторыми дополнительными osgi-метаданными, установленными в META-INF / MANIFEST.mf. Эта информация (Package-Export и Package-Import) жизненно важна для ОСГИ-систем.

Моя проблема в том, что пакет Hibernate не может найти мои JDBC-драйверы. Очень неправильно добавлять операторы импорта в комплект Hibernate из источника. Должен быть лучший способ решить эту проблему.

Ответы [ 5 ]

7 голосов
/ 13 апреля 2009

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

Обычный способ загрузки драйверов JDBC с Class.forName(<jdbc class name>) не работает внутри OSGi, потому что в этом случае Hibernate попытается загрузить драйвер, но не найдет его, как Hibernate (и не должен ) импортировать пакет драйвера JDBC.

Диспетчер драйверов JDBC также пытается проявить смекалку, выясняя, должен ли загрузчик класса вызывающего класса видеть драйвер, и это также конфликтует с OSGi.

Если вы используете Spring для настройки Hibernate, то я предлагаю вам использовать класс SimpleDriverDataSource, так как это работает в OSGi, и Spring позволяет вам настраивать Hibernate с конкретным источником данных, а не передавать имя класса, которое Hibernate необходимо создать.

Как только вы преодолеете эту проблему, вы, вероятно, столкнетесь с проблемами Hibernate, не видя классов вашего домена. У меня есть только опыт работы с подходом сопоставления XML, с которым я думаю, что в OSGi проще, так как я думаю, что способ аннотаций требует некоторого вида AOP-ткачества, и это еще одна проблема в OSGi.

В настоящий момент, если вы не используете что-то вроде dm-сервера Spring, вам нужно будет гораздо ближе познакомиться с механизмом загрузки классов Java и с тем, как вы можете использовать подход OSGi к сервисам, чтобы обойти несовместимости между vanilla Java и миром OSGi. .

В частности, посмотрите, как корпоративные библиотеки используют загрузчик классов контекста, и как вы можете управлять этим. Я использую Spring dm для переноса унаследованного кода в сервисы OSGi, поскольку это облегчает управление загрузчиком классов контекста.

3 голосов
/ 01 июля 2009

В пакете OSGi вы можете видеть только классы и ресурсы из пакетов, которые вы импортировали. Пакет Hibernate не импортирует (и не должен) импортировать классы вашего домена. Поэтому, когда Hibernate пытается обработать файл сопоставления XML, он будет жаловаться, что не может найти сопоставляемый класс (класс вашего домена).

Мы решаем эту проблему, используя политику друзей Equinox, поэтому каждый пакет, который предоставляет доменные объекты, является партнером по загрузке классов Hibernate. Мне не очень нравится этот подход, но у меня нет времени, чтобы написать (надеюсь) элегантное решение, которое у меня в голове.

Как я уже говорил в моем предыдущем посте, манипулирование загрузчиком классов контекста, вероятно, является лучшей долгосрочной ставкой, когда речь заходит о Hibernate.

3 голосов
/ 25 марта 2009

Вы позаботились о правильном заказе комплектации? Существует способ установить начальный уровень каждого пакета, чтобы ваша система могла корректно загрузиться. Может потребоваться правильный начальный уровень комплектов, если некоторые активаторы пытаются получить услуги напрямую. В случае, если услуги недоступны, потребители услуг просто застрянут.

Попробуйте установить правильные начальные уровни для ваших пакетов и посмотрите, работает ли он. Конкретно вам придется запустить пакет с драйверами JDBC, прежде чем переходить в спящий режим.

Другая проблема может заключаться в том, что у вас есть нерешенные зависимости. Убедитесь, что все есть. Вы можете сделать это, получив консоль OSGi и запросив список услуг. В Equinox это сводится к аргументу командной строки -console и командам "ss", за которыми следуют команды "diag" в оболочке OSGi.

РЕДАКТИРОВАТЬ (ответ на ваш комментарий):

Драйверы регистрируются по их интерфейсу. Тогда Hibernate, вероятно, ищет драйвер по его интерфейсу, поэтому нет необходимости импортировать определенные классы драйверов. В любом случае это привело бы к нежелательной зависимости от конкретного класса реализации.

1 голос
/ 02 января 2010

Я не пробовал этого (так как я являюсь анти-RDBMS и, следовательно, анти-ORM), но одним из решений может быть использование фрагментов OSGi.

Создайте фрагмент, содержащий классы вашего домена, и укажите в качестве хоста пакет Hibernate. Этот фрагмент должен экспортировать пакеты классов вашего домена.

Аналогично, вы можете сделать то же самое для драйвера JDBC, который вы хотите использовать. Возьмите классы драйверов и передайте их фрагменту OSGi с Hibernate в качестве пакета хоста. Однако вам не нужно экспортировать пакеты драйверов, поскольку они будут использоваться только пакетом Hibernate.

Я подозреваю, что фрагменты не были полностью поддержаны Феликсом 9 месяцев назад, но теперь они, похоже, таковы: http://osgithoughts.blogspot.com/2009/09/felix-now-fully-supports-osgi-fragments.html

1 голос
/ 07 мая 2009

Я встречал похожую проблему некоторое время назад. Решение состояло в том, чтобы зарегистрировать пакет jdbc-provider и jdbc-user как «друзья». Это связано с тем, что один пакет не может использовать классы (а также драйверы jdbc) из другого без явного объявления этого. Это было для «Затмения», поэтому я полагаю, что оно может вам помочь.

...