2009-10-12 11 views
19

Questo è un problema comune. Sto usando 2 librerie A.jar e B.jar e queste dipendono da diverse versioni dello stesso barattolo.
Diciamo che a tempo di esecuzione ho bisogno THIS.xxxjarJava Classloader - come fare riferimento a diverse versioni di un jar

MY.jar 
    -> A.jar -> THIS.1.0.0.jar 
    -> B.jar -> C.jar -> THIS.5.0.0.jar 

posso compilare il vaso specifico (A.jar/B.jar) contro la sua dipendenza, ma in fase di esecuzione che ho a caricare solo 1 versione. Quale?
Caricamento solo 1 dipendenza (l'ultima versione) significa che il mio codice genererà probabilmente eccezioni in runtime se le librerie non sono compatibili con le versioni precedenti (ci sono librerie compatibili con versioni precedenti là fuori?).

In ogni caso, so che qualcosa come OSGi può risolvere questo problema.
Mi chiedo qual è il vecchio modo per risolvere questo tipo di problemi ...

Grazie mille

+0

È possibile ottenere questo? Come OSGi aiuta? Stiamo di nuovo introducendo una depenenza su OSGi che è un sovraccarico nello sviluppo tipico del software di prodotto (specialmente per embedded) – sskumar86

risposta

7

"Vecchio modo" che hai citato (e l'unico OSGI certamente utilizza sotto il cofano) è quello di installare il tuo ClassLoader per entrambi i rami delle dipendenze. Ecco come, ad esempio, i server delle applicazioni sono in grado di eseguire sia le versioni precedenti che quelle più recenti della stessa applicazione all'interno della stessa JVM.

Informazioni sulla gerarchia del classloader.

Nella configurazione, la parte difficile è il punto di congiunzione, dove le classi di entrambi i rami si incontrano. Nessuno dei due rami può utilizzare classi caricate in un altro. Il modo per farlo funzionare è assicurarsi che solo le classi caricate dal classloader di avvio (classi JRE) o dal programma di caricamento classi di MY.jar vengano passate a entrambi i rami.

1

molte librerie sono compatibili. Ma non tutto ..


Il vecchio modo è provare a dipendere da una sola versione.

È probabilmente più sicuro compilare entrambi con la stessa versione (più recente).
Almeno si verificano errori in fase di compilazione, anziché errori di runtime.

Se necessario, è possibile modificare un po 'la vostra biblioteca che funziona con la vecchia dipendenza ...
Ciò richiederebbe l'accesso alla fonte ...


Si prega di notare che la compatibilità in fase di compilazione non garantirà il corretto comportamento in fase di esecuzione. Si tratta di un passo, allora si può:

  • leggere il file WhatsNew per la nuova versione del vaso
  • un'occhiata su Internet per gli utenti dichiarano problemi di compatibilità
  • JUnits scrittura
  • confrontare i codici a entrambi i vasi
4

OSGi può risolvere questo problema. Un bundle OSGi non è altro che un vaso con versioni aggiuntive di metadati. Un pacchetto ha un numero di versione e specificherà i numeri di versione (o intervalli) dei barattoli dipendenti.

Dai un'occhiata a this introductory Javaworld article per ulteriori informazioni.

Per risolvere questo senza OSGi è necessario assicurarsi manualmente che si compilino e corrano con i jar compatibili. Come hai scoperto, non è necessariamente un compito banale. Poiché i vasi non identificano necessariamente le loro versioni, l'unico modo sicuro per fare ciò è registrare/confrontare checksum o firme.

1

Come accennato da KLE, l'approccio predefinito dipende dalla versione più recente. Non c'è garanzia, ma la maggior parte delle volte funziona. Probabilmente il modo migliore (pur essendo gonfio) sta usando OSGI per superarlo.

Problemi correlati