2009-12-13 21 views
8

estoy usando el GlassFish v3 publicado recientemente y durante el uso de bibliotecas nativas GlassFish se quejan de forma intermitente Glassfish biblioteca nativa de carga (.dll, .so)

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

El procedimiento para cargar bibliotecas nativas en el comunicado de glassfish anterior (v2. 2) era simplemente poner los archivos .dll en GLASSFISH_HOME \ lib. Ahora no sé si hay una carpeta mágica en v3 y si hay algo que decir. También he comprobado la pantalla de administración y hay dos variables que creo que están relacionadas con mi problema: Prefijo de ruta de la biblioteca nativa y Sufijo de ruta de la biblioteca nativa. He estado buscando en Internet para encontrar una descripción adecuada de lo que hacen y cómo debo usarlos, pero aparentemente a nadie le gusta hablar sobre ellos.

Respuesta

3

Lo primero: una clase nativa determinada solo se puede cargar en un cargador de clases.

Segundo: cada aplicación web en un contenedor servlet tiene su propio cargador de clases.

Tercero: debe tener mucho cuidado al codificar el código nativo para permitir que sus clases sean basura.

Resultado: una vez que carga el código nativo en una aplicación web, es probable que obtenga estos errores si intenta descargarlo y volver a cargarlo.

Estoy, hasta cierto punto, omitiendo la variación realmente simple sobre este tema: simplemente cargar dos webapps diferentes con la misma clase nativa.

Algunas personas prefieren cargar el código nativo en el cargador de clases del sistema para evitar este problema.

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

Un lib nativa sólo puede ser cargado una vez en la JVM y obtendrá ese mensaje de error cada vez que se carga una nueva versión de la clase llamada (la clase en la que reside la llamada System.loadLibrary(String)) en una redistribución Más sobre esto a continuación.

El procedimiento para cargar bibliotecas nativas en la versión anterior de glassfish (v2.2) era simplemente poner los archivos .dll en GLASSFISH_HOME\lib.

Bueno, esta es en realidad solo la primera parte de la historia. Para cargar una biblioteca nativa, tiene que ponerla en la ruta de la biblioteca y para cargarla desde el código de Java. Para ello, la convención es incluir un inicializador estático como sigue:

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

    native void doFoo(); 
    } 
} 

Suponiendo que está trabajando con una aplicación web, una buena práctica es la de no colocar las bibliotecas nativas o sus interfaces JNI bajo WEB-INF/lib o WEB-INF/classes a evitar problemas al volver a cargar la aplicación, como se mencionó anteriormente. En otras palabras, la clase que llama a System.loadLibrary(String) debe ser cargada por un cargador de clases que no se vea afectado al volver a cargar la aplicación web.

Así que mi pregunta es: ¿dónde pusiste ese código?

PD: Otra opción sería verificar si el dll ya está disponible antes de cargarlo, pero yo no haría eso.

Cuestiones relacionadas