Mostrando entradas con la etiqueta Software Architecture. Mostrar todas las entradas
Mostrando entradas con la etiqueta Software Architecture. Mostrar todas las entradas

lunes, enero 02, 2012

Algunos libros para comenzar el año

Unos cuantos libros para comenzar el año de la mejor manera posible: aprendiendo cosas nuevas.

The Garbage Collection Handbook. Este libro ofrece una visión actualizada del estado del arte de los sistemas de recolección de basura y la gestión automática de memoria. He leido varias críticas de Gil Tene (CTO de Azul Systems) y en todas ellas pone al libro por las nubes.

No he tenido ocasión de leerlo, todavía, pero está en las primeras posiciones de la lista de libros que me gustaría leer este comienzo de año.




Para aquellos que estéis interesados en los sistemas distribuidos y/o trabajeis con ellos aquí podréis encontrar una magnífica y extensa referencia sobre este tipo de sistemas: fundamentos, algoritmos , etc.

No estoy seguro si ya he hablado de este libro con anterioridad pero la verdad es que se trata de una magnífica y reconfortante lectura en la que se pueden aprender infinidad de cosas.



Excelente lectura si os gusta conocer los "internals" del sistema operativo Linux y cómo funcionan la mayoría de sus principales subsistemas: gestión de procesos, gestión de memoria, etc. Posiblemente nunca escribamos ni una línea de código relacionada con el núcleo de este sistema operativo pero estoy convencido de que esta lectura puede ayudarnos como desarrolladores a escribir mejores programas.









Hasta pronto!

jueves, octubre 06, 2011

Escalabilidad, disponibilidad y estabilidad

En algunas ocasiones hemos hablado de temas de escalabilidad y disponibilidad de sistemas aunque siempre desde un punto de vista muy práctico, haciendo referencia a los problemas que ocupan nuestro día a día. Me gustaría recopilar, a lo largo de una serie de posts, algunos de los patrones y/o tecnologías más populares relacionados con la escalabilidad, la concurrencia o la alta disponibilidad.

Me gustaría dejar claro desde un principio que lo aquí expuesto son simplemente mis ideas, adquiridas a lo largo del tiempo gracias a la experiencia acumulada en la construcción de diversos sistemas software, mis estudios de doctorado, leer y practicar mucho, aprender de los maestros y pasarme muchas, pero muchas muchas,  horas aporreando el teclado. Por tanto, las cosas que aquí aparecen podrían ser erróneas y/o incompletas.

Me gustaría comenzar con una tecnología relacionada con la concurrencia: la memoria transaccional (STM en adelante).

Escribir programas concurrentes es una tarea sumamente complicada y, habitualmente, no determinista; ¿cuantas veces habremos probado un programa multihilo en nuestros sistemas de integración continua y , tras poner el sistema en producción, nos hemos encontrado con nuevos errores? Tan real como la vida misma.

Habitualmente las inmutabilidad (hablaremos de ella en el futuro) es un gran aliado a la hora de escribir programas concurrentes dado que resulta mucho más sencillo razonar sobre información cuyo estado permanece estable. Sin embargo, como en la mayoría de las situaciones, la inmutabilidad no es una bala de plata que soluciona todos los problemas por lo que tendremos que lidiar con información cuyo estado puede variar y con toda la problemática asociada a la misma. Llegados a esta situación, y siguiendo con el enfoque con el que estamos más familiarizados, estaríamos peleándonos con bloqueos, granularidad de los mismos, etc.

Un vistazo a la STM

La STM puede ayudarnos a resolver el problema anterior de manera mucho más sencilla visualizando la memoria (heap + pila) como si de un dataset transaccional se tratara. Algunas de las características más relevantes:

  • Concepto muy similar al de una base de datos tradicional. Se llevan a cabo operaciones como begin, commit o abort/rollback
  • En caso de que se produzca una colisión la transacción será relanzada de manera automática
  • Se realiza un proceso de rollback sobre la memoria cuando se produce una operación de abort.
  • Las transacciones se pueden componer y anidar

Un aspecto sumamente importante que debemos tener en cuenta a la hora de utilizar la memoria transaccional es que todas las operaciones englobadas en el ámbito de una transacción deberán ser idempotentes (anteriormente hablábamos del relanzamiento automático en caso de que se produjera una colisión).

Existen numerosas implementaciones disponibles para la máquina virtual de Java (JVM) entre las que destacan:

En la siguiente entrada realizaremos varios ejemplos prácticos de uso de la memoria transaccional y analizaremos cuales son los escenarios más propicios para la utilización de esta solución.

Hasta pronto!

Migue

miércoles, julio 13, 2011

Evento sobre escalabilidad de sistemas

