Java Server Faces vs Struts
Octubre 31st, 2004 - [Enlace local]
Supongo que esta es una de las preguntas del millón que se estarán haciendo actualmente todos los desarrolladores J2EE y que parece que tienen dificil respuesta. Por una parte esta nuestro viejo amigo Struts, con un valor ya demostrado en el campo de batalla y al que parece que se quiere mandar para casa (no sin antes agracederle los servicios prestados) en favor de un nuevo combatiente, JSF, mas joven y mejor formado.
Buscando información sobre esta disyuntiva me he encontrado con el interesantísimo (y sin embargo breve) artículo Java Server Faces (JSF) vs Struts de Roland Barcia. En dicho artículo, el autor hace una comparación entre ambos frameworks de distintas características. Así, Struts sale vencedor en madurez … y en nada mas !!. El resto de características comparadas en el artículo, Flexibilidad del Controlador y manejo de eventos , navegacion , desarrollo de paginas , integración y extensibilidad se las lleva JSF.
Personalmente estoy de acuerdo con estas conclusiones, aunque me gustaría que algún defensor de Struts diera su opinión. Después de probar ambos frameworks encuentro mas sencillo e intuitivo JSF. Sin embargo es inquietante tanto la postura de Sun como la del proyecto Struts, hablando no de competencia sino de cooperación entre ambos frameworks (aunque reconocen algún solapamiento). Así, JSF se define como mas centrado en ofrecer un modelo de componentes para el interfaz de usuario. En mi humilde opinión esto resulta confuso, ya que como dice Adam Winer (representante de Oracle en el Grupo de Expertos de JSF) en esta entrevista cuando se le pregunta por su posición en el debate JSF vs Struts: “JSF ofrece todo lo que necesitas tanto en la capa de la Vista como en la del Controlador - y puedes seguir una ruta JSF desde el principio hasta el final”. Supongo que “esta mano tendida” hacia Struts es consecuencia de que Craig McClanahan, lider de la especificación JSF sea el creador de Struts.
Sin embargo, la madurez y estabilidad de Struts son su punto fuerte. Ninguna de las empresas con las que tengo relación han empezado a trabajar con JSF, ni siquiera se ha planteado su utilización en proyectos próximos a iniciarse, parece que Struts es la única opción. Me da la impresión de que al menos en España, JSF todavía no ha despegado (visito a diario los foros de javaHispano y las consultas sobre JSF son muy escasas en comparación a las que se hacen sobre Struts). Supongo que con la llegada de las nuevas versiones de los IDE’s mas utilizados que integrarán JSF esta situación empezará a cambiar (ya están disponibles Sun Java Studio Creator, JBuilder 2005, WebSphere Studio Application Developer y mas)
En fin, que todo el mundo parece estar de acuerdo en que JSF es una decisión estratégica de cara al futuro, pero ¿para cuando? ¿Sería interesante/necesario adoptar JSF para proyectos que van a iniciarse ahora? Me gustaría leer alguna opinión…
» Leer más, comentarios, etc...
Null Pointer Exception
Java Server Faces vs Struts
Octubre 31st, 2004 - [Enlace local]
Supongo que esta es una de las preguntas del millón que se estarán haciendo actualmente todos los desarrolladores J2EE y que parece que tienen dificil respuesta. Por una parte esta nuestro viejo amigo Struts, con un valor ya demostrado en el campo de batalla y al que parece que se quiere mandar para casa (no sin antes agracederle los servicios prestados) en favor de un nuevo combatiente, JSF, mas joven y mejor formado.
Buscando información sobre esta disyuntiva me he encontrado con el interesantísimo (y sin embargo breve) artículo Java Server Faces (JSF) vs Struts de Roland Barcia. En dicho artículo, el autor hace una comparación entre ambos frameworks de distintas características. Así, Struts sale vencedor en madurez ... y en nada mas !!. El resto de características comparadas en el artículo, Flexibilidad del Controlador y manejo de eventos , navegacion , desarrollo de paginas , integración y extensibilidad se las lleva JSF.
Personalmente estoy de acuerdo con estas conclusiones, aunque me gustaría que algún defensor de Struts diera su opinión. Después de probar ambos frameworks encuentro mas sencillo e intuitivo JSF. Sin embargo es inquietante tanto la postura de Sun como la del proyecto Struts, hablando no de competencia sino de cooperación entre ambos frameworks (aunque reconocen algún solapamiento). Así, JSF se define como mas centrado en ofrecer un modelo de componentes para el interfaz de usuario. En mi humilde opinión esto resulta confuso, ya que como dice Adam Winer (representante de Oracle en el Grupo de Expertos de JSF) en esta entrevista cuando se le pregunta por su posición en el debate JSF vs Struts: "JSF ofrece todo lo que necesitas tanto en la capa de la Vista como en la del Controlador - y puedes seguir una ruta JSF desde el principio hasta el final". Supongo que "esta mano tendida" hacia Struts es consecuencia de que Craig McClanahan, lider de la especificación JSF sea el creador de Struts.
Sin embargo, la madurez y estabilidad de Struts son su punto fuerte. Ninguna de las empresas con las que tengo relación han empezado a trabajar con JSF, ni siquiera se ha planteado su utilización en proyectos próximos a iniciarse, parece que Struts es la única opción. Me da la impresión de que al menos en España, JSF todavía no ha despegado (visito a diario los foros de javaHispano y las consultas sobre JSF son muy escasas en comparación a las que se hacen sobre Struts). Supongo que con la llegada de las nuevas versiones de los IDE's mas utilizados que integrarán JSF esta situación empezará a cambiar (ya están disponibles Sun Java Studio Creator, JBuilder 2005, WebSphere Studio Application Developer y mas)
En fin, que todo el mundo parece estar de acuerdo en que JSF es una decisión estratégica de cara al futuro, pero ¿para cuando? ¿Sería interesante/necesario adoptar JSF para proyectos que van a iniciarse ahora? Me gustaría leer alguna opinión...
» Leer más, comentarios, etc...
Pointer to (void)
Acerca de algún Workflow
Octubre 28th, 2004 - [Enlace local]
Básicamente existen 4 problemas que deben ser resueltos desarrollando software (en muy pequeña escala):
- Entregar el software a tiempo. Ni antes ni después. Después no porque puede que el cliente nos pase la factura por retrasar SU planificación. Antes tampoco, porque el hecho de haber tenido suerte esta vez forzará al cliente a pedir un plazo más corto para el siguiente proyecto.
- Entregar el software sin errores. No comments.
- Mantener las previsiones de coste y de coste por errores en el desarrollo. Planifica bien.
- Utilizar lo ya desarrollado, tanto las técnicas como el código que pueda ser aprovechado. Y sobre todo, el knowhow.
3 pequeños (grandes) consejos que te pueden salvar algún día de trabajo:
- Utiliza un sistema de Gestión de la Configuración del Software (SCM), cualquier simple control de versiones puede ser útil como comienzo. Controla quién a hecho qué, en cuanto tiempo y además recupera una versión anterior en cualquier momento. Se disciplinado y reconoce de una vez que el mayor peligro para el código eres tu. Perforce rules again, pero CVS es open source. Tienes demasiado código para seguir numerando los archivos module1.3.45.cs, module1.3.46a.cs...
- Bugtracking, sigue la pista de los errores. Planifica, ordena qué tareas son más necesarias en cada momento del tiempo. BugZilla se usa en medio mundo, y es open source. Añade más y prueba a organizarte con JIRA.
- Los cambios, desde los requisitos, al código. Jamás cambies directamente sobre el código, por mucho que el cliente al otro lado del teléfono este a punto de darle un infarto. Si, ya se que son dos líneas de código, pero, ¿realmente puedes asegurar que no afectarán al resto del código? y si resulta que si, ¿no afectará también al diseño de la aplicación? ¿y ese diseño no está basado en unos requisitos? Ten en cuenta que el equipo de pruebas empieza a diseñar las pruebas desde los requisitos de la aplicación.
¿Sigues cumpliendo que la aplicación hace lo que tiene que hacer?. No te confundas, no es una buena idea hacer un cambio de abajo arriba. Empieza por arriba, mira si el objetivo es correcto, y luego sigue avanzando por el diseño antes de que tres o cuatro cambios de tres líneas de código acaben destrozando tu aplicación.
PD: Implementar estos tres pasos en una pequeña organización no lleva un mes, entre escoger herramientas, formar al personal, instalar todo, y sobre todo, discutir con todos ellos y despojarlos de la verdad absoluta y del cetro sagrado del conocimiento. Hazlo ahora, o por lo menos plantéatelo. No olvides que probablemente cambiarás la forma de trabajo de muchos de ellos. Improve the way you do business.
» Leer más, comentarios, etc...
Pointer to (void)
Acerca de algún Workflow
Octubre 28th, 2004 - [Enlace local]
Últimamente, y con la vorágine de metodologías que se acerca, es difícil establecer un proceso coherente para el desarrollo de aplicaciones en los plazos previstos. Otro día, metodologías, hot es la guerra.
Básicamente existen 4 problemas que deben ser resueltos desarrollando software (en muy pequeña escala):
- Entregar el software a tiempo. Ni antes ni después. Después no porque puede que el cliente nos pase la factura por retrasar SU planificación. Antes tampoco, porque el hecho de haber tenido suerte esta vez forzará al cliente a pedir un plazo más corto para el siguiente proyecto.
- Entregar el software sin errores. No comments.
- Mantener las previsiones de coste y de coste por errores en el desarrollo. Planifica bien.
- Utilizar lo ya desarrollado, tanto las técnicas como el código que pueda ser aprovechado. Y sobre todo, el knowhow.
3 pequeños (grandes) consejos que te pueden salvar algún día de trabajo:
- Utiliza un sistema de Gestión de la Configuración del Software (SCM), cualquier simple control de versiones puede ser útil como comienzo. Controla quién a hecho qué, en cuanto tiempo y además recupera una versión anterior en cualquier momento. Se disciplinado y reconoce de una vez que el mayor peligro para el código eres tu. Perforce rules again, pero CVS es open source. Tienes demasiado código para seguir numerando los archivos module1.3.45.cs, module1.3.46a.cs...
- Bugtracking, sigue la pista de los errores. Planifica, ordena qué tareas son más necesarias en cada momento del tiempo. BugZilla se usa en medio mundo, y es open source. Añade más y prueba a organizarte con JIRA.
- Los cambios, desde los requisitos, al código. Jamás cambies directamente sobre el código, por mucho que el cliente al otro lado del teléfono este a punto de darle un infarto. Si, ya se que son dos líneas de código, pero, ¿realmente puedes asegurar que no afectarán al resto del código? y si resulta que si, ¿no afectará también al diseño de la aplicación? ¿y ese diseño no está basado en unos requisitos? Ten en cuenta que el equipo de pruebas empieza a diseñar las pruebas desde los requisitos de la aplicación.
¿Sigues cumpliendo que la aplicación hace lo que tiene que hacer?. No te confundas, no es una buena idea hacer un cambio de abajo arriba. Empieza por arriba, mira si el objetivo es correcto, y luego sigue avanzando por el diseño antes de que tres o cuatro cambios de tres líneas de código acaben destrozando tu aplicación.
PD: Implementar estos tres pasos en una pequeña organización no lleva un mes, entre escoger herramientas, formar al personal, instalar todo, y sobre todo, discutir con todos ellos y despojarlos de la verdad absoluta y del cetro sagrado del conocimiento. Hazlo ahora, o por lo menos plantéatelo. No olvides que probablemente cambiarás la forma de trabajo de muchos de ellos. Improve the way you do business.
» Leer más, comentarios, etc...
La crisis de los huevos
Octubre 25th, 2004 - [Enlace local]
Para una versión apocalíptica de una empresa, en este caso informática, no dejen de leer La crisis de los huevos por Fuckowski en Memorias de un programador. Una visión Orweliana altamente recomendable sobre si ver cuatro o cinco dedos en nuestras vidas.
(via Javi’s Java)
» Leer más, comentarios, etc...
código escrito
Agujero de integridad, tapado
Octubre 23rd, 2004 - [Enlace local]
Si en algo he puesto empeño al escribir la versión 6.0 de Cuaderno de Bitácora ha sido en mantener la integridad referencial. Esto es, que todos los campos de los ficheros principales que se sirven de tablas auxiliares sólo puedan...
» Leer más, comentarios, etc...
Libros Gratis (Free Books)
Octubre 22nd, 2004 - [Enlace local]
A través de artERNATIVO llego a esta web en la que podemos encontrar muchos y buenos libros técnicos (casi todos de programación).
Una más para mis bookmarks.
» Leer más, comentarios, etc...
Pointer to (void)
Flash Remoting MX & .NET Primer
Octubre 22nd, 2004 - [Enlace local]
Bueno, por fin tengo hoy un rato para escribir después de toda la agotadora semana de (medio) descanso que he podido tomarme. Hoy, pequeños y pequeñas, tengo la ocasión de presentar el primer trozo de papel técnico de Pointer to Void: Como conectar Flash MX con un ensamblado desarrollado en C#. ¿Que qué significa exactamente todo esto? Pues bien, que podemos utilizar código para la plataforma .NET desde Flash.
En este ejemplo mostraremos como escribir una pequeña pequeñísima capa que provea datos a una aplicación escrita para .NET y utilizarla desde Flash. Crearemos un pequeño ensamblado en forma de DLL que obtendrá los datos de una base de datos SQL Server y devolverá un DataSet con los datos pedidos. Y utilizaremos esa DLL desde Flash MX con pocas líneas de código.
Lo primero que deberíais hacer, antes de tiraros a la piscina, es armaros de paciencia y una copia de Flash MX 2004 Prof, Flash Remoting MX, una instalación de IIS con ASP.NET y un compilador de C#. Tranquilos que existen versiones de evaluación para todo.
La instalación de Flash Remoting MX es lo que más se os complicará. Para el ejemplo de este articulo y para casi cualquier desarrollo que hagais, los pasos para tener el sistema listo son:
- Instalar el servidor Web, un entorno de desarrollo para C# y comprobar que funcionan las aplicaciones para .NET con la base de datos.
- Instalar Flash Remoting MX. Crear una nueva aplicación ASP.NET y copiar los archivos flashgateway.dll y frconfig.txt al directorio bin de la nueva aplicación. Podéis copiarlos del directorio de instalación de Flash Remoting. Crea también un archivo vacío llamado gateway.aspx en la raiz de la nueva aplicación. Este será el punto de entrada.
- Instalar los componentes Flash Remoting para Action Script 2.0.
- Bajar el ZIP de código fuente de esos componentes de la misma página y copiarlos al directorio First Run/Classes de la carpeta donde esté instalado Flash. (Capón a Macromedia por la cagada).
Una vez realizada toda esta instalación, crearemos una pequeña clase que provea datos. Extraeremos el nombre y los apellidos de los usuarios de una base de datos, tal como sigue a continuación:
using System;
using System.Data;
using System.Data.SqlClient;
namespace remoteDataProvider
{
public class DataProvider
{
public DataTable ObtenerUsuarios ()
{
SqlConnection sqlConnection = new SqlConnection (
"server=(local);database=fluxdb;
Trusted_Connection=true");
SqlDataAdapter sqlDataAdapter =
new SqlDataAdapter (
"SELECT nombre, apellidos FROM Usuario",
sqlConnection);
DataSet ds = new DataSet();
sqlDataAdapter.Fill (ds, "Usuario");
return ds.Tables["Usuario"];
}
}
}
Básicamente solo tenemos que tener en cuenta que para que Flash entienda el formato de los datos devueltos, estos deben devolverse como DataTable, lo que se convertirá en un RecordSet en Flash.
¿Y cómo accedemos a esta DLL en Flash?. Previamente compilada, procederemos a copiarla en el directorio bin de la aplicación creada anteriormente. Y ahora toca Action Script 2.0. Situaros en cualquier punto en el que queráis llamar a la función y el código necesario es el siguiente:
import mx.remoting.Service;
import mx.remoting.PendingCall;
import mx.rpc.RelayResponder;
import mx.rpc.FaultEvent;
import mx.rpc.ResultEvent;
import mx.remoting.RecordSet;
var servicioPrueba:Service = new Service (http://localhost/testRemotingApp/gateway.aspx, null, "remoteDataProvider.DataProvider", null, null);
var pc:PendingCall = servicioPrueba.ObtenerUsuarios();
pc.responder = new RelayResponder (this, "ObtenerUsuarios_Result", "ObtenerUsuarios_Fault");Como veis, el código apunta a la dirección URL de nuestra aplicación que enlazará el proveedor de datos con la aplicación en Flash. Hay dos funciones de callback definidas en la última línea (ObtenerUsuarios_Result y ObtenerUsuarios_Fault) que serán llamadas cuando se obtenga el resultado de haber llamado a la función o si dicha llamada falla. La función de callback una vez llegan los datos recibe un re:ResultEvent como entrada. El siguiente ejemplo muestra como utilizar ese objeto para extraer, de la primera fila, el nombre del usuario:
re.result.getItemAt(0).nombreResta recomendar la utilización de NetConnection Debuger, buena aplicación escrita en flash para depurar las conexiones entre los dos. Se instala con Flash MX. Otro día hablaremos de ello.
» Leer más, comentarios, etc...
Pointer to (void)
Flash Remoting MX & .NET Primer
Octubre 22nd, 2004 - [Enlace local]
Nota a 23 de enero de 2005: Siento no haber publicado el post antes, cayó en el olvido por error y estaba marcado como draft desde hace bastante... No he adjuntado el código fuente, por tiempo nada más, pero si alguien lo quiere encarecidamente lo empaqueto y lo subo. Gracias ;-)
Bueno, por fin tengo hoy un rato para escribir después de toda la agotadora semana de (medio) descanso que he podido tomarme. Hoy, pequeños y pequeñas, tengo la ocasión de presentar el primer trozo de papel técnico de Pointer to Void: Como conectar Flash MX con un ensamblado desarrollado en C#. ¿Que qué significa exactamente todo esto? Pues bien, que podemos utilizar código para la plataforma .NET desde Flash.
En este ejemplo mostraremos como escribir una pequeña pequeñísima capa que provea datos a una aplicación escrita para .NET y utilizarla desde Flash. Crearemos un pequeño ensamblado en forma de DLL que obtendrá los datos de una base de datos SQL Server y devolverá un DataSet con los datos pedidos. Y utilizaremos esa DLL desde Flash MX con pocas líneas de código.
Lo primero que deberíais hacer, antes de tiraros a la piscina, es armaros de paciencia y una copia de Flash MX 2004 Prof, Flash Remoting MX, una instalación de IIS con ASP.NET y un compilador de C#. Tranquilos que existen versiones de evaluación para todo.
La instalación de Flash Remoting MX es lo que más se os complicará. Para el ejemplo de este articulo y para casi cualquier desarrollo que hagais, los pasos para tener el sistema listo son:
- Instalar el servidor Web, un entorno de desarrollo para C# y comprobar que funcionan las aplicaciones para .NET con la base de datos.
- Instalar Flash Remoting MX. Crear una nueva aplicación ASP.NET y copiar los archivos flashgateway.dll y frconfig.txt al directorio bin de la nueva aplicación. Podéis copiarlos del directorio de instalación de Flash Remoting. Crea también un archivo vacío llamado gateway.aspx en la raiz de la nueva aplicación. Este será el punto de entrada.
- Instalar los componentes Flash Remoting para Action Script 2.0.
- Bajar el ZIP de código fuente de esos componentes de la misma página y copiarlos al directorio First Run/Classes de la carpeta donde esté instalado Flash. (Capón a Macromedia por la cagada).
Una vez realizada toda esta instalación, crearemos una pequeña clase que provea datos. Extraeremos el nombre y los apellidos de los usuarios de una base de datos, tal como sigue a continuación:
using System;
using System.Data;
using System.Data.SqlClient;
namespace remoteDataProvider
{
public class DataProvider
{
public DataTable ObtenerUsuarios ()
{
SqlConnection sqlConnection = new SqlConnection (
"server=(local);database=fluxdb;
Trusted_Connection=true");
SqlDataAdapter sqlDataAdapter =
new SqlDataAdapter (
"SELECT nombre, apellidos FROM Usuario",
sqlConnection);
DataSet ds = new DataSet();
sqlDataAdapter.Fill (ds, "Usuario");
return ds.Tables["Usuario"];
}
}
}
Básicamente solo tenemos que tener en cuenta que para que Flash entienda el formato de los datos devueltos, estos deben devolverse como DataTable, lo que se convertirá en un RecordSet en Flash.
¿Y cómo accedemos a esta DLL en Flash?. Previamente compilada, procederemos a copiarla en el directorio bin de la aplicación creada anteriormente. Y ahora toca Action Script 2.0. Situaros en cualquier punto en el que queráis llamar a la función y el código necesario es el siguiente:
import mx.remoting.Service;
import mx.remoting.PendingCall;
import mx.rpc.RelayResponder;
import mx.rpc.FaultEvent;
import mx.rpc.ResultEvent;
import mx.remoting.RecordSet;
var servicioPrueba:Service = new Service (http://localhost/testRemotingApp/gateway.aspx, null, "remoteDataProvider.DataProvider", null, null);
var pc:PendingCall = servicioPrueba.ObtenerUsuarios();
pc.responder = new RelayResponder (this, "ObtenerUsuarios_Result", "ObtenerUsuarios_Fault");
Como veis, el código apunta a la dirección URL de nuestra aplicación que enlazará el proveedor de datos con la aplicación en Flash. Hay dos funciones de callback definidas en la última línea (ObtenerUsuarios_Result y ObtenerUsuarios_Fault) que serán llamadas cuando se obtenga el resultado de haber llamado a la función o si dicha llamada falla. La función de callback una vez llegan los datos recibe un re:ResultEvent como entrada. El siguiente ejemplo muestra como utilizar ese objeto para extraer, de la primera fila, el nombre del usuario:
re.result.getItemAt(0).nombre
Resta recomendar la utilización de NetConnection Debuger, buena aplicación escrita en flash para depurar las conexiones entre los dos. Se instala con Flash MX. Otro día hablaremos de ello.
» Leer más, comentarios, etc...
Como no hacer una práctica de programación
Octubre 20th, 2004 - [Enlace local]
Estos artículos son muy útiles para aquellos que este año comienzan una Ingeniería Informática y no saben como afrontar una práctica en la que deban programar en algún lenguaje de programación. Sin más preámbulos:
- Cómo NO realizar una práctica de programación(Español)
- How NOT to go about a programming assignment (Inglés)
A los que tenéis un poco de experiencia tampoco os vendría mal leerlo
» Leer más, comentarios, etc...
Punteros a Funciones (Function Pointer)
Octubre 19th, 2004 - [Enlace local]
Los punteros a funciones (function pointers) son punteros, es decir, son variables que apuntan a la dirección de una función. Estos punteros son muy interesantes porque proveen técnicas muy elegantes y, sobre todo, eficientes. Se suelen usar para reemplazar sentencias switch/if, para realizar un enlace tardío (late-binding) o para implementar “callbacks”.
Debido a su sintaxis complicada no se trata con mucha profundidad en los libros de programación en C/C++, es por esto que recomiendo encarecidamente la web www.function-pointer.org que lo explica bastante bien.
En mi caso lo necesito para el “late-binding”, tengo que llamar a una función de la que no sé el nombre y no puedo hacerlo con métodos virtuales porque las funciones no son virtuales, por lo tanto no están en la V-Table. Esto implica que no se puede hacer de otra forma que no sea con punteros a funciones.
Espero que el enlace le sirva a alguien, aunque probablemente la parroquia no está muy interesada en programación tan específica, es más probable que este post le sirva más a los visitantes de El Oráculo
» Leer más, comentarios, etc...
¿Qué es Mutex?
Octubre 17th, 2004 - [Enlace local]
Hoy la cosa va de programación concurrente ![]()
Mutex es la abreviatura de “mutual exclusion”, es decir, exclusión mútua. Las variables Mutex son la forma más común de implementar la sincronización de threads y de proteger datos compartidos cuando acontecen multitud de escrituras sobre esos datos compartidos.
Una variable mutex actúa como un candado protegiendo los datos o recursos. El concepto básico de mutex en Pthreads es que sólo un thread puede cerrar el candado en un determinado instante. Incluso si varios threads intentan cerrar el mismo candado sólo uno saldrá victorioso. Ningún otro thread podrá poseer ese mutex hasta que el que lo cerró lo abra. Es decir, con esto conseguimos que los threads se turnen para acceder a datos protegidos o compartidos.
Los mutex pueden ser usados para prevenir “condiciones de carrera”. Este es un ejemplo de una “condición de carrera” en una transacción de un banco.
| Thread 1 | Thread 2 | Balance |
|---|---|---|
| Leer balance: 1000 | 1000 | |
| Leer balance: 1000 | 1000 | |
| Depósito 200 | 1000 | |
| Depósito 200 | 1000 | |
| Actualizar balance 1000 + 200 | 1200 | |
| Actualizar balance 1000 + 200 | 1200 |
En este ejemplo se debe utilizar un mutex para cerrar el “Balance” mientras un thread está utilizando este recurso compartido.
Muy a menudo la acción llevada a cabo por un thread que posee el mutex es la actualización de variables globales. Esta es la manera más segura de asegurar que los threads que actualizan la misma variable van a arrojar un resultado final igual al que arrojaría un sólo thread que realizara todas las operaciones.
Una típica secuencia en el uso de un mutex es:
1. Crear e inicializar la variable mutex.
2. Varios threads intentan bloquear el mutex.
3. Sólo uno lo hace y es el poseedor del mutex.
4. El poseedor del mutex realiza un conjunto de acciones.
5. El poseedor del mutex desbloquea el mutex.
6. Otro thread toma el mutex y repite el proceso.
7. Finalmente el mutex es destruido.
Cuando varios threads compiten por un mutex, los perdedores se bloquean hasta que el ganador desbloquea el mutex.
Y hasta aquí la lección de hoy
» Leer más, comentarios, etc...
Transacciones con AOP en Spring
Octubre 11th, 2004 - [Enlace local]
AOP (Aspect Oriented Programming) nos ofrece una forma diferente de declarar servicios para muestra aplicación y sin entrar en detalle en todo el mundo AOP, podemos utilizar solamente un subconjunto de su funcionalidad para agregar transaccionalidad declarativa a los servicios que desarrollemos, utilizando method interception.
Spring AOP integra el soporte AOP en la infraestructura misma de Spring, permitiéndonos declarar la transaccionalidad de los servicios en el mismo XML de configuración de nuestros beans.
Típicamente, en Spring 1.1.1, definimos una plantilla para nuestras transacciones:
<bean id= “daoTxProxyTemplate” abstract= “true” class= “org.springframework.transaction.interceptor.TransactionProxyFactoryBean”> <property name= “transactionManager”><ref bean= “transactionManager”/></property> <property name= “transactionAttributes”> <props> <prop key= “save*”>PROPAGATION_REQUIRED</prop> <prop key= “remove*”>PROPAGATION_REQUIRED</prop> <prop key= “update*”>PROPAGATION_REQUIRED</prop> <prop key= “*”>PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean>en la cual está especificado el transactionManager que utilizaremos, y una serie de patterns de nombres de métodos, sobre los cuales definiremos que tipo de transacción es requerida para los métodos que se ajusten a ese pattern.
Luego solo queda comenzar a definir nuestros servicios, con la implementación como inner bean:
<bean id= “itemManager” parent= “daoTxProxyTemplate”> <property name= “target”> <bean class= “com.example.services.itemManagerImpl”> <property name= “itemManagerDAO”><ref bean= “itemManagerDAO”/></property> </bean> </property> </bean>Asi, ante cada llamada al método saveItem de la clase itemManagerImpl (definida en el bean itemManager), Spring creará una transacción (o reutilizará una existente) antes de la llamada, y hará el commit luego de ella.
Mas adelante podríamos seguir definiendo nuestro servicios, por ejemplo uno sin propiedades, y con los parámetros de propagación sobreescritos:
<bean id= “miServicio” parent= “daoTxProxyTemplate”> <property name= “target”> <bean class= “com.example.services.otroServicio”/> </property> <property name= “transactionAttributes”> <props> <prop key= “load*”>PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean>En cuanto a los tipos de propagación para las transacciones y su nivel de aislamiento, lo mas utilizado es simplemente PROPAGATION_REQUIRED, pero podemos optar por todos los definidos en la interfaz
TransactionDefinition
, utilizando el formato “PROPAGATION_NAME, ISOLATION_NAME, readOnly, timeout_NNNN, +Exception1, -Exception2″, siendo PROPAGATION_NAME el único requerido.
En la definición de la plantilla de transacciones, también definimos una propiedad transactionManager. Este bean, puede tomar la forma de
<bean id= “transactionManager” class= “org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name= “dataSource”><ref bean= “defaultDataSource”/></property> </bean>si trabajamos con JDBC directamente, o
<bean id= “transactionManager” class= “org.springframework.orm.hibernate.HibernateTransactionManager”> <property name= “sessionFactory”><ref local= “sessionFactory”/></property> </bean>si utilizamos Hibernate.
Queda para otro post como definir el sessionFactory de Hibernate y el dataSource (con pooling o sin el) necesarios.
» Leer más, comentarios, etc...
El arte de programar
A tortas con el MFC y los cursores e iconos
Octubre 4th, 2004 - [Enlace local]
Bueno, hoy he estado haciendo pruebas sobre como crear un control estático donde maneje a mi antojo lo que dibuje en el con MFC para windows, y entre otras cosas se me ha ocurrido meterle un icono como dibujo y que cuando el ratón pase por una zona del control se cambie el cursor (el puntero).
Para el primero he tenido varios problemas puesto que no esta muy depurada la API de windows para manejar cursores y dejarlos en 16x16 pixeles, haciendo cosas raras, menos mal que dentro del oceano de Internet uno puede ir recopilando informaciones cuando no se encuentra todo en un documento para saber como hacerlo. Tan sencillo como esto:
HICON icono=(HICON)LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_SEMAFOROVERDE),
IMAGE_ICON,
16,16,
LR_DEFAULTCOLOR);
DrawIconEx(fondo.GetSafeHdc(),10,10,icono,16,16,0,NULL,DI_NORMAL);
DestroyIcon(icono);
-Primero cargo el icono con la función LoadImage, donde le paso como parámetros la instancia de la aplicación donde se encuentra el icono (la misma aplicación donde se ejecuta), el identificador del recurso del icono pasado a cadena con la macro MAKEINTRESOURCE, el tipo de imagen que es (un icono), la anchura y la altura del mismo y finalmente que lo coja con los colores por defecto.
-Segundo dibujo el icono en el dispositivo de contexto que nos ofrece windows para dibujar en el control CStatic, no uso la función DrawIcon del objeto de dispositivo contexto por que no consigue adaptar bién el icono a 16x16 pixeles, por lo que uso la función win32 DrawIconEx que si me lo permite, pasandole como parámetros el manejeador del dispositivo de contexto, la posición x e y donde quiero dibujar el icono, el icono, su achura y altura, ningúna brocha (no es necesario) y le digo que es una imagen con transparencias (DI_NORMAL indica todo eso).
-Tercero lo destruyo porque en esto de la programación en C es bueno la "limpieza".
Para el segundo caso, siendo aún más sencillo me he partido más los cuernos, simplemente porque el evento que se debe usar para cambiar el cursor no tiene mucha lógica con lo que uno quiere hacer. Mi idea es que cuando moviese el ratón por una zona del CStatic, se cambiase el cursor, sin embargo usando el evento OnMouseMove no funciona para nada la función SetCursor. He de decir que cuando digo CStatic, en realidad es una clase que he derivado de esa para poder interceptar los eventos. Por lo visto para que funcione lo que queremos hacer debemos usar el vento OnSetCursor, que funciona a semejanza del OnMouseMove, pero que no te da las coordenadas dentro del control donde se encuentre el puntero del ratón, sino que se activa cuando se pasa el ratón por el control. Esto no funcionaría si no tuviesemos activado la opción "notify" de los estilos del control. Aquí dejo mi solución de como lo he conseguido al final:
POINT point;
GetCursorPos(&point);
ScreenToClient(&point);
if(point.y>=10 && point.y<66)
{
::SetCursor(LoadCursor(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDC_CURSOR)));
return TRUE;
}
return CStatic::OnSetCursor(pWnd, nHitTest, message);
-Primero declaro una variable POINT, luego pregunto con GetCursorPos que me diga la posición relativa a pantalla donde se encuentra el ratón, y a continuación lo transformo a coordenadas del control gracias a la función ScreenToClient. Con todo esto logramos saber en que posición de nuestro control esta el cursor ya que el OnSetCursor no nos la da como parámetro como lo hicera el OnMouseMove.
-Segundo comparo si el cursor esta dentro de un rango en el eje de la altura y si es así ya uso la función SetCursor (de la api de win32 no del objeto), pasandole como parámetro el cursor que me devuelve la función LoadCursor, a la cual se le pasan como parámetros la instancia donde se encuentra el cursor (la nuestra en este caso) y el identificador del cursor pasado a cadena con la macro explicada antes. Después salimos de la función delvolviendo un valor TRUE indicando que no hay que hacer nada más.
-Tercero, si llega hasta aquí significa que no ha pasado por el if y que llama al manejador por defecto devolviendo el valor que a su vez este devuelve, esta linea la incorpora automáticamente el Editor de Visual C++ cuando añadimos el evento OnSetFocus.
Como veis la programación de Windows es apasionante, pero muchas veces me encuentro con cosas que no funcionan como deben o se manejan de forma ilógica, pero bueno, menos mal que ya hay mucho escrito sobre eso. Por cierto, sigo pendiente de aprender programar linux, estoy por el capítulo de programación avanzada de ficheros y en siguiente ya son los demonios, y aún así me queda mucho libro por leer :)