2012-12-03 21 views
13

capitolo 126 del OSGI Enterprise Release 5 specification menziona compatibilità:OSGI JNDI consente la coesistenza con chiamate JNDI dal codice non OSGI?

"Sostenere il modello di programmazione JNDI tradizionale utilizzato dai client Java SE e Java EE."

e l'uso del codice di OSGi-inconsapevoli:

"I clienti ei fornitori JNDI contesto che non sono a conoscenza di OSGi usano metodi statici per la connessione alla realizzazione JRE JNDI La classe InitialContext fornisce l'accesso a una. Contesto da un provider e i provider utilizzano i metodi statici NamingManager per eseguire la conversione dell'oggetto e individuare i contesti URL. Questo modello tradizionale non è a conoscenza di OSGi e può quindi essere utilizzato in modo affidabile solo se vengono gestite le conseguenze di questa mancanza di consapevolezza OSGi. "

ma non mi è chiaro se questo testo si applica solo ai "legacy" codice eseguito all'interno di un fascio di OSGi, o anche al codice di fuori del contenitore OSGi, ex f in uno scenario in cui il contenitore OSGi è incorporato nel un applicazione.

In uno scenario di incorporamento, è possibile che ci sia un codice di applicazione sia all'esterno che all'interno del contenitore OSGI che esegue chiamate JNDI e poiché eseguono nella stessa JVM condivideranno l'implementazione JNDI.

Domanda: caso un OSGI JNDI implementazione in esecuzione in un contenitore OSGi incorporato consentire codice OSGi-ignari di fuori del contenitore di svolgere la sua JNDI chiamate come al solito, o qualche porting a "OSGi-consapevolezza" richiesta?

Provando questo con Apache Karaf 2.3.0 (che utilizza Apache Aries JNDI 1.0.0), questo non sembra funzionare, poiché Apache Aries richiede che le chiamate client JNDI provengano da un bundle OSGI.
stacktrace parziale:

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) 

Domanda: È questo il comportamento corretto, o c'è una sezione della specifica posso fare riferimento a che viene violato da questa limitazione?

risposta

0

Non sono sicuro di aver compreso correttamente il problema ... JNDI è un'interfaccia provider di servizi e richiede un'esecuzione sottostante da eseguire. Tutto ciò che devi fare è provvedere al provisioning del contenitore OSGI.

Si consiglia di creare un singolo bundle con tutti i jar necessari per JNDI ed esportare tutti i pacchetti. Quindi usa Dynamic-Import: * per usarlo. Ha funzionato nel nostro caso (applicazione RCP Eclipse con JBoss 5 JNDI utilizzata per le chiamate EJB).

Tuttavia, se è necessario JNDI all'interno e all'esterno del contenitore e non si desidera lottare con Classloading, è consigliabile aggiungere tutti i jar al classpath delle applicazioni. In questo modo dovrebbe essere accessibile in tutta la tua applicazione.

1

Ho riscontrato lo stesso problema durante il tentativo di distribuire Apache Karaf su Weblogic. Usiamo karaf attraverso un ponte servlet - una guerra viene distribuita in weblogic che collega tutte le richieste http a karaf.

Sono in esecuzione con le seguenti applicazioni su WebLogic:

  1. app1 (usa JNDI)
  2. app2
  3. karaf-ponte (bridge richieste a Karaf)

Appena come karaf avvia l'implementazione di JNDI dell'Aries in esecuzione all'interno di Karaf imposta InitialContextFactoryBuilder all'interno di javax.naming.NamingManager per la sua implementazione. NamingManager contiene un riferimento statico al costruttore di factory di contesto iniziale, quindi qualsiasi implementazione, indipendentemente dal fatto che sia in esecuzione in un ambiente OSGI, imposta questo riferimento statico come provider JNDI.

Nel mio caso quando app1 (non-OSGI) prova a fare un nuovo InitialContext, Aries JNDI prova a risolverlo usando BundleContext e fallisce.

Ho risolto questo problema utilizzando alcuni hack molto brutti che comportavano l'estrazione del pacchetto javax.naming da jre e l'installazione come pacchetto in karaf.

Quindi la risposta alla tua domanda: Penso che il problema sia davvero nella jre e non con OSGI su come viene gestita la ricerca JNDI.

0

Apache Aries sembra aver pensato a questo e ha fornito un'implementazione del costruttore di contesto iniziale di JRE (org.apache.aries.jndi.JREInitialContextFactoryBuilder) che sembra funzionare. Tuttavia, affinché ciò funzioni, ho dovuto modificare il codice Aries che registra il generatore di factory di contesto iniziale di JVM. Potrebbe esserci un altro (e forse migliore) modo di raggiungere questo obiettivo. Ma questo sembrava funzionare.

Inoltre, si noti che il problema non si ferma su InitialContextFactoryBuilder impostato su NamingManager. Lo stesso problema si pone per ObjectFactoryBuilder (che viene nuovamente impostato su JVM in NamingManager). A seconda del provider JNDI a cui si sta tentando di connettersi, potrebbe essere necessario modificare anche quella parte del codice JNDI di Aries. per esempio. per la connessione JNDI Tibco EMS, ho dovuto modificare il codice per OSGiObjectFactoryBuilder da Aries per restituire un ObjectFactory specifico Tibco. Questo può essere facilmente generalizzato utilizzando il valore di ambiente Context.OBJECT_FACTORIES.

Ho sollevato una JIRA per lo stesso - https://issues.apache.org/jira/browse/ARIES-1127