2009-12-13 15 views
8

Sto usando il Glassfish recentemente rilasciato v3 e durante l'utilizzo di librerie native GlassFish sarebbe intermittenza lamentarsi Glassfish libreria nativa di carico (.dll, .so)

glassfish SEVERE: java.lang.UnsatisfiedLinkError: 
Native Library already loaded in another classloader

La procedura per caricare librerie native nella versione precedente GlassFish (v2. 2) doveva semplicemente mettere i file .dll in GLASSFISH_HOME \ lib. Ora non so se c'è una cartella magica in v3 e se c'è qualcosa da dire. Ho anche controllato la schermata di amministrazione e ci sono due variabili che penso siano correlate al mio problema: Native Library Path Prefix e Native Library Path Suffix. Sto setacciando internet per trovare una descrizione adeguata di ciò che fanno e di come dovrei usarli, ma a quanto pare a nessuno piace parlarne.

risposta

3

Prima cosa: una determinata classe nativa può essere caricata solo in un caricatore di classe.

Seconda cosa: ogni app Web in un contenitore servlet ha un proprio caricatore di classe.

Terza cosa: bisogna fare molta attenzione nel codificare il codice nativo per consentire che le sue classi vengano raccolte.

Risultato: una volta caricato il codice nativo in una webapp, è probabile che si verifichino questi errori se si tenta di scaricare e ricaricare.

Sono in una certa misura, saltando la variazione molto semplice su questo tema: semplicemente caricando due diverse applicazioni web con la stessa classe nativa.

Alcuni utenti preferiscono caricare il codice nativo nel caricatore di classi di sistema per evitare questo problema.

4
java.lang.UnsatisfiedLinkError: Native Library already loaded in another classloader 

A lib nativo possono essere caricati solo una volta nella JVM e si otterrà quel messaggio di errore ogni volta che si carica una nuova versione della classe chiamante (la classe in cui risiede la chiamata System.loadLibrary(String)) su una redeploy. Maggiori informazioni su questo sotto.

La procedura per caricare librerie native nella release precedente GlassFish (v2.2) è stato quello di mettere semplicemente i file dll in GLASSFISH_HOME\lib.

Bene, questa è in realtà solo la prima parte della storia. Per caricare una libreria nativa, devi ovviamente metterla sul percorso della libreria e per caricarla dal codice Java. Per fare ciò, la convenzione è quello di includere un inizializzatore statico come questo:

class FooWrapper { 
    static { 
     System.loadLibrary("foo"); 
    } 

    native void doFoo(); 
    } 
} 

Supponendo che si sta lavorando con un'applicazione web, una pratica migliore è di non posizionare le librerie native o le loro interfacce JNI sotto WEB-INF/lib o WEB-INF/classes a evitare problemi durante il ricaricamento dell'applicazione, come menzionato sopra. In altre parole, la classe che chiama System.loadLibrary(String) deve essere caricata da un classloader che non è interessato dal ricaricamento dell'applicazione web stessa.

Quindi la mia domanda è: dove hai messo quel codice?

PS: Un'altra opzione sarebbe quella di verificare se la DLL è già disponibile prima di caricarla ma non lo farei.

Problemi correlati