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!

miércoles, mayo 12, 2010

Luces y sombras

Hace medio año que decidí a Madrid y me parece un buen momento para hacer un pequeño balance de como han trasncurrido las cosas hasta este momento.

En el terreno personal las cosas marchan genial; sobre todo con la gordita, mucho más ahora que nos estamos comprando un piso (eso dará lugar para otra serie de entradas :) ). Intentamos aprovechar el poco tiempo que tenemos libre para divertirnos, viajar, conocer nuevos restaurantes :), y retomar el contacto con gente a lo que no veíamos con demasiada frecuencia.

Otra de las cosas buenas que me ha pasado tras mi regreso a Madrid ha sido mi admisión en los estudios de doctorado de la politécnica de Madrid. Me está suponiendo un gran esfuerzo (pocas horas de sueño y mucho trabajo, quizás demasiado) pero la verdad que, al menos hasta este momento, la experiencia está siendo gratificante; las clases son interesantes además de que estoy conociendo a gente que presenta mis mismos intereses. Puede que dentro de poco tiempo tenga alguna novedad respecto a este tema pero tampoco quiero adelantarme a los acontecimientos.

Sin embargo estar en Madrid también tiene sus cosas "malas", principalmente porque estás mucho más lejos de la gente con la que has vivido muchos años de tu vida y a la que quieres: tu familia  y  amigos. Esta entrada quedaría imcompleta si no me acordase de mis padres y mi hermana o de Fer,Rube, Andre,Vicio,Yudi,Miguel, el Mono, Héctor, Marta,. . . (lo sé, lo sé, me estoy dejando a gente en la lista ).

Visto así, podría parecer que todo está genial, pero la otra pieza del puzzle, que, por desgracia, también es una parte importante de nuestras vidas, no termina de encajar. Si, es lo que todos estamos pensando, el maldito trabajo.

Siempre he dicho que me gusta a lo que me dedico, pero la verdad que cada día que pasa me voy desilusionando (o quizás siendo realista) un poquito más. Regresé a Madrid con la idea de intentar seguir creciendo profesionalmente pero, hasta el momento, lo único que estoy haciendo es ir hacia atrás. Falsas promesas, mentiras, . . . se están convirtiendo en tónica habitual. Prefiero no seguir porque me enciendo y me tengo que ir a la cama :)

¿Y entonces? Pues lo único que tengo claro es que estoy firmemente convencido de darle un giro de 180º a mi carrera y dedicarme a algo completamente diferente. Os mantendré informados :).

Estoy un poco espeso así que voy a dejarlo aquí.

Keep walking :)

PD: A partir de ahora comenzaré a escribir el inglés porque necesito practicar. Os agradecería, a los pocos que frecuentais este blog, todo tipo de correcciones

viernes, mayo 07, 2010

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