1/16/2004

MEJORAS QUE TRAJO CONSIGO EL J2SE1.4: WEBSTART (III)

Core Java Technology

Java Webstart

Es un sistema de despliegue de aplicaciones. Permite instalar software con un sólo click en un navegador web.

Está basado en el protocolo JNLP (Java Network & Launching Protocol).

Una aplicación JAWS se descarga, como si fuera un applet, de un servidor web remoto. La diferencia es que la aplicación se "cachea" en local, y se va actualizando mediante el "JAWS runtime system".

Las aplicaciones JAWS se ejecutan dentro de un sandbox, wrapper de seguridad que controla qué recursos del sistema se pueden utilizar y cuáles no. Si la aplicación es "de fiar" -trusted-, se puede traspasar el sandbox. Si la aplicación JAWS puede utilizar el paquete javax.jnlp, éste le ofrece opciones de acceso restringido a los recursos del sistema. P.e. una aplicación JAWS, mediante este paquete, podría grabar un fichero en local, pero SIEMPRE se utilizará una caja de diálogo para que el usuario lo autorice.

1/15/2004

MEJORAS QUE TRAJO CONSIGO EL J2SE1.4: NIO AVANZADO(II)

Java 2 Platform, Standard Edition (J2SE)

Brevemente, comento algunas características avanzadas de NIO:

1. MappedByteBuffers: permite asociar una porción del fichero en un buffer de memoria.
Es importante anotar que sólo carga en memoria bajo demanda -sólo lo que se está leyendo-.

2. E/S No Bloqueante:

ByteBuffer buffer = ByteBuffer.allocate( bufferSize );
Socket newSocket = ss.accept();
newSocket.configureBlocking( false );
SocketChannel sch = socket.getChannel();
buffer.clear();
sch.read( buffer );

La llamada a read devuelve un buffer vacío si no hay nada que leer, en lugar de quedarse esperando hasta que llegue el primer byte.


3. Multiplexación

Para realizar E/S multiplexada, en Java hasta ahora no quedaba más remedio que utilizar polling. Sin embargo, de los viejos tiempos de C nos llega el "selector": es un objeto que monitoriza un conjunto de canales, avisando cuando alguno tiene datos de entrada.
El método Selector.select() se queda bloqueado hasta que alguno de los canales está preparado:
while (true) {
selector.select();
// deal with new input ...
}


Interfaces de Red

La clase NetworkInterface provee acceso a objetos de nivel de sistema operativo que representan las interfaces.




MEJORAS QUE TRAJO CONSIGO EL J2SE1.4: NIO (I)

Java Technology

Ahora, con el J2SE1.5 a punto de caramelo, quizá es buen momento para ver cuáles fueron las mejoras de la versión anterior, que quizá no habéis llegado a utilizar.

Información tomada a partir del JDK1.4 Tutorial de Manning.

Este primer post trata sobre el NIO (New I/O):

El paquete java.nio aporta las siguientes características al preexistente java.io:
1. block-oriented: opera sobre bloques, buscando obtener las mismas prestaciones que otros lenguajes, como C ó C++.
2. Utilización de buffers directos, que no utilizan buffers Java.
3. E/S no bloqueante, simplificando la programación multithreading.

Los elementos fundamentales, que se añaden al concepto anterior de "stream", son los siguientes:
1. Canal -channel-: fuentes y destinos de datos secuenciales, solo que leen los datos en pedazos, no byte a byte. Además, un canal puede ser bidireccional.
2. Buffer: donde se almacenan los trozos de datos. Normalmente son muy grandes.

- Obtención de un canal:
FileInputStream fin = new FileInputStream( infile );
FileChannel inc = fin.getChannel();

- Creación de un buffer:
ByteBuffer buffer = ByteBuffer.allocate( 1024 );

Tb. existen los IntBuffer, ShortBuffer, FloatBuffer, ...

- Lectura:

Se pasa de:
public int read( byte[] b, int off, int len );
, a:
public int read( ByteBuffer dst );

- Escritura:

Se pasa de:
public void write( byte[] b, int off, int len );
, a:
public int write( ByteBuffer src );


Buffers

También se puede utilizar directamente un buffer mediante sus métodos get y put. Es importante entender que cuando se lee de un canal, se escribe en un buffer, y viceversa.


- Lectura y Escritura de otros tipos desde un ByteBuffer:

Aquí hay que recordar el tamaño en bytes de cada tipo: byte, short, float, ...