Desde el grupo de escalabilidad en español hacía tiempo que estábamos barajando la posibilidad de organizar un evento relativo a la escalabilidad de sistemas y finalmente hemos dado un paso adelante.

Es una primera aproximación en la que estamos intentando recabar el mayor conjunto de información posible con el objetivo de llegar al mayor número de gente posible.

No voy a repetir todo el rollo que hemos escrito en otros sitios :) así que simplemente os dejo los enlaces donde podréis encontrar toda la información de la que disponemos hasta este momento:

Estaremos encantados de recibir vuestras críticas, sugerencias y/o propuestas.

Hasta pronto!

Migue

viernes, junio 03, 2011

Mecanismo de Load Time Weaving (LTW)

Durante la última entrada analizábamos de manera introductoria los diferentes mecanismos de tejido ofrecidos por AspectJ así como las principales características de los mismos. Durante esta entrada nos acercaremos un poquito más al mecanismo de tejido en tiempo de carga, por normal general más desconocido, desde mi punto de vista, que el mecanismo de tejido en tiempo de construcción (durante todos los ejemplos que hemos visto en anteriores entradas siempre hemos utilizado el tejido en tiempo de construcción).

Los pasos que tenemos que seguir cuando utilizamos el tejido en tiempo de carga son los siguientes:

  • Iniciar nuestra aplicación con el archivo aspectjweaver.jar el actuando como un agente (hablaremos de agentes en otra entrada). Para ello podríamos utilizar una línea como la siguiente
java -javaagent:/aspectjweaver.jar
  • Durante el proceso de inicialización del agente (llevado a cabo por la máquina virtual) el propio agente recupera aquellos archivos existentes en el classpath que coincidan con META-INF/aop.xml (en el caso de encontrar múltiples llevará a cabo la combinación de los mismos).
  • Carga de los aspectos indicados.
  • El agente se registra como un listener del evento de carga de clases de la máquina virtual. Mediante este mecanismo se tiene acceso a la definición de la clase, permitiendo incluso la modificación de la misma.
  • Continua el proceso normal de carga de nuestro aplicación.
  • Cada vez que una nueva clase es cargada la máquina virtual notifica al agente dicha situación. En ese momento es posible examinar la clase en cuestión y determinar si algunos de los aspectos cargados con anterioridad necesita ser tejido. En caso afirmativo, la clase será tejida con el aspecto en cuestión, retornando el bytecode resultante a la máquina virtual.
  • La máquina virtual utiliza el bytecode resultante como elemento de definición de la clase.
Mediante el conjunto de pasos anteriores, aquellas clases que hayan hecho matching con las definiciones de nuestros aspectos tendrán incorporada la funcionalidad definida en éstos últimos.

El agente anterior utiliza un interfaz de la máquina virtual conocido como JVMTI (Java Virtual Machine Tools Interface) que ha sido introducido a partir de Java 5. En el caso de que utilicéis una versión anterior podréis hacer uso de este mecanismo mediante una versión basada en classloaders específicos.

viernes, mayo 27, 2011

Weaving en AspectJ (I)

Hace un tiempo escribí una serie de entradas relacionadas con la orientación a aspectos en general y AspectJ en particular (podéis encontrar dichas entradas aquí) que posteriormente agrupé en un documento.

Hasta este momento nos hemos centrado en la teoría de la orientación a aspectos, cómo escribir los mismos y algunas de sus posibles aplicaciones. Sin embargo, no hemos prestado especial atención al modo en el que los aspectos se combinan con las clases para componer nuestro sistema final. Durante esta entrada y las siguientes profundizaremos en diferentes aspectos del proceso de tejido (weaving).

El mecanismo de tejido es aquel que nos permite combinar la definición de nuestras clases y de nuestros aspectos en un ente ejecutable que conforma nuestro sistema final.

Podemos clasificar los diferentes modelos en base al momento en el que llevan a cabo el tejido. En este caso tendríamos:

  • Build time. Las clases y los aspectos son combinados durante el proceso de construcción de nuestra aplicación.
  • Load time (LTW). En este caso el tejido se realiza en el momento en el que una clase se carga en la máquina virtual, por lo que en este caso no será necesario llevar a cabo ningún proceso adicional en nuestro proceso de construcción. 
Otra posible clasificación podría establecerse en función del los tipos de entrada del proceso de weaving
  • Source code weaving. La entrada al proceso son archivos de código fuente (clases y aspectos)
  • Weaving binario (bytecode). La entrada al proceso es el bytecode obtenido como resultado del proceso de compilación de nuestras clases
