Допускает ли OSGI JNDI сосуществование с вызовами JNDI из кода, отличного от OSGI?

В главе 126 спецификации OSGI Enterprise Release 5 упоминается совместимость:

«Поддержка традиционной модели программирования JNDI, используемой клиентами Java SE и Java EE».

и использование кода, не поддерживающего OSGI:

«Клиенты и поставщики контекста JNDI, которые не знают об OSGi, используют статические методы для подключения к реализации JRE JNDI. Класс InitialContext обеспечивает доступ к контексту от поставщика, а поставщики используют статические методы NamingManager для преобразования объектов и поиска контекстов URL. Это традиционная модель не знает об OSGi и поэтому может надежно использоваться только в том случае, если последствия отсутствия осведомленности об OSGi устранены».

но мне не ясно, относится ли этот текст только к «устаревшему» коду, выполняемому внутри пакета OSGI, или также к коду вне контейнера OSGI, например, в сценарии, когда контейнер OSGI встроен в приложение.

В сценарии внедрения может быть код приложения как снаружи, так и внутри контейнера OSGI, который выполняет вызовы JNDI, и поскольку они выполняются в одной и той же JVM, они будут использовать реализацию JNDI.

Вопрос. Должна ли реализация OSGI JNDI, работающая во встроенном контейнере OSGI, разрешать коду, не поддерживающему OSGI, вне контейнера выполнять свои вызовы JNDI, как обычно, или требуется некоторый перенос на «поддержку OSGI»?

Пробуя это сам с Apache Karaf 2.3.0 (который использует Apache Aries JNDI 1.0.0), это, похоже, не работает, поскольку Apache Aries требует, чтобы клиентские вызовы JNDI исходили из пакета OSGI.
Частичная трассировка стека:

javax.naming.NoInitialContextException: The calling code's BundleContext could not be determined.
    at org.apache.aries.jndi.OSGiInitialContextFactoryBuilder.getInitialContext(OSGiInitialContextFactoryBuilder.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
    at javax.naming.InitialContext.init(InitialContext.java:242)
    at javax.naming.InitialContext.<init>(InitialContext.java:192)

Вопрос. Это правильное поведение или есть раздел спецификации, на который я могу сослаться и который нарушает это ограничение?


person mikewse    schedule 03.12.2012    source источник


Ответы (3)


Я столкнулся с той же проблемой при попытке развернуть Apache Karaf на Weblogic. Мы используем karaf через мост сервлетов — в weblogic развернута война, которая соединяет все http-запросы с karaf.

Я работаю со следующими приложениями в weblogic:

  1. app1 (использует JNDI)
  2. приложение2
  3. karaf-bridge (соединяет запросы к Карафу)

Как только karaf запустит реализацию Aries JNDI, работающую внутри Karaf, устанавливает InitialContextFactoryBuilder внутри javax.naming.NamingManager в свою собственную реализацию. NamingManager содержит статическую ссылку на построитель фабрики начального контекста, поэтому любая реализация, независимо от того, работает ли она в среде OSGI, устанавливает эту статическую ссылку, становится поставщиком JNDI.

В моем случае, когда app1 (не OSGI) пытается создать новый InitialContext, Aries JNDI пытается разрешить его с помощью BundleContext и терпит неудачу.

Я исправил это, используя несколько очень уродливых хаков, которые включали извлечение пакета javax.naming из jre и установку его в виде пакета в karaf.

Итак, ответ на ваш вопрос: я думаю, что проблема действительно в jre, а не в OSGI, в том, как управляется поиск JNDI.

person 6ton    schedule 27.06.2013

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

Я бы рекомендовал создать единый пакет со всеми jar-файлами, необходимыми для JNDI, и экспортировать все пакеты. Затем используйте Dynamic-Import: *, чтобы использовать его. В нашем случае это сработало (приложение Eclipse RCP с JBoss 5 JNDI, используемое для вызовов EJB).

Однако, если вам нужен JNDI внутри и снаружи контейнера и вы не хотите бороться с загрузкой классов, я бы рекомендовал добавить все jar-файлы в путь к классам приложений. Таким образом, он должен быть доступен во всем вашем приложении.

person Sebastian Łaskawiec    schedule 22.12.2012

Apache Aries, похоже, подумал об этом и предоставил реализацию построителя исходной фабрики контекстов JRE (org.apache.aries.jndi.JREInitialContextFactoryBuilder), которая, похоже, работает. Однако, чтобы это сработало, мне пришлось изменить код Aries, который регистрирует построитель фабрики начального контекста JVM. Может быть другой (и, возможно, лучший) способ добиться этого. Но это, похоже, сработало.

Также обратите внимание, что проблема не ограничивается установкой InitialContextFactoryBuilder в NamingManager. Та же проблема возникает для ObjectFactoryBuilder (который снова задается широко JVM в NamingManager). В зависимости от провайдера JNDI, к которому вы пытаетесь подключиться, вам может потребоваться изменить и эту часть кода JNDI Aries. например для соединения Tibco EMS JNDI мне пришлось настроить код для OSGiObjectFactoryBuilder из Aries, чтобы он возвращал специфичную для Tibco ObjectFactory. Это можно легко обобщить, используя значение среды Context.OBJECT_FACTORIES.

Я поднял JIRA для того же — https://issues.apache.org/jira/browse/ARIES-1127

person A.J.    schedule 25.10.2013