Estoy tratando de crear una aplicación Java simple que use JNI para llamar a algunas funciones nativas. He seguido los ejemplos en la Guía de programación de JNI y parece que no puedo hacer que funcionen. Tengo el siguiente programa Hola Mundo, escrito en Java:¿Este error está causado por el acceso a una biblioteca de 64 bits por un programa Java que se ejecuta en una JVM de 32 bits?
class HelloWorld {
private native void print();
public static void main(String [] args) {
new HelloWorld().print();
}
static {
System.load("/home/mike/Desktop/libHelloWorld.so");
}
}
Compilo usando javac HelloWorld.java
, al igual que lo normal.
que también tienen la aplicación C de la función de impresión, en el archivo HelloWorld.c:
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj) {
printf("Hello world!\n");
return;
}
Luego ejecutar javah -jni HelloWorld
, y finalmente el siguiente:
gcc34 -shared -fpic -o libHelloWorld.so -I/<path to JDK>/include -I/<path to JDK>/include/linux HelloWorld.c
gcc34 es el nombre del programa GCC en mi máquina aquí en el trabajo (no controlo eso) y obviamente coloco el camino real al JDK en ese comando. Cuando ejecuto mi programa, utilizando el estándar java HelloWorld
, me sale un error que dice lo siguiente:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/mike/Desktop/libHelloWorld.so: /home/mike/Desktop/libHelloWorld.so: wrong ELF class: ELFCLASS64 (Possible causes: architecture word width mismatch)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1778)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1674)
at java.lang.Runtime.load0(Runtime.java:770)
at java.lang.System.load(System.java:1003)
at HelloWorld.<clinit>(HelloWorld.java:8)
Could not find the main class: HelloWorld. Program will exit.
Sé que estoy ejecutando una JVM de 32 bits (y por desgracia no es así, a partir de ahora, estoy permitido obtener una JVM de 64 bits). Intenté decirle a GCC que compilara en modo de 32 bits con la opción "-m32", pero no tenemos (y de nuevo, no podemos) lo que necesitamos para eso. EDITAR: pude mover mis archivos a una máquina capaz de compilar en modo de 32 bits. Así que lo hice, y luego verifiqué que mi archivo libHelloWorld.so era de 32 bits ejecutando file libHelloWorld.so
y obtuve ELF32-bit MSB dynamic lib SPARC Version 1, dynamically linked, not stripped, no debugging information available
. También ejecuté java -version
y obtuve Java HotSpot(TM) Server VM (build <blah>, mixed mode)
por lo que parece que esta JVM se está ejecutando en modo de 32 bits.
¿Por qué sigo recibiendo este error?
+1 para una pregunta muy bien descrita. –