lunes, 27 de julio de 2015

1.5. Un vistazo más profundo a la arquitectura de J2ME (CLDC y MIDP).

Como ya hemos visto, J2ME se sustenta en dos bloques principales: la configuración y el perfil. Volviendo a repasar estos conceptos, una configuración define la plataforma mínima necesaria para un grupo de dispositivos que tienen similar memoria y capacidades de procesamiento. Se compone de una máquina virtual, unas características del lenguaje Java y un conjunto mínimo de clases que soporta ese grupo de dispositivos. Por otro lado, un perfil extiende una configuración y completa las necesidades específicas para una cierta familia de dispositivos. Un perfil tiene asociado un conjunto específico de bibliotecas mínimas.

J2ME presenta dos configuraciones: CLDC y CDC. La primera se dedica a dispositivos con estrictas limitaciones de memoria, capacidad de cálculo, consumo y conectividad de red. Por otro lado, CDC se encarga de dispositivos con más potencia. Parte de CLDC es un subconjunto de CDC, por lo que la portabilidad de aplicaciones se puede conseguir cuando nos movemos de un entorno más restringido a otro más rico. De la misma manera, y siguiendo en el hilo de la portabilidad, una aplicación en J2ME podrá ejecutarse en J2EE normalmente, salvo que se utilicen las bibliotecas específicas de J2ME.

