2012-12-03 13 views
13

Kapitel 126 der OSGI Enterprise Release 5 specification erwähnt Kompatibilität:Ermöglicht OSGI JNDI die Koexistenz mit JNDI-Aufrufen aus Nicht-OSGI-Code?

"Unterstützen Sie das Modell traditionelle JNDI Programmierung von Java SE und Java EE-Clients verwendet."

und die Verwendung von OSGi-nicht bewusst Code:

„Clients und JNDI Context-Provider, die keine Kenntnis von OSGi sind verwenden statische Methoden zur JRE JNDI Implementierung verbinden Die Initial Klasse ermöglicht den Zugriff auf ein. Kontext von einem Provider und Provider verwenden die statischen NamingManager-Methoden, um Objektkonvertierung und URL-Kontexte zu finden Dieses traditionelle Modell ist OSGi nicht bekannt und kann daher nur zuverlässig verwendet werden, wenn die Folgen dieser fehlenden OSGi-Awareness verwaltet werden. "

aber es ist mir nicht klar, ob dieser Text nur auf „Legacy“ Code gilt innerhalb eines OSGi-Bundle ausgeführt wird, oder auch außerhalb der OSGi-Container zu codieren, f ex in einem Szenario, in dem die OSGi-Container in eingebettet ist eine Bewerbung.

In einem Einbettungsszenario kann sowohl außerhalb als auch innerhalb des OSGI-Containers Anwendungscode vorhanden sein, der JNDI-Aufrufe ausführt. Wenn sie in derselben JVM ausgeführt werden, teilen sie sich die JNDI-Implementierung.

Frage: Sollte ein OSGi JNDI Implementierung läuft in einem eingebetteten OSGi-Container OSGi-Code nicht bewusst außerhalb des Behälters erlauben auszuführen seine JNDI wie gewohnt Anrufe oder einige Portierung auf „OSGi-Bewusstsein“ erforderlich?

Probieren Sie dies mit Apache Karaf 2.3.0 (die Apache Aries JNDI 1.0.0 verwendet) dies scheint nicht zu funktionieren, wie Apache Wides erfordert JNDI-Client-Aufrufe aus einem OSGI-Bundle stammen.
Teilstacktrace:

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) 

Frage: Ist das richtige Verhalten, oder gibt es einen Abschnitt der Beschreibung ich darauf verweisen kann durch diese Einschränkung verletzt wird?

Antwort

0

Ich bin mir nicht sicher, ob ich das Problem richtig verstehe ... JNDI ist ein Service Provider Interface, und es benötigt einige zugrunde liegende Implementierung mit zu laufen. Sie müssen lediglich den OSGI-Container bereitstellen.

Ich würde empfehlen, ein einzelnes Bündel mit allen Gläsern zu erstellen, die von JNDI benötigt werden, und alle Pakete zu exportieren. Dann benutze Dynamic-Import: * um es zu benutzen. Es funktionierte in unserem Fall (Eclipse RCP-Anwendung mit JBoss 5 JNDI für EJB-Aufrufe).

Wenn Sie jedoch JNDI innerhalb und außerhalb des Containers benötigen und Sie nicht mit Classloading kämpfen möchten, würde ich empfehlen, alle JARs zum Klassenpfad der Anwendungen hinzuzufügen. Auf diese Weise sollte es in Ihrer gesamten Anwendung zugänglich sein.

1

Ich stieß auf dasselbe Problem beim Versuch, Apache Karaf auf Weblogic bereitzustellen. Wir verwenden Karaf über eine Servlet-Bridge - in weblogic wird ein War bereitgestellt, der alle http-Anfragen an Karaf überbrückt.

ich mit den folgenden Anwendungen auf WebLogic leite:

  1. app1 (verwendet JNDI)
  2. app2
  3. karaf-Brücke (Brücken-Anfragen zu Karaf)

Sobald Wenn Karaf die Aries JNDI-Implementierung startet, die in Karaf ausgeführt wird, legt InitialContextFactoryBuilder in javax.naming.NamingManager auf seine eigene Implementierung fest. NamingManager enthält eine statische Referenz auf den ursprünglichen Builder für Kontextfactory. Daher wird unabhängig davon, ob die Implementierung in einer OSGI-Umgebung diese statische Referenz festlegt, der JNDI-Provider.

In meinem Fall, wenn App1 (nicht-OSGI) versucht, einen neuen InitialContext zu erstellen, versucht Aries JNDI, es mithilfe des BundleContext aufzulösen, und schlägt fehl.

Ich reparierte dies mit einigen sehr hässlichen Hacks, die das Entpacken des javax.naming Pakets von jre und die Installation als Paket in Karaf beinhalteten.

So die Antwort auf Ihre Frage: Ich denke, das Problem ist wirklich in der JRE und nicht mit OSGI, wie JNDI Lookup verwaltet wird.

0

Apache Widder scheint darüber nachgedacht zu haben und eine Implementierung von JRE ursprünglichen Kontext Factory Builder (org.apache.aries.jndi.JREInitialContextFactoryBuilder) zur Verfügung gestellt, die zu funktionieren scheint. Damit dies jedoch funktioniert, musste ich den Aries-Code ändern, der den JVM-Wide-Initial-Context-Factory-Builder registriert. Es kann einen anderen (und möglicherweise besseren) Weg geben, dies zu erreichen. Aber das schien zu funktionieren.

Beachten Sie auch, dass das Problem nicht auf InitialContextFactoryBuilder in NamingManager gestoppt wird. Dasselbe Problem tritt für ObjectFactoryBuilder auf (das wiederum im NamingManager JVM-weit festgelegt ist). Abhängig von dem JNDI-Anbieter, mit dem Sie eine Verbindung herstellen möchten, müssen Sie möglicherweise auch diesen Teil des Aries JNDI-Codes ändern. z.B. Für die Tibco EMS JNDI-Verbindung musste ich den Code für OSGiObjectFactoryBuilder von Aries optimieren, um eine Tibco-spezifische ObjectFactory zurückzugeben. Dies kann leicht mithilfe des Context.OBJECT_FACTORIES-Umgebungswerts verallgemeinert werden.

Ich habe eine JIRA für die gleiche - https://issues.apache.org/jira/browse/ARIES-1127

ausgelöst