De manera esquemática, a continuación se reflejan las diferente combinaciones ofrecidas por el weaver de AspectJ:

  • Tiempo de construcción: las entradas admitidas son tanto código fuente como clases compiladas (bytecode)
  • Tiempo de carga: las entradas pueden ser bytecode o un archivo xml (lo veremos más adelante)

Con esta pequeña entrada nos hemos aproximado de manera sencilla a los procesos de tejido presentes en AspectJ de una manera teórica. En futuras entradas analizaremos con un poco más de detalle los contenidos aquí presentados, haciendo especial hincapié en los mecanismos de tejido en tiempo de carga.

Hasta pronto!

lunes, febrero 14, 2011

Grupo sobre escalabilidad en español

El otro día, mientras revisaba alguno de los artículos y libros que tengo a medio leer, me "di cuenta" de que muchas de las cosas que me gustan están relacionadas con temas de programación distribuida, escalabilidad de sistemas y temáticas similares.

Pues bien, me he movido un poquito por la red y he intercambiado  unos cuantos correos electrónicos con dos auténticos cracks: Martín Pérez y Marc de Palol en los que hemos estado hablando,un poco, sobre la posibilidad de crear un grupo relacionado con temáticas de escalabilidad.

¿Qué cosas tendrían cabida en el grupo os estaréis preguntando? Pues me imagino que las inquietudes y conocimientos de todos los participantes irán marcando un poco el devenir del mismo. 

Nosotros, en un principio (Marc, plagio y añado alguna pincelada a tu correo inicial :) ) habíamos pensado en temas relacionados con la computación distribuida y escalabilidad en general: problemática, soluciones, frameworks, arquitecturas, alternativas, etc utilizados (o que podrían ser utilizados) en el desarrollo software de aquellas aplicaciones en las que  el soporte a millones de usuarios concurrentes, el manejo de cantidades ingentes de datos o los tiempos de respuesta son requisitos altamente importantes.

La idea del grupo, al menos inicialmente, ya veremos si la cosa evoluciona y cómo evoluciona, no es ceñirse a ninguna tecnología en particular sino tratar los temas anteriores desde una perspectiva un poco más abierta.

Las tecnologías que podrían aparecer en el grupo, tal y como decía antes, vendrán marcadas por el interés que demuestre la gente por el mismo así como la orientación que se le quiera dar. A modo de "brainstorming" dejo algunas de los temas/tecnologías que, desde mi punto de vista, podrían aparecer:
  • Hadoop y todo su ecosistema: HBase, Hive, Zookeeper, Hive, . . . (aquí iría un largo ecétera : )
  • Modelos de actores: una alternativa "diferente" a la computación distribuida. Aquí habría cabida para hablar largo y tendido: Erlang y OTP, Scala, Akka, . . .
  • Temáticas relacionadas con el cloud (desde un punto de vista de sistemas escalables, no de usuario): ¿cómo se lleva a cabo la elasticidad de recursos en las plataformas PaaS como GAE, Amazon Beanstalk o Heroku? ¿Cuáles son las arquitecturas que utilizan este tipo de sistemas? ¿Qué técnicas utilizan para dar soporte a tantos usuarios y aplicaciones? . . .
  • Movimiento NoSQL: CouchDB, Cassandra, Riak, etc y otras alternativas diferentes como pueden ser las aportadas por plataformas como Greenplum o Vertica.
  • Seguro que muchísimas cosas más . . . .

¿Os animáis?

Martín ha comentado algo en su blog


martes, junio 22, 2010

Aspect Oriented Programming Intro Guide

Hace tiempo que habíamos comenzado una serie de post relativos a la programación orientada a aspectos y los tenemos dispersos a lo largo de diferentes entradas. He decido recolectar todos los post publicados junto a los que estaban por venir y hacer una sola entrega.

Espero que os guste:


Está escrito en docbook por lo que si alguien está interesado en los fuentes no tiene más que pedírmelos.

Hasta pronto!

domingo, mayo 30, 2010

AOP: crosscutting (I)

A lo largo de las entradas anteriores hemos analizado el modelo de joint point de AspectJ y la manera de definir las reglas que permitan seleccionar aquellos joint points de nuestro interés. 
Durante esta entrada analizaremos el modo en el que se puede alterar el comportamiento de un sistema en los joint points seleccionados mediante la definición de los pointcuts.

Descripción general


Las reglas de tejido están compuestas de dos partes:

  • advice: qué deseamos hacer.
  • pointcuts: dónde aplicamos el advice anterior.

AspectJ soporta el crosscutting dinámico mediante el concepto de advices, construcciones similares a los métodos gracias a los cuales se permiten definir las acciones a ejecutar en los joint points seleccionados por un pointcut.

Categorías de advices


Dependiendo de las funcionalidades que se estén implementando será necesario llevar a cabo la lógica en un determinado lugar del flujo de ejecución original; así por ejemplo, si se está construyendo la seguridad de un sistema, el código tendrá que verificar dicha seguridad antes de la ejecución del joint point. En un sistema de cachés, la nueva funcionalidad tendría que ejecutarse alrededor del joint point original, intentando recuperar el valor de la caché, y en caso de que no exista, ejecutar el código real y añadirlo a la misma para futuras invocaciones. AspectJ ofrece tres categorías de advices que satisfacen los escenarios anteriores (y alguno más):

  • Before Advice: se ejecutan anteriormente a la ejecución del joint point
  • After Advice: se ejecutan posteriormente a la ejecución del joint point. Existen tres variantes diferentes
    • After finally: se ejecuta tras la ejecución del join point independientemente del resultado de la misma.
    • After returning: se ejecuta tras la ejecución del joint point siempre y cuando ésta última haya finalizado correctamente, es decir, sin lanzar ninguna excepción.
    • After throwing: se ejecuta tras la ejecución fallida de un joint point, es decir, después de que dicho joint point dispare una excepción.
  • Around Advice: rodean la ejecución del joint point.


Sintaxis de los advices


Aunque la sintaxis varía ligeramente dependiendo del tipo de advice que se esté escribiendo, se podría dividir su estructura general en tres partes claramente diferenciadas:

  • Declaración del advice. En esta parte de la declaración se especifica el momento de ejecución del advice, es decir, si se ejecutará antes, después o alrededor de los joint points.
  • Definición de los pointcuts. Se especifican los pointcuts sobre los que se desea actuar.
  • Cuerpo del advice. Definición del código a ejecutar una vez se haya alcanzado el joint point indicado.

Veamos, por partes, un ejemplo sencillo de definición de un advice:


  •  En primer lugar se define un sencillo pointcut :

pointcut secureOperation(User user): call( * User.*(..)) && target(user)


  • En el pointcut anterior estamos capturando todas las llamadas a cualquier método de la clase User, y, adicionalmente estamos recogiendo el objeto que actúa como target de la llamada. A continuación veremos un around advice para ilustrar la sintaxis:

            Object around(User user):secureOperation(user){
System.out.println("Securing operation on user " 
+ user.toString());
                Object retValue = proceed(user);
System.out.println("Finished secured operation on user " 
+ user.toString());
return retValue;
           }

  • En la definición anterior se puede ver la estructura de la declaración de un advice descrita anteriormente:
    • La parte que precede a los dos puntos indica el momento de ejecución del advice (after,before,around). En este caso, se ejecutará alrededor del joint point seleccionado.
    • La parte que sigue a los dos puntos representa el pointcut, es decir, la definición de los criterios que determinan cuándo se ejecutará el advice.
    • La última parte representa el cuerpo del advice, es decir, el código que se ejecutará cuando alguno de los joint point definidos por el pointcut sea alcanzado.

Advices y métodos

Al igual que los métodos de una clase, los advices se utilizan para definir comportamiento. La sintaxis de éstos últimos es similar a la de los métodos aunque existen algunas diferencias dado que los advices son aplicados de manera automática, sin la necesidad de realizar explícitamente la invocación del mismo.

A continuación se analizan las similitudes entre ambos en tres categorías diferentes: declaración, cuerpo y comportamiento. La declaración de un advice es similar a la signatura de un método tradicional en que:
  • Opcionalmente puede asignarse un nombre al advice mediante el uso de la anotación @AdviceName.
  • Recibe argumentos a través del contexto del joint point, que posteriormente podrán ser utilizados en el cuerpo para implementar la lógica necesaria.
  • Puede declarar el lanzamiento de una excepción.
  • El cuerpo de los advices también es muy parecido al de los métodos puesto que:
  • El código del cuerpo del advice sigue las mismas reglas de acceso a miembros de otros tipos y/o aspectos.
  • Se puede referenciar a la propia instancia del aspecto mediante el uso de this.
  • Los advices de tipo around pueden retornar un valor.
  • Los advices deben declarar las excepciones que sean checked que la implementación podría disparar.
  • En la categoría relativa al comportamiento, los advices :
  • No pueden declarar el disparo de una excepción que no está declarada en TODOS los joint points sobre los que actúa.
  • Pueden omitir algunas de las excepciones de tipo checked que han sido declaradas por alguno de los joint point sobre los que actúa.
  • Pueden declarar el disparo de excepciones más específicas (de tipo checked) que las definidas por los joint point sobre los que está actuando.
  • Pueden lanzar cualquier tipo de excepción de tipo runtime. 

En comparación con los métodos, los advices presentan las siguientes diferencias:

  • La declaración de un nombre es opcional.
  • No pueden ser invocados directamente.
  • No presentan especificadores de acceso (relacionado con la característica de que no pueden ser invocados directamente).
  • No presentan un tipo de retorno en los advices de tipo before y after.
  • Tienen acceso a unas cuantas variables dentro del propio aspecto: thisJointPoint, thisJointPointStaticPart, thisEnclosingJointPointStaticPart.
  • Se puede utilizar la palabra reservada proceed en los advices de tipo around para ejecutar el joint point sobre el cual se está realizando el advice.

La siguiente entrada realizará un análisis más detallado de los advices y cómo se puede acceder a los contextos del joint point.


Hasta pronto!!

viernes, mayo 21, 2010

MMOG Architectures

El poco tiempo libre que tengo no me permite realizar una actualización mínimamente interesante; así que os vais a tener que conformar con ésto; lo siento!

Es una pequeña presentación que sirve como introducción a las principales arquitecturas software subyacentes en los populares MMOG.
Hasta pronto!

PD: por fin esta semana ha llegado la hora; nos toca comer en el Diverxo!! bien !!!!! Prometo un post con la crítica!

lunes, mayo 03, 2010

AOP: non kinded pointcuts

En la entrada anterior analizábamos aquellos tipos de pointcuts en los que los joint point seleccionados encajaban en una determinada categoría (de ahí su nombre).

El mecanismo implementado mediante non-kinded pointcuts permite la selección de joint points basados en criterios adicionales a las signaturas vistas anteriormente. Por ejemplo, podremos seleccionar todos los joint point donde el objeto this es de un determinado tipo. Dicho joint point incluiría las llamadas a métodos, ejecuciones, manejadores de excepciones, etc.

A continuación, a través de ejemplos, veremos los diferentes tipos de non-kinded pointcuts ofrecidos por AspectJ.

Non-kinded pointcuts basados en control de flujo

PointcutDescripción
cflow( execution(* TransactionManager. commit() ))Selecciona todos los joint points en el flujo de la ejecución de cualquier operación commit de la clase TransactionManager, incluyendo la ejecución del propio método.
cflowbellow( execution(* TransactionManager. commit() ))Selecciona todos los joint points en el flujo de la ejecución de cualquier operación commit de la clase TransactionManager, excluyendo la ejecución del método.
cflow(execution(@Secured * * (..)))Todos los joint points en el flujo de la ejecución de cualquier método anotado con la anotación Secured
cflow(transacted())Cualquier joint point en el flujo de ejecución de los joint points seleccionados por el pointcut transacted()
Non-kinded pointcuts basados en la estructura léxica
Dentro de este tipo de pointcuts tenemos dos categorías:
  • within(TypeSingnature): selecciona cualquier joint point que aparece en el cuerpo de las clases y aspectos que concuerden con el tipo especificado.
  • withincode(ConstructorSignature),withincode(MethodSignature): selecciona cualquier joint point que aparezca dentro de un método o un constructor, incluyendo la definición de cualquier clase local que pudiera aparecer en los mismos.

PointcutDescripción
within(User)Selecciona todos los joint points que aparecen dentro de la clase User
within(User+)Selecciona todos los joint points que aparecen dentro de la clase user y cualquiera de sus clases derivadas
within(@Transactional *)Selecciona todos los joint points que aparecen dentro de cualquier clase que se encuentre marcada con la notación Transactional
withincode(* TransactionManager. retrieve*(..))Selecciona todos los joint points que parecen dentro de cualquier método de la clase TransactionManager cuyo nombre comience por retrieve
Non-kinded pointcuts de ejecución
Este tipo de pointcuts permite seleccionar joint points en base al tipo de los objetos en tiempo de ejecución. De este modo se dispone de:
  • this(). Acepta dos formas diferentes: this(ObjectIdentifier) o this(Type). Seleccionará aquellos joint points cuyo objeto this sea del tipo (o el objeto) indicado.
  • target(). Similar al concepto anterior, aunque en este caso, se utilizar el target del joint point en lugar del this.

PointcutDescripción
this(User)Selecciona cualquier joint point en que la expresión this instanceof User sea cierta. Así por ejemplo, seleccionará las llamadas a métodos o accesos a campos donde el objeto actual sea de tipo User o cualquier de sus subclases.
target(User)Selecciona cualquier joint point en el que el objeto sobre el que se realiza la llamada al método es instanceof User
Non-kinded pointcuts sobre argumentos
Este tipo de pointcuts permite seleccionar joint points en base al tipo de los argumentos en tiempo de ejecución. Veamos los distintos tipos de argumentos, en función del tipo del joint point :
  • En el caso de los joint points manejadores de excepciones el argumento será la excepción manejada.
  • En los métodos y constructores, los argumentos serán los argumentos del método y constructor.
  • En los accesos de modificación de un campo, el argumento será el nuevo valor que va a tomar dicho campo.

PointcutDescripción
args(User, . . , String)Selecciona cualquier joint point de tipo método o constructor en el que el primer argumento es de tipo User (o cualquiera de sus subclases), y el último argumento es de tipo String.
args (SqlException)Selecciona cualquier joint point con un único argumento de tipo SqlException. Seleccionaría cualquier método o constructor que esperase un único argumento de tipo SqlException, un acceso de escritura a un campo estableciendo un nuevo valor de tipo SqlException, y también seleccionaría un manejador de excepciones de tipo SqlException
Non-kinded pointcuts condicionales
Este tipo de pointcuts permiten seleccionar joint points basados en una expresión condicional.

PointcutDescripción
if(debug)Selecciona cualquier joint point donde el campo estático debug (en la definición del aspecto) toma el valor cierto

Poco a poco vamos completando, de manera sencilla, una idea general de los mecanismos que nos ofrece la orientación a aspectos en general, y AspectJ en particular. En la siguiente entrada analizaremos los conceptos de crosscutting dinámico y los mecanismos disponibles para la modificación del comportamiento de un programa en un determinado joint point.

domingo, mayo 02, 2010

AOP: kinded pointcuts

Continuando la serie de posts relativos a la programación orientada a aspectos y, concretamente, el lenguaje AspectJ, durante esta entrada analizaremos la implementación que este último hace de los pointcuts.

AspectJ ofrece dos mecanismos diferentes que permiten a los pointcuts realizar la selección de los joint points:
  • Kinded pointcuts. En este caso, los pointcuts seleccionan categorías de joint points (de ahí su nombre). Así, por ejemplo, se ofrece la posibilidad de realizar matching sobre la ejecución de un método.
  • Non-kinded pointcuts. Se seleccionan los joint point en base a la información de la que disponen, como los tipos en tiempo de ejecución o su contexto. En esta situación se seleccionan joint points de cualquier clase, siempre y cuando satisfagan la condición descrita.
A continuación analizaremos los kinded pointcuts y dejaremos para la siguiente entrada la segunda categoría.
  • Kinded Pointcuts
Joint Points expuestos y tipos de pointcuts
Categoría de Joint Point Sintaxis del pointcut
Ejecución de un método execution(MethodSignature)
Llamada a un método call(MethodSignature)
Ejecución de un constructor execution(ConstructorSignature)
Llamada a un constructor call(ConstructorSignature)
Inicialización de una clase staticinitializaction(TypeSignature)
Acceso de lectura a un campo get(FieldSignature)
Acceso de escritura a un campo set(FieldSignature)
Ejecución de un manejador de excepciones handler(TypeSignature)
Inicialización de un objeto initialization(ConstructorSignature)
Pre-inicialización de un objeto preinitialization(ConstructorSignature)
Ejecución de un advice adviceexecution()


Por ejemplo, si deseamos seleccionar todas las llamadas a los métodos públicos commit() de la clase TransactionManager, escribiríamos un pointcut similar al siguiente:
call(public void TransactionManager.commit(..))

En la siguiente entrada analizaremos en detalle la segunda categoría de pointcuts ofrecida por AspectJ

lunes, marzo 15, 2010

R-Eclipse 1.0

Hace un tiempo comencé a construir un entorno de desarrollo integrado (IDE) para el lenguaje de programación R, y finalmente he decidido liberar una primera versión. El componente dista mucho de ser perfecto (y completo) pero sinceramente me siento muy orgulloso del trabajo realizado.

La herramienta está basada en la arquitectura de plugins de Eclipse, constando de cinco módulos (plugins/bundles) que a continuación describo de manera muy resumida:
  • Plugin r.core: núcleo de la aplicación. Incluye el analizador léxico y sintáctico del lenguaje, infraestructura básica para la construcción y recorrido del AST, indexado, mixin parsers, etc.
  • Plugin r.completion: añade a la herramienta la capacidad de realizar la compleción de código.
  • Plugin r.formatter: añade a la herramienta la capacidad de ordenación e indentación del código fuente.
  • Plugin r.launching: añade a la herramienta la capacidad de ejecución integrada de los programas R.
  • Plugin r.ui: contiene la mayor parte de componentes gráficos de la herramienta. Gestión de preferencias de formateo/indexación, editor R, preferencias de compleción de código, resaltado de palabras reservadas, templates, etc
  • Adicionalmente existe un módulo de documentación que contiene información de diversa índole
He utilizado maven como herramienta de gestión de dependencias y control del proyecto aunque en este mismo instante está un poco "manga por hombro" puesto que he estado haciendo varias pruebas para la generación de la feature final mediante  Buckminster.

Soy consciente de la existencia de varios bugs (y todos los que yo no habré detectado :) ) y de muchas características que podrían añadirse para mejorar la herramienta. A continuación resumo una pequeña lista de defectos/mejoras:
  •  Tal y como indicaba anteriormente, intentaré migrar por completo a Buckminster.
  • Añadir más pruebas (tanto unitarias como de integración)
  • Mejorar la compleción de código: ampliar los lugares donde se habilita la compleción del mismo y mejorar algunas de las características ya existentes.
  • Inclusión de un motor de ejecución remoto, de modo que se permita configurar un intérprete en una máquina diferente que sea capaz de ejecutar nuestros scripts R.
  • Inclusión de una consola interactiva. En la actualidad la consola simplemente integra los resultados de las ejecuciones de nuestros scripts, pero no permite la interactividad.
  • Incluir un depurador de código. Puede que sea la más complicada, pero, personalmente, creo que es la características más interesante junto con la ejecución remota descrita en el punto anterior.
  • Programación visual: diagrama R integrado. Creación de un diagrama que nos permita construir nuestros programas de manera gráfica mediante una paleta de funcionalidades. Estaría basado en Eclipse GMF y puede que entonces también se distribuyera la herramienta como cliente rico (Eclipse RCP)
  • . . . . 
Se puede obtener acceso al código fuente en modo lectura desde la siguiente URL: http://reclipse.googlecode.com/svn/trunk/. Si alguien quiere participar le puedo dar acceso al repositorio en modo escritura.

Hasta pronto!

PD: en la siguiente entrada añadiré unas capturas de pantalla para que se pueda tener una perspectiva general de la herramienta

lunes, marzo 08, 2010

AOP Pointcuts theory

Hace tiempo habíamos hablado acerca del modelo de joint point ofrecido por AspectJ, concretamente en estas dos entradas: Joint Point I y Joint Point II.

En los dos posts anteriores indicabamos que un join point no es más que un punto de ejecución en un sistema. Así por ejemplo, el acceso al campo de una clase, la ejecución de una función o una sentencia for son ejemplos de join points. AspectJ solamente expone un subconjunto de todos los posibles joint points, limitando de este modo, el acceso a las construcciones más estables.

Los pointcuts son construcciones que nos permite seleccionar joint points y recuperar su contexto. Veamos algunas de las características principales:
  • Los pointcuts especifican un criterio de selección. Utilizaremos tipos, campos, métodos, anotaciones, etc para generar dichas definiciones. También podremos establecer condiciones en tiempo de ejecución que tendrán que cumplirse en el joint point seleccionado.
  • Los joint point disponen de información en tiempo de ejecución. Determinados pointcuts pueden recolectar dicha información y pasársela al advice. Por ejemplo, la llamada a un método de un objeto tendrá disponible el propio objeto que realiza la llamada y los argumentos que se están pasando.
  • En el caso del lenguaje Java, todos los elementos que componen un programa tienen una signatura. La utilización de patrones para dichas signaturas permiten a los pointcuts especificar las reglas de selección de los joint point que se desean capturar.
Los párrafos anteriores resumen de manera breve, y teórica, las características principales de los pointcuts. En la siguiente tabla se resumen las categorías principales de joint points expuestos por AspectJ.

Categorías de joint points expuestas por AspectJ (resumen)
Categoría Joint Point Expuesto Código que representa
Método Execution Cuerpo del método
Método Call Invocación del método
Constructor Execution Ejecución de la lógica de creación de un objeto
Constructor Call Invocación de la lógica de creación de un objeto
Acceso a un campo Read Lectura de un objeto o el campo de una clase
Acceso a un campo Write Escritura de un objeto o el campo de una clase
Proceso de excepciones Handler Bloque catch para manejar una
excepción
Inicialización Class init Proceso de carga de una clase (class
loading
)
Inicialización Object init Inicialización de un objeto en un constructor
Inicialización Object pre-init Pre-inicialización de un objeto en un constructor
Advice Execution Ejecución de un advice

En la siguiente entrada (espero que sea lo más pronto posible :) ) analizaremos en detalle la estructura sintáctica de los pointcuts, haciendo especial hincapié en las signaturas.

Hasta pronto!

PD: Últimamente mi tiempo escasea (por llamarlo de alguna manera) pero eso dará para una nueva entrada.

viernes, noviembre 13, 2009

Definición de DSL

Los DSL's son lenguajes de programación específicos desarrollados para resolver problemas en un dominio especializado.

El dominio anterior podría ser multitud de cosas diferentes, por ejemplo, podría ser relativo a la industria: inteligencia analítica, banca, seguros, marketing, . . . o relativo a la tecnología: JEE,.Net, servicios de mensajes, arquitectura o bases de datos.

Existe tres tipos diferentes de DSL: externos, internos, y workbench languages
donde cada uno de los anteriores tiene una audiencia definida, y, por normal general, no suelen solaparse:
  • Los DSL externos utilizan un lenguaje diferente al de la aplicación que los está utilizando. Generalmente tienen un lenguaje específico, aunque en otras ocasiones, utilizan otra sintáxis diferente (XML es el ejemplo más claro). Algunos ejemplos de DSL externos que seguramente os puedan sonar son: SQL,awk o los ficheros xml de configuración de herramientas como Hibernate o Spring.
  • Los DSL's internos utilizan el mismo lenguaje de propósito general más utilizado en el sistema, aunque haciendo un uso limitado del mismo. Se utiliza un subconjunto de las construcciones del lenguaje, enfocadas a un aspecto determinado de la aplicación. Tanto Groovy como Ruby han generado una gran cultura en la construcción de DSL's. Mucha gente ve los frameworks más populares asociados a los dos lenguajes anteriores (Grails y Rails) como una colección de DSL's.
  • Language Workbenches (este término ha sido acuñado por Martin Fowler) son IDE's diseñados para la construcción de DSL's. Estas herramientas permitirán definir la sintaxis del lenguaje, junto a editores y generadores. Los primeros nos permitirán disponer de sofisticados entornos de programación para los DSL's, de manera idéntica a los actuales IDE's. Ejemplos de este tipo pueden ser los proyectos de eclipse de GMF o las herramientas de ANTLR para Eclipse.
En próximos post intentaremos profundizar en el tema.

Hasta pronto!

jueves, noviembre 05, 2009

New Languages. Building IDE's

En los últimos años han surgido muchos lenguajes similares a Java que se ejecutan sobre la propia máquina virtual de este último (JVM) lo cual es un indicador bastante fiable de cual será el futuro del desarrollo de aplicaciones sobre esta plataforma.

Sin embargo, Eclipse y su solución JDT, no ofrecen soporte para la integración de estos nuevos lenguajes en su modelo subyacente. Por ejemplo, no existe un modo de incluir jerarquías de tipos,jerarquías de llamadas, etc de manera directa.

Una aproximación utilizada por muchos entornos de desarrollo de lenguajes actuales, como por ejemplo el caso de Scala, es la utilización de servicio de tejido de JDT. Las características principales son:

  • Utiliza AspectJ añadiendo puntos de unión al modelo JDT
  • Se encapsula en puntos de extensión de Eclipse, haciéndolo extensible a terceras partes.
  • Utiliza un proyecto de Eclipse conocido como Equinox Aspects que soporta el proceso de tejido en tiempo de carga en un entorno OSGI.
La construcción de entornos de desarrollo para otro tipo de lenguajes, que podríamos denominar de scripting, como puede ser JavaScript,Python,Tcl o Ruby se puede basar en un enfoque diferente al anterior, mediante el uso del proyecto DLTK de Eclipse (www.eclipse.org/dltk).

En próximas entradas analizaremos las claves de la construcción de un IDE para el lenguaje de programación R (www.r-project.org).

Hasta pronto!

viernes, octubre 16, 2009

Modelo de Joint Point (y II)

El modelo de "joint point" que introducíamos en el post anterior está compuesto de dos partes claramente diferenciadas: los "join point", que no son más que puntos en la ejecución de un programa, y los "pointcuts", un mecanismo de selección de los puntos anteriores.

Imaginemos por un momento que nos encontramos desarrollando un sistema que necesita gestión de la seguridad, algo muy común en el mundo en el que nos movemos, y, que, debido a la naturaleza transversal del mismo, elegimos AOP como enfoque principal nuestra solución. ¿Cuáles son los pasos que deberíamos seguir?

A continuación esbozamos, de manera esquemática, los pasos que se deberían seguir:
  • Identificar los puntos del sistema que necesitan ser protegidos, comprobando, antes de realizar el acceso, que el usuario que está realizando el acceso está autenticado y tiene los privilegios necesarios para hacerlo. En resumen, estamos identificando los "joint point" que requieren ser securizados.
  • Construiremos un pointcut (o varios, todos los que sean necesarios), que permitan la selección de los "joint point" descritos en el punto anterior.
  • Construiremos un aspecto que encapsule toda la lógica de seguridad requerida.
Esto es un mera introducción a los conceptos que componen un sistema orientado a aspectos, concretamente AspectJ. En el siguiente post analizaremos las categorías de joint points expuestas por AspectJ y el modo en el que podemos realizar la definición de los pointcuts que las capturen.