Подтвердить что ты не робот

Поддерживает ли 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.
Частичная stacktrace:

javax.naming.NoInitialContextException: The calling code 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)

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

4b9b3361

Ответ 1

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

Я запускаю следующие приложения в weblogic:

  • app1 (использует JNDI)
  • app2
  • karaf-bridge (запросы мостов в Karaf)

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

Я поднял JIRA за то же самое - https://issues.apache.org/jira/browse/ARIES-1127