2009-12-08 9 views
46

OSGi consente di determinare le dipendenze tramite Import-Package, che collega solo un singolo pacchetto (esportato da qualsiasi pacchetto) e Require-Bundle, che esegue il collegamento alle esportazioni di un bundle specifico.Quando dovrei usare Import-Package e quando dovrei usare Require-Bundle?

Nella creazione di un'applicazione OSGi greenfield, quale approccio devo utilizzare per rappresentare le dipendenze? La maggior parte dei bundle sarà interna, ma ci saranno alcune dipendenze da pacchetti esterni (open-source).

+4

Da http://eclipsesource.com/blogs/2009/07/14/why-i-cant-recommend-using-import-package/: "Look, Require-Bundle è qualcosa che è stato utilizzato in Eclipse per per un po ', soprattutto per motivi legacy. Non ne raccomandiamo l'uso più. Import-Package è migliore se si desidera un accoppiamento più flessibile tra i bundle. Tuttavia, tieni presente che i pacchetti di split del dolore possono causare. " –

risposta

45

Credo che Require-Bundle sia una cosa di Eclipse (che ora è stata implementata nelle specifiche OSGi per ospitare Eclipse). Il modo "puro" OSGi è quello di utilizzare Import-Package, in quanto disaccoppia in modo specifico il pacchetto dal pacchetto che lo fornisce. Dovresti dichiarare dipendenze sulla funzionalità di cui hai bisogno (l'API Java fornita da una determinata versione di un determinato pacchetto) invece di dove proviene quella funzionalità (che non dovrebbe essere rilevante per te). Ciò mantiene la composizione dei pacchi più flessibile.

analogia JavaScript: è come rilevare se un browser Web supporta una determinata API anziché inferire da quale stringa di utente-agente indica che tipo di browser è.

Peter Kriens della OSGi Alliance ha altro da dire su questo OSGi blog.

Probabilmente l'unico caso in cui è necessario utilizzare Require-Bundle è se si dispone di pacchetti divisi, ovvero un pacchetto distribuito su più bundle. I pacchetti divisi sono ovviamente molto scoraggiati.

+2

Sia Require-Bundle che Import-Package sono definiti nelle specifiche OSGi; non esiste una variante "pura" dei due. – AlBlue

+2

@AlBlue: aggiornata la mia risposta per rendere più chiaro che mentre Require-Bundle si trova nella specifica, viene reso disponibile solo per la compatibilità con Eclipse. – Thilo

+6

Penso che Thilo abbia ragione. Come ha detto Peter Kriens nell'articolo: "Require-Bundle ha un appeal intuitivo difficile da negare". Ma sta legando inutilmente i pacchi insieme. Nel mondo Java lo paragonerei a IoC vs guardando direttamente alle dipendenze. Un esempio è in funzione del pacchetto 'commons-logging' in funzione del pacchetto API' commons-logging'.In quest'ultimo caso è possibile scambiare facilmente il bundle 'common-logging' con il bundle dell'adattatore SLF4J appropriato che esporta anche il pacchetto API' commons-logging' e quindi crea senza problemi un bridge da 'commons-logging' a SLF4J. –

3

Credo che Importa-pacchetto offra un accoppiamento più flessibile e dovrebbe essere preferito. Lo uso quando dichiaro dipendenze su pacchetti che non possiedo, come ad esempio slf4j, e posso scambiare implementazioni come vorrei. Io uso Require-Bundle quando la dipendenza è qualcosa su cui ho il controllo, come i miei bundle, perché ogni cambiamento importante sarebbe passato attraverso me stesso comunque.

-1

Non sono convinto che l'utilizzo di Import-Package sia migliore, perché la mia aspettativa predefinita quando si lavora con un bundle è di lavorare con l'API pubblica associata. Per questo motivo, Require-Bundle ha più senso.

+5

Questa affermazione non ha senso. La tua giustificazione è la ragione per cui utilizzerai Importa pacchetto invece di Richiedere-Bundle. Gestisci l'API pubblica e non preoccuparti di chi lo fornisce. Non si lavora con il pacchetto, si lavora con l'API. – Robin

13

Favore Importa-Pacchetto su Richieste-Bundle.

require-Bundle:

  • specifica il fascio esplicito (e versione) da usare. Se un pacchetto requirde deve essere refactored e un pacchetto spostato altrove, i dipendenti devono modificare il loro MANIFEST.MF
  • ti dà accesso a TUTTE le esportazioni del pacchetto, indipendentemente da cosa siano e indipendentemente dal fatto che siano necessarie . Se le parti non è necessario avere le proprie dipendenze dovrai coloro ai
  • fasci possono essere riesportate
  • anche se scoraggiato, consente l'utilizzo di pacchetti frazionate, per esempio: un pacchetto che si sviluppa su più fasci
  • può essere utilizzato per dipendenze non di codice, ad esempio: risorse, Guida, ecc.

Import-Package:

  • sciolto accoppiamento, solo il pacchetto (e versione) è specificato e il runtime trova il pacchetto richiesto
  • implementazioni effettivi possono essere swaped su
  • Dependent i pacchetti possono essere spostati in bundle diversi dal proprietario del pacchetto
  • Tuttavia, è necessario mantenere più metadati da mantenere (ad esempio: ciascun nome di pacchetto) a livelli inferiori di granularità
+0

Per Import-Package, cosa succede se hai bisogno di una versione specifica del pacchetto ma il pacchetto contiene effettivamente la versione? AFAIK, i pacchetti java non hanno versioni. –

0

Import-Package dovrebbe essere migliore, perché, come detto in precedenza, è possibile spostare un pacchetto da un fascio all'altro senza cambiare del client esistente MANIFEST.MF

Ma ...

C'è una ragione pratica per utilizzare Require-Bundle se si utilizza Eclipse per sviluppare i pacchetti:

Eclipse non utilizzare i pacchetti come unità di risoluzione. Usa pacchi. Cioè, se si utilizza un pacchetto di un pacchetto, Eclipse compila il pacchetto senza segnalare alcun problema con l'uso del resto dei pacchetti non importati da quel pacchetto.

Si potrebbe (tu sei umano) pensare che tutto sia OK e caricare il tuo pacchetto per la distribuzione ma ... il tuo pacchetto si romperà in fase di runtime.

Ne sono sicuro perché questo problema è successo (a me!) Oggi.

La soluzione migliore sarebbe quella di modificare il contenitore del classpath Eclipse ma ... se questo non verrà fatto ... si potrebbe decidere di evitare questo tipo di problemi che richiedono pacchetti, anziché pacchetti, pagando il prezzo indicato (nessun movimento di codice compatibile con le versioni precedenti tra i pacchetti).

0

Evita pacchetto di importazione. Poiché i pacchetti forniscono relazioni molti-a-molti tra i pacchetti, sono soggetti a cicli di dipendenza difficili da rilevare ed evitare.

Require-Bundle, d'altra parte, fa riferimento a un singolo fascio, rendendo il grafico delle dipendenze protetto dai cicli da un banale controllo in fase di compilazione. Con Require-Bundle è molto più semplice costruire architetture a livelli con un livello di astrazione inferiore isolato.

Problemi correlati