Utilizar el Java Native Interface (JNI)

En el JDK 1.1, la M�quina Virtual Java est� almacenada como una librer�a compartida (o librer�a de enlace din�mico en Win32). Podemos introducir la VM en nuestra aplicaci�n nativa, enlazando la aplicaci�n con la librer�a. El JNI soporta un API de "Invocation" invocaci�n que permite cargar, inicializar, y llamar a la M�quina Virtual Java. De hecho, la forma normal de arrancar el int�rprete Java, java, no es m�s que un sencillo programa C que analiza los argumentos de la lin�a de comandos y llama a la M�quina Virtual Java a trav�s del API Invocation.

.�Llamar a la M�quina Virtual Java

Para ilustrar como llamar a la M�quina Virtual Java, escribiremos un programa C que la invoque y llame al m�todo Prog.main definido en Prog.java.

public class Prog {
 public static void main(String[] args) {
  System.out.println("Hello World" + args[0]);
 }
}

El c�digo C de invoke.c empieza con una llamada a JNI_GetDefaultJavaVMInitArgs para obtener losa valores para la inicializaci�n por defecto (tama�o de la pila, etc) Luego llama a JNI_CreateJavaVM para cargar e inicializar la M�quina Virtual. JNI_CreateJavaVM rellena dos valores de retorno.

  • jvm se refiere la M�quina Virtual creada. Se puede utilizar para destruir la M�quina Virtual, por ejemplo.
  • env es un puntero a interface JNI que el thread actual puede utilizar para acceder a las caracter�sitcas Java, como llamar a un m�todo Java.

Observa que despu�s de que JNI_CreateJavaVM haya retornado satisfactoriamente, el thread nativo, se introduce a s� mismo en la M�quina Virtual Java y por lo tanto se est� ejecutando como si fuera un m�todo nativo. La �nica diferencia es que no existe el concepto de retorno de la M�quina Virtual Java. Por lo tanto, las referencias locales creadas despu�s no ser�n liberadas hasta que se llame a DestroyJavaVM.

Una vez que se ha creado la M�quina Virtual Java, se pueden realizar llamadas normales del JNI, por ejemplo a Prog.main. DestroyJavaVM intenta descargar la MV. (En el JDK 1.1 la M�quina Virtual Java no puede ser descargada; por lo tanto DestroyJavaVM siempre devuelve un c�digo de error.)

Se necesita compilar y enlazar invoke.c con las librer�as Java distribuidas con el JDK 1.1. En Solaris, se puede utilizar el siguiente comando para compilar y enlazar invoke.c.

cc -I<where jni.h is> -L<where libjava.so is> -ljava invoke.c

En Win32 con Microsgt Visual C++ 4.0, la l�nea de comandos es.

cl -I<where jni.h is> -MT invoke.c -link <where javai.lib is>\javai.lib

Aquellos que trabajen en el entorno MacOS deber�n referirse al API JManager, que forma parte del MacOS Runtime for Java (MRJ). Se utiliza este API para incluir aplicaciones Java en aplicaciones MAC.

Al ejecutar el programa resultante desde la l�nea de comandos, es posible que obtengamos el siguiente mensaje de error.

Unable to initialize threads: cannot find class java/lang/Thread
Can't create Java VM

Este mensaje de error indica que se ha seleccionado err�neamente el valor para la variable vm_args.classpath. Por otro lado, si el error indica que no puede encontrar libjava.so (en Solaris) o javai.dll (en Win32), a�adiremos libjava.so a nuestro LD_LIBRARY_PATH en Solaris, o javai.dll en nuestro path de ejecutables en Win32. Si el programa muestra un error diciendo que no puede encontrar la clase Prog, debemos asegurarnos de que el directorio que contiene Prog.class tambi�n est� en la variable vm_args.classpath.

.�A�adir Threads Nativos

El API Invocation tambi�n permite a�adir threads nativos a una VM Java que se est� ejecutando y convertir los propios threads en threads Java. Esto requiere que la M�quina Virtual Java utilice internamente threads nativos. En el JDK 1.1, esta caracteristica s�lo funciona en Win32. La versi�n Solaris de la M�quina Virtual Java utiliza soporte de threads de nivel de usuario y por lo tanto es incapaz de a�adir threads nativos. Una futura versi�n del JDK para solaris soportar� threads nativos.

Por lo tanto, nuestro programa de ejemplo, attach.c, s�lo funcionar� en Win32. Es una variaci�n de invoke.c. En lugar de llamar a Prog.main en el thread principal, el c�digo nativo espande cinco threads y espera a que finalicen antes de destruir la M�quina Virtual Java. Cada thread se a�ade a s� mismo a la M�quina Virtual Java, llama al m�todo Prog.main, y finalmente se borra de la M�quina Virtual antes de terminar. Observa que el tercer argumento de AttachCurrentThread est� reservado y siempre debe ser NULL.

Cuando se llama a DetachCurrentThread, todas las referencias locales pertenecientes al thread actual ser�n liberadas.

.�Limitaciones del API Invocation en el JDK 1.1

Como se mencion� anteriormente, existe un n�mero de limitaciones en la implementaci�n del API Invocation en el JDK 1.1.

  • La implementaci�n de thredas a nivel de usuario en Solaris requiere que la M�quina Virtual Java redireccione ciertas llamadas al sistema. El juego de llamadas redireccionadas realmente incluye: read, readv, write, writev, getmsg, putmsg, poll, open, close, pipe, fcntl, dup, create, accept, recv, send, etc. Esto podr�a causar efectos indeseados en aplicaciones nativas, que tambi�n dependan de llamadas al sistema.
  • No se pueden a�adir threads narivos a la M�quina Virtual Java bajo Solaris. AttachCurrentThread simplemente falla en Solaris (a menos que se llame desde el thread principal que cre� la M�quina Virtual).
  • No se puede destruir la M�quina Virtual Java sin terminar el proceso. La llamada a DestroyJavaVM simplemente devuelve un c�digo de error.

Estos problemas ser�n corregidos en futuras versiones del JDK.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO