2011-09-19 26 views
9

In base alla documentazione OSGi, OSGi è progettato per aiutare a prevenire i problemi di ClassPath.OSGi: come garantire la coerenza del classpath?

Ad esempio, da "OSGi in azione":

ClassNotFoundExceptions quando iniziano l'applicazione perché il percorso classe non era corretta. OSGi può aiutare assicurando che le dipendenze del codice siano soddisfatte prima di consentire l'esecuzione del codice.

Tuttavia, dal momento che abbiamo passato la nostra applicazione java a OSGi, vedo più ClassNotFoundExceptions e soprattutto NoClassDefFoundErrors che mai. Le classi che in precedenza caricavano correttamente non vengono più trovate dal classloader OSGI, e peggio: si ottiene l'errore in fase di esecuzione, il che significa che non è possibile controllarlo facilmente eccetto testando manualmente ogni angolo della propria applicazione.

Ad esempio, la nostra applicazione era in esecuzione felicemente con OSGi, ma abbiamo ricevuto rapporti dai beta tester che non potevano più esportare documenti in PDF. In effetti, quando ho guardato dentro, ho scoperto che questa funzionalità ha causato un'eccezione da registrare:

java.lang.NoClassDefFoundError: org/w3c/dom/Node 

Quindi, è in realtà la creazione OSGi più problemi di quanti ne risolva classpath?

e, ancora più importante: come posso verificare che il mio percorso di classe sia coerente, con tutte le istruzioni Import-Package necessarie, ecc. prima del Ho letto su di loro in segnalazioni di bug?

+0

"se non per testare manualmente ogni angolo della vostra applicazione" - test automatizzati ERM? (lo stesso vale per qualsiasi applicazione) Se prima di eseguire la migrazione avevi suite di test, avresti individuato questi errori prima dei testers. Per verificare che i tuoi bundle si colleghino correttamente devi eseguire alcuni test di integrazione: stiamo utilizzando Pax Exam per questo e abbiamo brevi test di integrazione (bundle corrente e collaboratori) e alcuni test end-to-end più lunghi (testare l'intera app). – earcam

risposta

12

Un'applicazione OSGi sarà non gettare ClassNotFoundExceptions e NoClassDefFoundErrors se vostro manifesto è corretta. Cioè, devi dire a OSGi quali pacchetti utilizza il tuo bundle; se non lo fai correttamente o onestamente, allora OSGi non può aiutarti. In altre parole: GIGO (Garbage In, Garbage Out).

Ad esempio, si utilizza il pacchetto org.w3c.dom ma non lo si elenca nell'istruzione Import-Package. Pertanto OSGi non sa che è necessario accedere a quel pacchetto e quindi quando si tenta effettivamente di caricare classi da quel pacchetto, non sono disponibili.

Pertanto, è necessario assicurarsi che l'istruzione Import-Package sia accurata rispetto ai pacchetti effettivamente utilizzati dai pacchetti. La buona notizia è che lo strumento "bnd" può farlo per te generando il manifest bundle, utilizzando l'analisi bytecode per trovare tutti i pacchetti con riferimenti statici.

Aggiornamento: L'ultima domanda chiede come verificare che i pacchetti siano coerenti prima di rilevare problemi in fase di esecuzione. Bnd ha una funzione di "verifica" che fa esattamente questo. In realtà se usi Bnd per generare manifest, in primo luogo, non avrai bisogno della funzione di verifica. Tuttavia, non so nulla del tuo processo di compilazione, quindi potresti trovare difficoltà nel passare a una build basata su Bnd a breve termine ... in questo caso sarebbe relativamente semplice aggiungere l'attività di verifica come post- fase di elaborazione dopo la compilazione. Tuttavia, ti consiglio comunque di provare a utilizzare Bnd in precedenza nel processo di creazione.

+0

Non conoscevo la funzionalità di verifica del bnd, molto utile sapere! – amarillion

+3

"se il manifest è corretto" .... cioè se il manifest è esattamente come la particolare implementazione che stai usando si aspetta che sia e tu non stia facendo nulla che i progettisti OSGI e i programmatori della particolare implementazione stai usando haven ' Ho pensato a Sono d'accordo con amarillion - OSGI è un incubo di problemi di classe non trovati, con quasi nessun meccanismo di risoluzione dei problemi disponibile. Può essere utile per gli utenti finali avere una maggiore flessibilità di implementazione, ma è HELL per gli sviluppatori. – user252690

+0

@ user252690 È facile per i codardi anonimi fare fandonie sugli insulti su Internet. Se ti calmi e decidi di imparare qualcosa, sai dove trovare persone sensibili che possono aiutarti. –

2

Penso che il problema qui sia che non si specifica l'insieme corretto di pacchetti/classi utilizzati dal pacchetto (utilizzando la direttiva Import-Packages in MANIFEST). A meno che OSGi non ne sia a conoscenza, non può davvero aiutare!

Non sei sicuro di come stai creando i tuoi bundle OSGi, ma dovresti controllare lo Maven bundle plugin, che risolve i problemi di specificare esplicitamente i pacchetti di importazione (almeno per quelli di compilazione). Vedi http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin#Importing%20packages.

+0

+1. Giusto per aggiungere: il Maven Bundle Plugin è basato su Bnd, quindi tutto ciò che ho detto nella mia risposta sull'utilizzo di Bnd vale anche per il Maven Bundle Plugin. Se la tua build non è attualmente basata su Maven, non è necessario spostarsi su Maven per ottenere questa funzionalità. –

1

Non sto rispondendo alla domanda centrale, ma fornendo la mia soluzione per un problema simile.

Nel mio caso, ho avuto questa struttura di classe:

  • interface javax.script.ScriptEngineFactory
  • class pkga.A implements ScriptEngineFactory
  • class pkgb.B extends A

Il mio codice primario del progetto era in classe B e questa classe estesa A in un vaso dipendente. Utilizzando

<Export-Package>pkgb.*</Export-Package> 

era insufficiente, ho ricevuto un errore che lamentano la mancanza di javax.script.ScriptEngineFactory. Questo è strano in quanto fa parte del JDK 8 standard, si noti che il codice nel pacchetto pkgbnon ha esplicitamente riferimento javax.script.*; forse lo scrittore Manifest non sapeva che questa interfaccia doveva essere esportata?

Ho trovato questa aggiunta alla direttiva Export-pacchetto ha risolto il problema

<Export-Package>pkgb.*,javax.script.*</Export-Package> 
Problemi correlati