java jni static-libraries java-8 static-linking

java - Vinculación de la biblioteca estática con JNI



static-libraries java-8 (2)

Las versiones de Java anteriores a Java 8 requieren que el código nativo esté en una biblioteca compartida, pero he leído que con Java 8 es posible usar bibliotecas vinculadas estáticas con JNI. He buscado ejemplos pero no he podido encontrar ninguno.

¿Cómo puedo vincular estáticamente una biblioteca JNI en mi aplicación java?


En referencia al JEP 178 al que se ha vinculado en su comentario, no tiene que hacer nada diferente. System.loadLibrary ahora cargará tanto bibliotecas dinámicas como estáticas.

No requiere cambios en el código Java existente para utilizar una biblioteca nativa estática en lugar de una biblioteca nativa dinámica. Una invocación de método del formulario System.loadLibrary ("foo"), en particular, debería poder cargar la biblioteca "foo" independientemente de si esa biblioteca se proporciona en forma estática o dinámica.

Probablemente solo necesites asegurarte de que java.library.path esté configurado correctamente.


La especificación Java SE 8 se ha modificado para admitir la vinculación estática y la vinculación estática se implementa en el JDK. Esto se menciona brevemente en la especificación para System.loadLibrary . Las secciones de la Especificación JNI a la que hace referencia están aquí y aquí .

Las firmas de métodos nativos y los tipos de datos son los mismos para los métodos vinculados estática y dinámicamente. Sin embargo, es posible que tenga que hackear los archivos make de JDK para vincular su biblioteca estáticamente.

Una diferencia significativa es la forma en que se inicializan las bibliotecas estáticas. Las bibliotecas dinámicas se inicializan llamando a la función JNI_OnLoad y se desinicializan llamando a JNI_OnUnload . Cada biblioteca dinámica puede tener su propia versión de estas funciones. Si hay múltiples bibliotecas vinculadas estáticamente, claramente no todas pueden tener funciones con estos mismos nombres. Para una biblioteca estática llamada libname las funciones de carga / descarga son JNI_OnLoad_libname y JNI_OnUnload_libname .

La función JNI_OnLoad_libname debe devolver un valor de JNI_VERSION_1_8 o superior. Si no lo hace, la JVM ignorará la biblioteca estática.

Básicamente, si llama a System.loadLibrary("foo") , el sistema busca la función JNI_OnLoad_foo en la imagen ejecutable en ejecución, y si se encuentra, asume que la biblioteca está enlazada estáticamente y se buscan sus métodos nativos dentro del ejecutando la imagen. Si no se encuentra JNI_OnLoad_foo , entonces se realiza la búsqueda y carga habitual de las bibliotecas dinámicas, y los métodos nativos se vinculan desde la biblioteca dinámica que se encuentra.