IMPORTANTE: la ordenación por defecto de un ByteBuffer es BigEndian (MSB antes), pero puede cambiarse mediante el método order(ByteOrder).

Realmente, esta nueva manera de implementar E/S me recuerda a la manera de C con la estructura FILE * y los métodos fopen, ... ¡qué tiempos!

Buffers Directos

En lugar de utilizar buffers intermedios en la JVM para interactuar con el exterior, se utiliza la memoria del entorno de ejecución directamente:

ByteBuffer buffer = ByteBuffer.allocateDirect( 1024 );

No es buena idea utilizarlo siempre, ya que cuesta más recursos. Sólo cuando sea necesario por velocidad.


File Locking

* Tipos de bloqueos:

1. Mandatory lock
Evita que un fichero o la porción de un fichero sea accedido.

2. Advisory lock
Evita que otros "locks" adquieran la misma región.

También hay otra diferenciación:

1. Exclusive
Como los bloqueos del synchronized.

2. Shared
No evitan que otros threads adquieran el lock, sino que evitan que bloqueos exclusivos lo hagan.




FileOutputStream fout = new FileOutputStream( "abc.txt" );
FileChannel fc = fout.getChannel();
FileLock fl = fc.lock( 20, 20, false );
, donde se están bloqueando los bytes 20 a 39 del fichero abc.txt, de manera exclusiva

Todo el fichero:
FileOutputStream fout = new FileOutputStream( "abc.txt" );
FileChannel fc = fout.getChannel();
FileLock fl = fc.lock();




1/14/2004

JAXB: ARQUITECTURA JAVA PARA XML BINDING

The Java(TM) Web Services Tutorial

Aunque es fundamental para comprender el esquema interno de XML, la utilización de JAXP (ya sea DOM o SAX) como parser se hace muy incómodo. Ya desde hace años JDOM viene a solucionar este problema, pero hacía falta una estandarización. JAXB puede resolver este problema.

Esto no quiere decir que DOM o SAX -en particular este último- dejen de utilizarse.

En JAXB tenemos dos pasos:

1. Enlazar (bind) el esquema para el documento XML.
2. Deserializar (unmarshal) el XML a objetos Java.

1. Binding

Primero, es necesario que el sistema comprenda cuál es la estructura del XML, lo cuál se realiza mediante la transformación del XmlSchema del documento a clases e interfaces Java.

JAXB exige que el XML tenga un esquema, y que cumpla el W3C XML Schema Language.

Para ello, se utiliza el Xml Java Compiler (xjc), que se encuentra en \jaxb\bin:

xjc -p <package> <XmlSchema>.xsd -d <directorio destino>

, que genera un conjunto de clases e interfaces, generalmente -por lo que estoy viendo-, para los elementos y los tipos compuestos, además de algún factory. Cada clase define sus métodos getter y setter para cada tipo de elemento y atributo.

2. Unmarshalling

Este paso crea, a partir de un fichero XML, un conjunto de instancias de las clases anteriormente generadas con xjc, en memoria.

Además de eso, el framework JAXB provee:
- javax.xml.bind: marshalling, unmarshalling, validación.
- javax.xml.bind.util: clases de utilidad.
- javax.xml.bind.helper: proveedores de implementación.

Sin meternos en detalles de implementación -para eso está el enlace de arriba-, la idea es que JAXB, al pasarle el nombre del XML, nos devuelve la instancia de la clase "root" del fichero XML -p.e. si el root se llama "Ciudad", la clase será Ciudad-.


Aunque no lo he probado, se supone que se puede realizar este proceso sobre multitud de fuentes: InputStreams, URLs, DOMs, o incluso eventos SAX!


Creación de un Documento

Los pasos son fáciles de imaginar:

1. Binding -como antes-.

2. Creación del Content Tree. Se crea el root del XML.

3. Marshalling.
Transformación a fichero XML.



Anotaciones

Hasta ahora hemos dado por hecho que los tipos de dato que selecciona el compilador xjc son los adecuados para nosotros, pero ¿y si no es así? ¿Y si deseamos que una de las clases generadas se llame de una manera determinada, o que un tipo XML se transforme a otro Java que no es el estándar?

Respuesta: Anotaciones XML. Forma parte del XmlSchema, normalmente arriba del todo, y define qué cambios con respecto a lo definido por defecto tiene que haber.





ALGUNOS PATRONES DE DISEÑO CLÁSICOS

Hillside.net - Design Patterns Book - DP Book

Lo mismo que el post anterior, pero sobre algunos patrones de diseño del GoF:

* Prototype: otra manera de creación de objetos, pero utilizando un prototipo como medio de creación de instancias. La propia clase tiene un método "clone" que implementa un deep copy. La utilidad de Prototype es sobre todo para evitar la proliferación de estructuras paralelas, como ocurre con el Factory Method, y es muy importante para el tema de instancias cargadas dinámicamente: el usuario no se entera de con qué subclase concreta está trabajando. De todas formas, me vendría bien un ejemplo más claro.

* Bridge: desacoplamiento "físico" entre la abstracción y la implementación en dos clases diferentes. Esta idea es la que utilizamos en la implementación de drivers, la que nos permite crear las diferentes capas de una aplicación.

* Decorator: adición dinámica de nuevas responsabilidades a un objeto. Para ello se utiliza una jerarquía de objetos que encapsulan los objetos a modificar, manteniendo su interfaz pero añadiendo -por "arriba" o por "abajo"- su funcionalidad. El planteamiento de este patrón es la modificación de partes visibles o externas del objeto. Para cambiar su comportamiento interno es más útil el patrón Strategy o State.

* Flyweight: objetos muy repetitivos que sólo se almacenan una vez -como los caracteres en un procesador de textos-. La información intrínseca -en este caso el ASCII code- se almacena en el objeto carácter, mientras que la información extrínseca -el contexto del carácter en cada una de sus ocurrencias, como tamaño, fuente, ...- tiene que ser conocida en algún otro sitio. Esto permite que un documento no crezca demasiado, pues el acceso a los caracteres se realiza mediante referencia. Si un documento no cambia mucho de fuente y tamaño, el tratamiento será sencillo.

* Chain of Responsibility: desacoplamiento entre el cliente y el servidor mediante una serie de objetos que se van encargando de partes de la petición, o se van pasando hasta que alguien puede responder adecuadamente (como el DNS). El concepto es el de "burocracia".

* Interpreter: es la creación de un autómata, no es nada más, donde cada clase tiene un método de interpretación con un argumento de contexto -para saber dónde está-, y que puede realizar operaciones de comprobación de la gramática. El árbol en sí suele ser un composite. Es válido para gramáticas sencillas -es lo que utilicé en el SGRT, sin saberlo ;) -.

* Mediator: un "manager" que se encarga de gestionar las interacciones de un conjunto de objetos, para así evitar un excesivo acoplamiento entre sí. Se puede implementar también como un observer, de manera que los objetos envían notificaciones al mediador cuando cambian de estado.

* Memento: patrón que permite capturar y externalizar el estado interno de un objeto, de manera que pueda ser restaurado a ese mismo estado más tarde. Aunque comprendo la idea, un ejemplo de cómo se utiliza exactamente el patrón no vendría mal.

* Strategy: definición de una familia de algoritmos para hacerlos intercambiables.


* Template Method: la superclase deja la implementación de partes del algoritmo como métodos redefinibles por las subclases, de manera que se puedan modificar fácilmente. Sigue el "principio de Hollywood: no nos llames, te llamaremos nosotros", refiriéndose a que sea el padre quien realice las operaciones.

* Visitor: cuando las clases de una jerarquía de clases invocan diferentes métodos dispares entre sí, quizá es mejor crear una jerarquía complementaria para cada tipo de método (métodos parecidos que se invocan desde diferentes subclases), de manera que se estructure todo mejor. El visitor permite que las operaciones relacionadas estén juntas en una misma clase, de manera que las clases de la primera estructura que lo necesiten, accederán como "visitantes" a esas operaciones.

ALGUNOS PATRONES J2EE

Sun Java Center - J2EE Patterns

A continuación pongo pequeños comentarios, basándome en los patrones clásicos de GoF, de los patrones J2EE más conocidos. Doy por hecho que primero os habréis leído la definición de cada patrón.

* Front Controller: ya conocido, es un MVC donde el controller utilizar una serie de dispatchers.

* Composite View Pattern: las JSP están constituidas por conjuntos de JSPs, a través de "includes".

* Session Facade: al igual que el patrón clásico Facade, en este caso es un Session Bean el que ejerce como tal.

* Service Locator: utilización de un singleton que permite encontrar el resto de EJBs. Esto permite no tener que utilizar JNDI constantemente desde el servidor.

* Value Object: en la comunicación c/s, cuando un EJB tiene multitud de propiedades, el acceso constante degrada las prestaciones. Para ello, un EJB devuelve un objeto ValueObject con todas sus propiedades, de manera que el cliente puede procesarlas localmente.

