2011-05-20 32 views
5

Un problema: la mia applicazione utilizza due librerie che utilizzano versioni incompatibili di una terza libreria. Qualcuno conosce qualche metodo per l'isolamento delle classi?Come utilizzare due classi incomprimibili con lo stesso nome completo?

Ho sentito parlare di programmi di caricamento di classi, ma non capisco, come potrebbero aiutare - se cariceremo una versione di classe, non possiamo caricarne un'altra - la classe è già stata caricata?

Penso anche a Spring, ma non so se fornisce un tale isolamento.

+0

Prendo queste due classi non in spazi dei nomi separati? –

+0

Non capisco cosa significhi "spazio dei nomi" nel contesto di Java. Un nome di pacchetto? Lascia che siano in pacchetti diversi se è importante. – Nulldevice

+0

Scusa, sì, intendevo pacchetti. Inoltre, ho letto male la tua domanda, quindi non penso sia pertinente! –

risposta

1

se avremo caricare una versione di classe, non siamo in grado di caricare un altro - La classe è già stata caricata?

Non vero. Il programma di caricamento classi è considerato parte dell'identità della classe. Se è caricato da un altro classloader, è considerato una classe diversa.

+0

Significa che possiamo gestire le classi come oggetti java? Ad esempio, li fuori in matrice o lista, o creare più di una istanza? – Nulldevice

+1

@Nulldevice Le classi possono essere istanziate solo dal bytecode, da classloader. Tuttavia, sì, sono oggetti e possono essere messi in array o liste. Penso che solo i ClassLoaders avrebbero bisogno di fare queste cose. –

2

I ClassLoaders sono fondamentalmente gli elementi che danno significato alle classi nella JVM. Formano una gerarchia per cui la radice si trova nella JVM e carica le classi java. ApplicationClassLoader è il primo ClassLoader che devi considerare, poiché carica tutte le classi della tua applicazione.

Quando una classe viene caricata, tutti i suoi riferimenti ad altre classi vengono risolti e queste classi vengono caricate. La JVM fornisce di default un sistema dove i classloader chiedono ai loro genitori prima di vedere se hanno già caricato una classe. In caso contrario, cercano nel classpath

Due classi possono essere isolate se vivono in 2 diversi classloader e non nel classloader dell'app. Non è difficile da fare. Devi solo creare un classloader (come URLClassLoader) specificando il suo genitore e il suo classpath (il luogo in cui è presente il bytecode)

quindi, gli dici di caricare una classe. Chiederà al genitore, e se la classe non è ancora stata caricata, cercherà il suo classpath e lo caricherà. Se crei un altro classloader collegato allo stesso genitore, le classi caricate dal primo non saranno mai viste dai secondi come se fossero fratelli. E la seconda lattina carica una classe con lo stesso nome senza alcun problema

Questo è abbastanza un buon isolamento

app server utilizzare un'altra forma di delega di avere un isolamento franca tra le applicazioni. ridefiniscono un classloader che si estende, per esempio, URLClassLoader e invertire il processo di delega da parte di iniziare a cercare le classi nel loro percorso di classe prima, poi chiedere al genitore

-1

Se almeno una delle librerie è open source e la libreria da cui dipendono è open source, non è necessario scherzare con i programmi di caricamento classi. Basta rinominare in blocco tutti i pacchetti in una delle versioni della libreria da cui dipendono, assicurandosi di cambiare anche tutto il codice che si riferisce a quei pacchetti. Hey presto - nessun scontro di nomi. Questo è ciò che Sun ha effettivamente fatto per il JDK, quando hanno incluso Xerces e Xalan dietro le quinte.

+0

Cosa succede se dico che si tratta di un progetto sviluppato da circa 50 ingegneri del software? Non voglio essere responsabile della risoluzione dei bug di migliaia di righe di codice. Non è così facile cambiare le versioni di alcune librerie, anche open source. – Nulldevice

+0

È sufficiente scrivere uno script che esegue i necessari rinominazioni ed eseguire tale script su ogni nuova versione rilasciata. Fai attenzione a 'Class.forName', ma dovrebbe essere relativamente semplice. –

+0

Signore, ha decine di migliaia di righe di codice - stai scherzando? – Nulldevice

Problemi correlati