Veamos más detalladamente algunas características de CLDC, ya que es la configuración en la que nos centraremos en este curso. Comencemos por las propiedades mínimas requeridas a un dispositivo para poder desarrollar con esta configuración:
  • De 160 a 512 Kbytes de memoria disponible para el entorno de Java.
  • Un procesador de 16 o 32 bits.
  • Consumo de energía bajo (generalmente utilizan baterías).
  • Permiten algún tipo de conectividad a una red (lo normal, es una conexión intermitente, con un ancho de banda bajo -sobre 9600 bps- y a menudo inalámbrica.
Al tener como objetivo dispositivos con prestaciones reducidas, CLDC elimina una gran cantidad de características que sí aparecen en J2SE, tanto en el propio lenguaje Java como en la máquina virtual, como por ejemplo:
  • Interfaz nativo de Java (Java Native Interface -JINI) (Máquina virtual). 
  • Cargadores de clases definidas por el usuario (Máquina virtual).
  • Grupos de hilos e hilos demonios (Máquina virtual).
  • Finalización (lenguaje Java).
  • Referencias débiles (Máquina virtual).
  • Reflexión (Máquina virtual).
  • Tipos de datos de punto flotante (lenguaje Java).
  • Algunos aspectos de seguridad y APIs (Máquina virtual).
  • Verificación de ficheros de clases (Máquina virtual).
  • Posee algunas limitaciones en las gestiones de errores (lenguaje Java).
Pero ¿qué razones se consideraron para eliminar esas prestaciones? Por supuesto, una de ellas se basa en cuestiones de ahorro de memoria, ya que el tamaño general del API queda reducido. Aunque otras también han sido quitadas por cuestiones de aligerar el procesador, como es el caso de las operaciones en punto flotante, o la verificación de las clases. Concretamente, esta operación, que identifica y rechaza ficheros de clases inválidas, se realizada en la máquina virtual en la edición J2SE, pero en ese caso aumenta su tamaño. Por esta razón, en J2ME la verificación se hace en dos partes: la primera, la preverificación, en un ordenador distinto; la segunda sí se lleva a cabo en el propio dispositivo, pero en este caso es mucho más simple y rápida.  Más adelante estudiaremos de manera más detallada el proceso de verificación.

Con respecto a la seguridad, al no definir CLDC completamente el sistema de seguridad de Java deben eliminarse prestaciones que sí figuran en el J2SE (por ejemplo, JNI, que permite la utilización de una biblioteca de clases escrita en otros lenguajes -enlazado en tiempo de ejecución) y que harían muy vulnerables las aplicaciones. Por ejemplo, sin este modelo de seguridad, un cargador de clases definido por el usuario podría alterar la forma en que el camino de las clases fuera recorrido, pudiendo una aplicación sustituir trozos de las bibliotecas del núcleo de Java y ganar acceso al dispositivo de tal forma que pudiera dañarlo.

También se considera la simple conveniencia como criterio: algunas clases pueden ser desarrolladas por los programadores basadas en otras que sí se mantienen. Igual ocurre con algunos métodos de clases. Por otro lado, otras clases se eliminan por que no tiene razón de ser: java.io.File tiene sentido si se trabaja en un sistema de ficheros, pero muchos dispositivos no disponen de él. En su lugar, CLDC utiliza las propias prestaciones del dispositivo.  Otro ejemplo en este sentido son la finalización de objetos, ya en el J2SE puede ocurrir que nunca se lleve a cabo. La eliminación de gestión de errores, por último, va en la linea de la utilidad de la acción, y del tiempo consumido en ello. Una excepción es un error que puede ser recuperable; un error es, por el contrario, representa errores muy serios y generalmente dependientes directamente del dispositivo, por lo que no merece la pena hacerlo.

En cuanto a la máquina virtual de CLDC, KVM, ésta requiere entre 40 y 80 Kbytes dependiendo de las opciones de compilación y el tipo de dispositivo para el que se compile.  Esto implica que se podrán ejecutar aplicaciones con un total de 128 Kbytes. Aparte de esto, se necesitan otros 32 Kbytes para memoria dinámica de la aplicación a ejecutar. KVM está implementada en C y está diseñada para ser tan completa y rápida como sea posible. De hecho, puede ejecutarse de un 30 a un 80% de la velocidad de la JVM.

Volviendo a la verificación de clases, la máquina virtual de Java estándar efectúa un proceso en tiempo de ejecución que se denomina verificación de clases, el cual se lleva a cabo antes de cargar ninguna clase en memoria. El objetivo es asegurar la integridad de los ficheros donde se almacena una clase Java y que el código en ella no intente acceder a memoria fuera de su espacio de nombres, eliminando la posibilidad de que pueda sustituir alguno de los paquetes del núcleo de Java (java.* o javax.*), y poniendo así en juego la seguridad del sistema.  Esta etapa juega un papel muy importante en el modelo de seguridad de Java.

Para que nos hagamos una idea, J2SE verifica, entre otras, estos puntos:
  • Inicialización de todas las variables locales antes de su uso.
  • El constructor de un objeto debe ser llamado justo seguidamente de la creación del mismo, y antes de que se use.
  • Cada constructor tiene que comenzar con una llamada al constructor de su superclase.
  • Las variables locales y miembros estáticos deben contener referencias a objetos que sean asignables legalmente.
Si nos trasladamos a CLDC, este proceso será muy costoso en términos de uso de recursos, ya que requiere mucha memoria, procesador y espacio para código binario.  Es por esto por lo que los diseñadores de KVM decidieron hacer la verificación de clases de manera diferente a como se hace con JVM. Así, antes de que la clase se llegue a emplear en el dispositivo, ésta es modificada externamente por una utilidad "preverificadora". La idea es añadir al fichero clase generado por javac nuevo código que identifique la clase como válida (pasa a ser una clase verificada). Seguidamente, se transfiere al dispositivo y la KVM sólo tiene que comprobar si esta información está o no presente o contiene o no la información correcta. En cualquiera de los dos casos negativos, el proceso de carga se interrumpe y se lanza una excepción. Esta comprobación se puede hacer justo cuando se carga la clase o como parte del proceso de instalación de la aplicación. En cualquier caso es un proceso más rápido que la preverificación y requiere menos memoria.

Pasando seguidamente a los perfiles,  éstos suministran un interfaz de usuario, métodos de entrada y mecanismos de persistencia, así como un entorno de desarrollo completo para un conjunto específico de dispositivos, soportando sus características concretas. Los perfiles son necesarios porque las configuraciones no presentan ninguna de estas  prestaciones.  La razón principal para crear diferentes perfiles es el hecho de que, por ejemplo, un teléfono móvil tiene diferentes funcionalidades y conductas que una lavadora (al primero se le requerirá envío y recepción de correo electrónico, pero no funciones de inicio y parada programadas, como a la lavadora). Así, J2ME oferta al programador el concepto de perfil, el cual define una plataforma común para un grupo determinado de dispositivos, los cuales comparten características y funciones.  Un dispositivo puede cubrir más de un perfil.

Los perfiles se asentan sobre una configuración dada y utilizan los servicios que ofrece, aunque es la parte de la arquitectura J2ME que más cerca se encuentra del aparato físico. Para el caso de CLDC, su único perfil es MIDP (Mobile Information Device Profile), el cual cubre el mercado de dispositivos móviles, que comparten características como memoria limitada, pantalla pequeña, conexión a algún tipo de red inalámbrica y mediante banda ancha limitada y alimentados normalmente por baterías . El software desarrollado con MIDP se ejecuta en el KVM suministrado por CLDC.

Las aplicaciones MIDP se denominan "MIDlets", las cuales pueden utilizar tanto las facilidades aportadas por MIDP como las APIs que MIDP hereda de CLDC, pero nunca acceden directamente al sistema operativo subyacente, por lo que no serían portables. Un MIDlet consiste en una clase Java, como mínimo, derivada de la clase abstracta MIDP, y que se ejecutan en un entorno de ejecución dentro de la máquina virtual, la cual provee un ciclo de vida bien definido controlado mediante métodos de la clase MIDlet que cada MIDlet debe implementar. También estas aplicaciones usan métodos de esta clase abstracta para conseguir servicios de su entorno. Un grupo de MIDlets que están relacionados se suelen agrupar en un MIDlet suite. Todos estos MIDlet se empaquetan,  instalan, desinstalan y borran como una única entidad y comparten recursos tanto en tiempo de ejecución  (se ejecutan en la misma máquina virtual, lo que implica que compartan instancias de de todas las clases de Java cargadas en la máquinavirtual), como estáticos (el almacenamiento persistente se gestiona en el nivel de suite).

Veamos seguidamente algunos detalles sobre los dispositivos que soportan MIDP. Comenzando con los requerimientos de memoria, MIDP necesita 128 KB de RAM disponible para la implementación correspondiente. A esta cantidad debemos sumarle la que necesita CLDC y como mínimo 32 Kbytes para almacenar la pila de la aplicación, tamaño que obliga al programador a tener bastante cuidado a la hora de diseñar las aplicaciones. Además, los dispositivos MIDP cuentan con 8 Kbytes como mínimo de memoria no volátil que se utiliza como almacenamiento persistente, que no se borra tras apagar el aparato (salvando el problema del cambio de batería).

Sobre las pantallas de los dispositivos, la especificación MIDP indica que ésta requiere 96 pixels de ancho por 54 de alto y que debe soportar al menos dos colores (como es el caso de muchos teléfonos móviles, en contraposición con algunas PDAs que tienen pantallas de 160 pixels en ambas direcciones y 65.536 colores diferentes).

Con respecto a los tipos de entradas del dispositivo, el rango es muy amplio: desde los que tienen un teclado alfanumérico completo, hasta aquellos que permiten escribir en ciertas áreas de la pantalla, pasando por los teclados de los teléfonos móviles. La especificación mínima requiere un teclado que permita marcar los números del 0 al 9, junto con el equivalente a las teclas del cursor y un botón de selección.

MIDP no asume que los dispositivos estén permanentemente conectados a una red, ni siquiera que soportan TCP/IP, pero que sí tienen algún tipo de acceso a una red. En este sentido, la especificación si establece que soporte HTTP 1.1, bien mediante una pila de protocolos o una pasarela WAP.

También los sistemas operativos de los dispositivos tienen restricciones con respecto a MIDP. Por ejemplo, deben ofrecer un entorno de ejecución protegido donde la máquina virtual pueda correr, o algún tipo de apoyo para el acceso a una red, como puede ser el caso de un API para programar sockets, sobre el cual el protocolo HTTP se pueda implementar.  Es el sistema operativo el que ofrecerá acceso al teclado y al posible dispositivo puntero, entregando los correspondientes eventos que surjan. Además, será el encargado de abstraer al MIDP la pantalla, ya que será visto por él como una matriz de pixels, y de ofrecer un interfaz para el acceso al almacenamiento persistente.

Un aspecto muy importante a tener en cuenta es el de la seguridad. J2SE ofrece un modelo de seguridad potente y flexible, y a la vez, costoso en términos de memoria, razón por la cual CLDC y MIDP incluyen ningún tipo de prueba en las llamadas al API de las que incluye J2SE. Para un usuario de un dispositivo móvil esto puede suponer un peligro, porque el MIDlet no está limitando en ningún sentido. Es por esto por lo que el usuario debería ser bastante cuidadoso a la hora de instalar nuevas aplicaciones.

Los MIDlets necesitan empaquetarse antes de que sean trasferidos a un dispositivo para su instalación: tanto la subclase MIDlet correspondiente como las clases que requiera y el resto de ficheros necesarios (como pueden ser ficheros de imágenes) constituirán un único fichero JAR, incluyendo el conocido como manifiesto del JAR (contiene información de empaquetado que indica qué se almacena en el fichero JAR). Adicionalmente se emplea otro segundo fichero conocido como Java Application Descriptor (JAD). El manifiesto del JAR almacena el dispositivo, el nombre y la versión del MIDlet suite en el JAR correspondiente, así como qué ficheros de clase se corresponde con cada MIDlet, información útil para instalar los MIDlets. El segundo es un fichero de texto que contiene una lista de atributos junto con su valor correspondiente. Algunos atributos están también contenidos en el manifiesto del JAR, ya que éste puede ser grande y su transferencia lenta debido a la baja velocidad del acceso a la red que suelen tener estos dispositivos, en vez de descargar el JAR completo, se descarga el fichero JAD, el cual es mucho más pequeño y rápido de transferir, se muestra por la pantalla del dispositivo y se decide si se instala o no.

No hay comentarios.:

Publicar un comentario