* Business Delegate: llega más allá del SessionFacade, encapsulando todo el tratamiento con los objetos de negocio (es quien interactúa con el cliente y con el service locator, por ejemplo). Se puede aprovechar como proxy para temas de caché, reintentos, etc.

* Data Access: las tareas sobre los datos suelen ser independientes del formato de esos datos. Es básicamente un Adapter.

* View Helper: encapsulamiento de la interacción de la lógica de negocio con la JSP mediante helpers (JavaBeans, por ejemplo), con métodos getters y setters si es posible.

* Dispatcher View: interactúa con el Front Controller para controlar el acceso a la vista JSP. También funciona de manera que la JSP tenga un View Helper. De esa manera se soluciona completamente el problema de acoplamiento entre las dos capas.

* Service To Worker: parecido al Dispatcher View, sólo que mientras que el Dispatcher View no instancia View Helpers, por lo que se entiende que el acceso a los datos externos sólo ocurre cuando ya se ha accedido a la vista, en el caso del Service To Worker el FrontController sí accede a diferentes View Helpers, de manera que el Dispatcher, cuando selecciona la vista, también interactúa con estos ViewHelpers. Básicamente, la diferencia fundamental es que el Dispatcher se preocupa de la elección del conteindo del modelo cuando se crea la vista, mientras que el ServiceToWorker ya crea un modelo intermedio antes.

* Value List Handler: También llamado Page-by-page Iterator. Stateful session bean que accede al DAO para que el cliente no tenga que realizar múltiples peticiones a través de la red. También ejerce de fachada.

* Fast Lane Reader: cuando los datos no cambian mucho y son de sólo lectura, la utilización de EJB Finders es tediosa y mala para las prestaciones del sistema. Este patrón accede directamente a la fuente de datos, e interactúa con el cliente, como si fuera un Entity Bean.

* Transfer Object: a mí me da la sensación de que es un Value Object con otro nombre, centrado en entities.

* Transfer Object Assembler: debido al problema de siempre con las comunicaciones, este patrón lo que hace es devolver al cliente un sólo objeto que sea "resumen" de diversos valores devueltos por session beans, entity beans, DAOs, etc.

* Composite Entity: igual que el Transfer Object, pero centrado en un Entity Bean particular.
En cuanto a la tesis, además de ver el resto de patrones J2EE para considerarlos en el diseño, estaría bien echar un vistazo al documento de diseño de VINI, donde parece que hay buenos diseños que estudiar. En principio yo tiraría por utilizar el patrón Data Access Object, tal y como recomienda J2EE y Fowler, pero habrá que ver.

* Composite Entity: un mapping directo entre el modelo relacional y el objetual (entity beans) no tiene en cuenta que los EBeans son mejores cuando la granularidad es gruesa. El Composite Entity modela un conjunto de objetos interrelacionados en lugar de representarlos independientemente. De esta manera sólo se tiene un Entity Bean, el que se comunica con este patrón, en lugar de considerar cada elemento compuesto como un entity bean.

MÉTODOS DE APRENDIZAJE AUTOMÁTICO PARA MODELADO DE ESTILO MUSICAL (II)

IEEE Computer Society

Uno de los métodos que se utiliza para generación de música por ordenador es el de predicción basado en diccionario. La idea es la de "parsear" una pieza musical ya existente, y proveer una regla de inferencia que permita seleccionar el "mejor" objeto musical que debería aparecer tras uno concreto -o tras un contexto-. Este método exige que el esquema de parsing:
1. intente maximizar el tamaño del diccionario, para obtener una mejor predicción.
2. recoja suficiente evidencia de que el objeto seleccionado es lo suficientemente fiable.

Otro método ya comentado, el de Markov, genera tablas enormes de "posibles futuros estados". El artículo comenta la utilización de "predicción selectiva" para conseguir que este modelo funcione con un tamaño variable de memoria.




El proyecto que se detalla en el artículo utiliza métodos basados en diccionarios para obtener un plan léxico con "motivos" a partir de una pieza musical, y sus probabilidades de predicción asociadas.

Para generar nuevas piezas, estos modelos predictivos navegan a través del árbol de predicción, buscando, a partir de un contexto determinado, si aparece un "motivo" en el árbol.





1/12/2004

TEMARIO DE INGENIERÍA DEL SOFTWARE II. PATRONES DE DISEÑO (II)

Hillside.net - Your Patterns Library

El "core" de la asignatura es la comprensión, conocimiento, y posterior maestría en la utilización adecuada de Patrones de Diseño en la creación de arquitecturas y diseños software acordes a lo requerido por los requisitos de la aplicación a realizar.

