Utilizar el Java Native Interface (JNI)

En el JDK 1.1, la Mquina Virtual Java est almacenada como una librera compartida (o librera de enlace dinmico en Win32). Podemos introducir la VM en nuestra aplicacin nativa, enlazando la aplicacin con la librera. El JNI soporta un API de "Invocation" invocacin que permite cargar, inicializar, y llamar a la Mquina Virtual Java. De hecho, la forma normal de arrancar el intrprete Java, java, no es ms que un sencillo programa C que analiza los argumentos de la lina de comandos y llama a la Mquina Virtual Java a travs del API Invocation.

.Llamar a la Mquina Virtual Java

Para ilustrar como llamar a la Mquina Virtual Java, escribiremos un programa C que la invoque y llame al mtodo Prog.main definido en Prog.java.

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

El cdigo C de invoke.c empieza con una llamada a JNI_GetDefaultJavaVMInitArgs para obtener losa valores para la inicializacin por defecto (tamao de la pila, etc) Luego llama a JNI_CreateJavaVM para cargar e inicializar la Mquina Virtual. JNI_CreateJavaVM rellena dos valores de retorno.

  • jvm se refiere la Mquina Virtual creada. Se puede utilizar para destruir la Mquina Virtual, por ejemplo.
  • env es un puntero a interface JNI que el thread actual puede utilizar para acceder a las caractersitcas Java, como llamar a un mtodo Java.

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

Una vez que se ha creado la Mquina 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 Mquina Virtual Java no puede ser descargada; por lo tanto DestroyJavaVM siempre devuelve un cdigo de error.)

Se necesita compilar y enlazar invoke.c con las libreras 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 lnea 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 debern 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 lnea 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 errneamente 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), aadiremos 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 tambin est en la variable vm_args.classpath.

.Aadir Threads Nativos

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

Por lo tanto, nuestro programa de ejemplo, attach.c, slo funcionar en Win32. Es una variacin de invoke.c. En lugar de llamar a Prog.main en el thread principal, el cdigo nativo espande cinco threads y espera a que finalicen antes de destruir la Mquina Virtual Java. Cada thread se aade a s mismo a la Mquina Virtual Java, llama al mtodo Prog.main, y finalmente se borra de la Mquina 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 sern liberadas.

.Limitaciones del API Invocation en el JDK 1.1

Como se mencion anteriormente, existe un nmero de limitaciones en la implementacin del API Invocation en el JDK 1.1.

  • La implementacin de thredas a nivel de usuario en Solaris requiere que la Mquina 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 podra causar efectos indeseados en aplicaciones nativas, que tambin dependan de llamadas al sistema.
  • No se pueden aadir threads narivos a la Mquina Virtual Java bajo Solaris. AttachCurrentThread simplemente falla en Solaris (a menos que se llame desde el thread principal que cre la Mquina Virtual).
  • No se puede destruir la Mquina Virtual Java sin terminar el proceso. La llamada a DestroyJavaVM simplemente devuelve un cdigo de error.

Estos problemas sern corregidos en futuras versiones del JDK.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.