En este blog no pretendo explicar en detalle cada uno de los patrones, pues existen libros y URLs que lo hacen mucho mejor de lo que yo sería capaz. Sin embargo, quizá un párrafo resumen de cada patrón, que llegue algo más allá de los resúmenes que aparecen en las cubiertas de los libros, podría resultar útil.´
Además, a mí me vendrá bien para repasar ;)

Los patrones en la asignatura estarán divididos en dos partes:

1. Patrones Arquitectónicos
2. Patrones de Diseño



TEMARIO DE INGENIERÍA DEL SOFTWARE II (I)

Página Principal de Justo N. Hidalgo

Ya es época de plantear las asignaturas del segundo cuatrimestre, sobre todo aquellas que sufren cambios fundamentales con respecto al año pasado. Este es el caso de INgeniería del Software II, ya que la creación de la nueva asignatura optativa de quinto, "Gestión de Proyectos Tecnológicos", me permite "abandonar" un poco la parte más gerencial de la ISW, y centrarme en la parte técnica.

Obviamente, mientras no exista una carrera de Ingeniería del Software, o, al menos un itinerario intensivo, no puedo pretender enseñar TODO lo existente de la ingeniería del sw en dos asignaturas cuatrimestrales.

Ingeniería del Software I es una asignatura bien centrada -aunque todo es mejorable, obviamente-, que introduce qué es la ingeniería, qué es la ingeniería del sw, metodologías, ..., y que permite definir y utilizar el Proceso Unificado.

Mi planteamiento de Ingeniería del Software II es centrarme en un par de temas específicos de la ingeniería del software desde el punto de vista técnico, como es el diseño orientado a objetos mediante la utilización de patrones arquitectónicos y de diseño, y las nuevas tendencias de orientación a componentes, SOA, y creación de frameworks.

El año pasado, esta asignatura fue desde el principio un "cajón de sastre" donde meter muchos conceptos diferentes y no relacionados entre sí. Este año todo está mucho más cohesionado:

1. Introducción a la planificación de proyectos: aunque esto se ve con mucho más detalle en la asignatura optativa mencionada anteriormente, algo tiene que verse en la parte obligatoria de la carrera.
2. Análisis y diseño: arquitectura y patrones. Ya saben lo que es analizar y diseñar. Ahora enseñemos a los alumnos a hacerlo BIEN.
3. Tendencias de ingeniería: lo comentado anteriormente.

Sin embargo, me quedan temas sin tratar que son fundamentales -los temas que aparecen a continuación han sido tomados del IEEE/ACM CCSE (Computing Curriculum: Software Engineering), un intento bastante loable de estandarizar el conocimiento que un alumno de titulación de segundo ciclo debe conocer sobre la Ingeniería del Software. Obviamente, no pretendo que un alumno que no se especializa en este ámbito domine todas las áreas que aparecen en este documento, pero sí que domine las fundamentales, y haya oído hablar de algunas más.


Knowledge Areas:

1. CMP: Computing Essentials: OK.

2. FND: Mathematical & Engineering Fundamentals: OK.

3. PRF: Professional Practice:
Al no disponer de tiempo material en la carrera, se está realizando desde el año pasado un Ciclo de Inteligencia Emocional para Ingenieros en Informática que traten temas tales como la comunicación, asertividad, trabajo en equipo, etc.

4. MAA: Software Modeling & Analysis: OK (Ingeniería del Software I)

5. DES: Software Design: OK, excepto el DES.hci: Human Computer Interface Design.

6. VAV: Software Verification & Validation: OK (un capítulo en ISW I).

7. EVL: Software Evolution: OK, si se concibe desde el punto de vista iterativo del Proceso Unificado.

8. PRO: Software Process: OK.

9. Software Quality: casi nada. Daremos un poco de Métodos Formales al final de ISW II.

10. Software Management: un poco al principio de ISW II, el resto se deja para la asignatura optativa.


Por tanto, nos quedaría por ver:
- Gestión de Versiones: este tema lo podría tratar tangencialmente aprovechando las prácticas que tienen que realizar.
- Calidad de Software: estándares ISO-9000, CMM, ...
UN COMPAÑERO SE NOS UNE

AUDIO E IMAGEN DIGITAL

Juan Franco abre un nuevo blog que versará sobre temas de Audio e Imagen Digital. Por de pronto, acabo de aprender que MP3 NO ES MPEG-3!!!