El tráfico gracias a la contribución de muchos usuarios móviles de Google Maps

30 August, 2009 (22:13) | General | By: jose.selman

El concepto de Crowdsourcing fue introducido originalmente por personajes de la revista Wired; resumiendo en una línea podríamos decir que, en términos generales, se trata de la contribución masiva de voluntarios aplicando principios de autoorganización.
Esta semana leí en Google Mobile Blog una nueva aplicación de este concepto lograda gracias a los aportes anónimos de usuarios volutarios de Google Maps en sus celulares. Al igual que cuando compartimos nuestra ubicación usando Latitude, el tener la aplicación Google Maps corriendo en nuestros celulares (con GPS) permite que esta envíe información anónima de por donde nos movemos y a qué velocidad lo estamos haciendo. Esta información, provista por miles de contribuyentes, es agregada y permite tener una muy buena aproximación de cómo se ve el tráfico en las distintas arterias en tiempo real, la cual puede accesarse desde la misma aplicación en nuestros móviles. Por ahora este servicio se encuentra disponible sólo en Estados Unidos, cubriendo las principales autopistas… Sólo nos queda esperar que se masifique a otros lugares.
Me pregunto como podría utilizarse este servicio en zonas urbanas, por ejemplo el centro de Santiago, donde muchas veces se logra avanzar más rápido caminando que arriba de un auto… :-)

La revolución de los medios sociales

23 August, 2009 (21:34) | General | By: jose.selman

Navegando por ahí me topé con este video que encontré bastante interesante. Las cifras dejan mucho que pensar. Si les interesa este tema les recomiendo el libro Wikinomics.

Via: FayerWayer

El problema de la reutilización

20 August, 2009 (17:08) | General | By: jose.selman

Que las organizaciones logren bajos niveles de reutilización en la construcción de su Software es bastante más común de lo que uno podría esperar. Existe, en general, un gran esfuerzo para crear frameworks, patrones, etc. que fomentan la reutilización de componentes pero sin embargo no logran los resultados esperados.

¿Por qué?

Para que alguna de las piezas de nuestro Software sea reutlizada necesitamos, al menos, que quién podría utilizarlo sepa oportunamente que está ahí y que conozca cómo utilizarlo. En caso contrario, sumado a las constantes presiones de cortos ciclos de delivery, parece muchas veces ser más fácil y rápido hacer cada pieza desde cero. El enfoque anterior trae, como nos ha enseñado la historia, problemas de mantención para el futuro.

La comunicación efectiva es clave; la solución no pasa por temas técnicos. Encontrar la fórmula que sea capaz de comunicar correcta, efectiva y oportunamente información acerca de los artefactos que están diponibles para ser reutilizados es el desafío… Como hacerlo va a depender de la cultura de cada una de las organizaciones…

Información Relacionada: Reuse is about people and education, not just architecture

Inicios en el Snowboard

11 August, 2009 (23:06) | Uncategorized | By: jose.selman

Como he estado con mucho trabajo y trámites personales no había tenido el tiempo para subir esto antes. Tuve la suerte de ir a Valle Nevado hace unos días con varios compañeros de oficina, entre ellos dos personas de Costa Rica y uno de Brasil. Como se ve en el video, era su primer día pero le pusieron muchas ganas.

Brasil y Costa Rica en Valle Nevado from Jose Selman on Vimeo.

Los Arquitectos deben “ensuciarse las manos”

28 June, 2009 (18:59) | General | By: jose.selman

Hace un tiempo me compre el libro “97 Things Every Software Architect Should Know”, libro que recopila algunos pensamientos de varios arquitectos. Ha resultado muy entretenido ya que son pequeños artículos de 2 o 3 páginas que van directo al grano.

Uno de mis axiomas favoritos hasta el momento: Architects Must Be Hands-on de John Davies, el cual resumo a continuación:

Un buen arquitecto debe liderar siendo el ejemplo, el o ella debe ser capaz de realizar las tareas de cualquiera de los miembros de su equipo desde cablear la red, hasta escribir los procedimientos de compilación, hasta escribir pruebas unitarias, etc. Sin una buena comprensión de todo el rango de tecnología un arquitecto no sería nada distinto a un líder o jefe de proyecto. Es perfectamente aceptable de que cada miembro del equipo tenga un conocimiento más profundo en su área específica pero es difícil de imaginar que el equipo pueda tener confianza en un arquitecto que no entiende la tecnología. Como se ha dicho siempre, el arquitecto es la interfaz entre el negocio y el equipo de tecnología; el arquitecto debe comprender cada aspecto de la tecnología para representar a todo el equipo sin tener que estar constantemente refiriéndose a otros. Similarmente, el arquitecto debe entender el negocio para conducir al equipo hacia su objetivo en función de servir las necesidades del negocio. 

Un arquitecto es como el piloto de un avión; puede no parecer ocupado todo el tiempo pero usa años de experiencia para constantemente monitorear  la situación, tomando acciones inmediatas si oye o ve algo fuera de lo común. El jefe de proyecto (co-piloto) ejecuta las tareas rutinarias del día a día liberando al arquitecto de tareas mundanas y la administración de personas.

Las personas aprenden mejor mirando a otros; así aprendemos como niños. Un arquitecto debe ser capaz de identificar un problema, juntar al equipo y, sin elegir a una victima, explicar de qué se trata el problema y proveer una solución elegante al mismo. Es perfectamente respetable que el arquitecto pida ayuda al equipo. El equipo debe sentirse parte de la solución pero es responsabilidad del arquitecto liderar la discusión e identificar la solución correcta.

Esto último, al menos a mí, me ha resultado muy bien. Lo único que se logra al identificar a una víctima es crear un clima laboral poco cálido en el cual es muy difícil sacar el 100% de las personas. 

Un arquitecto viene generalmente con un muy buen curriculum y con un pasado impresionante, pudiendo impresionar al negocio y a los tecnólogos pero, a menos que pueda demostrar metiendo las manos lo que puede hacer, es difícil que se gane el respeto del equipo, dificultando la habilidad del equipo para aprender y como consecuencia hacer casi imposible entregar aquello para lo cual fueron contratados originalmente.

Lo anterior se fortalece un poco gracias a otro axioma de Mike Brown If you design it, you should be able to code it. Claro, ¿cómo puedo exigir a otros algo que yo no soy capaz de hacer? Aunque parezca insólito esto es bastante más común de lo que uno pudiera esperar…

Creando un WebService alla JAX-WS con Netbeans y GlassFish

23 June, 2009 (14:45) | Java | By: jose.selman

Vamos a asumir para este ejemplo que tenemos Netbeans y Glassfish correctamente instalados.

Primero debemos crear un proyecto para un nuevo módulo EJB.

1-modulo-ejb.png

2-modulo-ejb.png

3-servidor-para-el-modulo.png

Luego, debemos crear un servicio.

4-nuevo-web-service.png

5-nuevo-web-service.png

Agregamos una operación al servicio recién creado. Las operaciones son implementadas como métodos de nuestro Stateless Session EJB.

6-agregar-operacion.png

7-parametros-operacion.png

Modificamos el “esqueleto” generado por Netbeans para proveer una implementación de la operación.

8-implementar-operacion.png

Finalmente, podemos compilar y hacer el deployment en nuestro servidor.

9-compilar-y-correr.png

Lo que nos permite abrir el tester y probar nuestro servicio.

10-inicializar-el-tester.png

11-probar.png

Facil, ¿no? Pueden descargar el código desde acá.

Cerrando ciclos y una nueva etapa…

22 June, 2009 (18:45) | General | By: jose.selman

Muchos me han presionado para que oficialice un par de cambios que han ocurrido últimamente en mi vida, asi que acá va.

El pasado Viernes 19 de Junio fue mi último día de trabajo en BEE. La razón es bastante sencilla; después de siete años y medio siento que llegó el momento de explorar nuevos caminos en el ámbito profesional. Dejo BEE pero me llevo muchísimos logros, alegrías pero por sobre todo la gran amistad que generé durante todo ese tiempo. Dejó atras, además, a un excelente equipo, sin el cual no hubiese sido posible lograr todo lo que hicimos. No tengo dudas de que serán capaces de seguir entregando, como siempre, lo mejor de si para alcanzar lo inalcanzable…

Estaré de vacaciones hasta el 1ero de Julio y asumiré como ¡Senior Solutions Architect en Oracle! Adicionalmente a esta gran noticia, tengo una noticia aún más importante… ¡Voy a ser padre! Mi señora tiene recién 8 semanas… Estamos muy contentos y lo increíble es que llegara todo junto :-) … En fin, estamos muy contentos con todo lo que ha pasado y nos estamos preparando para este nuevo desafío que nos esta planteando la vida; probablemente el más difícil…

Por ahora, estoy intentando aprovechar al máximo esta semana para descansar lo más que pueda cosa de poder recargar mis baterías al 100%… Muy pronto inicio una nueva etapa en mi vida en la cual estoy seguro de que necesitaré mucha energía para enfrentar este nuevo gran desafío.

Un breve ejemplo de JPA con NetBeans y GlassFish

8 June, 2009 (11:14) | Java | By: jose.selman

No hay deuda que no se pague… En un curso que dicté hace poco quedé de hacer una pequeña aplicación para mostrar las cosas básicas que se pueden hacer con JPA (Java Persistence API). Dado que el curso era el FJ-310-EE5 (Developing Applications for the Java EE Platform), oficial de Sun, y que los alumnos ya se encuentran familiarizados con NetBeans y GlassFish usaré en este ejemplo Netbeans 6.1 y GlassFish v2. El objetivo de este artículo no es un “JPA paso a paso” sino que destacar un par de puntos clave en el desarrollo con JPA.

screenshot-menu.png

Como GlassFish v2 viene con JavaDB, tambien conocida como Apache Derby, será la base de datos que usaremos para este ejemplo. Primero es necesario crear una nueva base de datos.

0-derby-menu.png 1-derby-crear-db.png

Luego creamos una conexión desde Netbeans.

2-conexion-db.png

En nuestro ejemplo crearemos un proyecto de tipo Java EE, que generará un EAR EjemploJPA compuesto de dos módulos.

  • EjemploJPA-war
  • EjemploJPA-ejb

Adicionalmente crearemos un proyecto tipo Java bautizado EjemploJPA-Lib, en el cual definiremos nuestras entidades, interfaces y excepciones. Con lo anterior vemos que tenemos lo siguiente en NetBeans:

proyectosennetbeans.png

En este ejemplo, tendremos dos entidades principales: Cliente y OrdenDeCompra, donde un Cliente puede tener 0 o más ordenes de compra.

package com.joseselman.ejemplojpa.entidades;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import javax.persistence.*;

@Entity
@Table(name="cliente")
public class Cliente implements Serializable {

    private int id;
    private String nombre;
    private Collection<OrdenDeCompra> ordenes;

    @Id
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    @OneToMany(cascade=CascadeType.ALL, mappedBy="cliente", fetch=FetchType.LAZY)
    public Collection<OrdenDeCompra> getOrdenes() {
        return ordenes;
    }

    public void setOrdenes(Collection<OrdenDeCompra> ordenes) {
        this.ordenes = ordenes;
    }
}
package com.joseselman.ejemplojpa.entidades;

import javax.persistence.*;

@Entity
@Table(name="orden")
public class OrdenDeCompra implements java.io.Serializable {

    private int id;
    private String direccion;
    private Cliente cliente;
    private int monto;

    @ManyToOne()
    @JoinColumn(name="ID_CLIENTE")
    public Cliente getCliente() {
        return cliente;
    }

    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    @Column(name="DIRECCION_ENVIO")
    public String getDireccion() {
        return direccion;
    }

    public void setDireccion(String direccion) {
        this.direccion = direccion;
    }

    @Id
    @Column(name="ID_ORDEN")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getMonto() {
        return monto;
    }

    public void setMonto(int monto) {
        this.monto = monto;
    }
}

En el módulo EjemploJPA-ejb creamos una Unidad de Persistencia (Persistence Unit):

persistenceunit.png

Lo que genera el siguiente archivo de configuración:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="EjemploJPA-ejbPU" transaction-type="JTA">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <jta-data-source>ds/ejemploJPA</jta-data-source>
    <jar-file>EjemploJPA-Lib.jar</jar-file>
    <properties>
      <property name="toplink.ddl-generation" value="drop-and-create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

Al hacerlo con el IDE, se encarga de crear el Connection Pool y Data Source en el servidor de aplicaciones. En caso contrario tendríamos que crear el Connection Pool y DataSource directamente en la consola del servidor de aplicaciones.

datasource-connection-pool.png

Como seleccionamos la estrategia DROP AND CREATE, en la unidad de persistencia, las tablas son creadas en forma automática al correr la aplicación.

tablas-estructura.png

Adicionalmente creamos un Stateless Session EJB para ejecutar un par de consultas a la base de datos.

El método cargarDatos() para poblar datos en la base de datos. Notar que es necesario indicar las referencias en ambas puntas de la relación. Además, recordemos que el contexto de persistencia vive a lo largo de toda la transacción.

public void cargarDatos() throws ClientesOrdenesDAOException {
        Cliente clienteVictor = new Cliente();
        clienteVictor.setId(1);
        clienteVictor.setNombre("Victor");

        em.persist(clienteVictor);

        OrdenDeCompra ordenDeCompraVictor1 = new OrdenDeCompra();
        ordenDeCompraVictor1.setId(1);
        ordenDeCompraVictor1.setDireccion("XXXXXXXX 1200");
        ordenDeCompraVictor1.setMonto(100000);

        OrdenDeCompra ordenDeCompraVictor2 = new OrdenDeCompra();
        ordenDeCompraVictor2.setId(2);
        ordenDeCompraVictor2.setDireccion("ZZZZZZZZ 5688 depto. 101");
        ordenDeCompraVictor2.setMonto(150000);

        // Las asociaciones
        ordenDeCompraVictor1.setCliente(clienteVictor);
        clienteVictor.getOrdenes().add(ordenDeCompraVictor1);

        ordenDeCompraVictor2.setCliente(clienteVictor);
        clienteVictor.getOrdenes().add(ordenDeCompraVictor2);

        Cliente clienteJaime = new Cliente();
        clienteJaime.setId(2);
        clienteJaime.setNombre("Jaime");

        em.persist(clienteJaime);

        OrdenDeCompra ordenDeCompraJaime1 = new OrdenDeCompra();
        ordenDeCompraJaime1.setId(3);
        ordenDeCompraJaime1.setDireccion("YYYYYY 6006 of. 26");
        ordenDeCompraJaime1.setMonto(200000);

        // Las asociaciones
        ordenDeCompraJaime1.setCliente(clienteJaime);
        clienteJaime.getOrdenes().add(ordenDeCompraJaime1);

        Cliente clienteJose = new Cliente();
        clienteJose.setId(3);
        clienteJose.setNombre("Jose");

        em.persist(clienteJose);

        OrdenDeCompra ordenDeCompraJose1 = new OrdenDeCompra();
        ordenDeCompraJose1.setId(4);
        ordenDeCompraJose1.setDireccion("TTTTTTT 103 depto 1604");
        ordenDeCompraJose1.setMonto(500000);

        // Las asociaciones
        ordenDeCompraJose1.setCliente(clienteJose);
        clienteJose.getOrdenes().add(ordenDeCompraJose1);
    }

Al llamar a este método, vemos que los datos son cargados en la base de datos.

screenshot-carga.png tablas-contenido-cliente.png tablas-contenido-orden.png

El método listarClientes() para consultar todos los clientes y sus ordenes de compra ingresadas. Acá hacemos "el truco" de recorrer las "relaciones" de la entidad para asegurarnos que serán cargadas; recordemos que marcamos esta relación como LAZY.

public Cliente[] listarClientes() throws ClientesOrdenesDAOException {
        Query q = em.createQuery("SELECT c FROM Cliente c");
        Cliente[] clientes = (Cliente[])(q.getResultList()).toArray(new Cliente[0]);
        if (clientes != null) {
            for(int i=0; i<clientes.length; i++) {
                // Para asegurarnos que se carguen las relaciones "LAZY"
                clientes[i].getOrdenes().size();
            }
        }
        return clientes;
    }

screenshot-todos.png

El método consultarClientesMontos() genera un reporte con los nombres de los clientes y la suma de todas las ordenes de compra asociadas a ellos. Para este caso fue necesario crear un DTO (Data Transfer Object) para que sirva como contenedor para el resultado.

  public ClienteMontoDTO[] consultarClientesMontos() throws ClientesOrdenesDAOException {
        Query q = em.createQuery("SELECT NEW com.joseselman.ejemplojpa.dto.ClienteMontoDTO(c.nombre, SUM(o.monto)) " +
                "FROM Cliente c LEFT JOIN c.ordenes o GROUP BY c.nombre");
        ClienteMontoDTO[] resultado = (ClienteMontoDTO[])(q.getResultList().toArray(new ClienteMontoDTO[0]));
        return resultado;
    }

screenshot-reporte.png

Descarga los proyectos NetBeans desde acá

Referencias: Glassfish Project – Java Persistence Example.

Estilos de Gestión

16 May, 2009 (16:45) | General | By: jose.selman

Un amigo me mostró ayer un artículo titulado “Proyectos, Gestión, Gestores y Programadores” que además de encontrarlo elocuente por una serie de temas internos, es muy interesante; está sustentado sobre una sólida teoría de administración del profesor de la Escuela de Administración del MIT, Douglas McGregor denominada Teoría X y Teoría Y la cual examina el comportamiento de los indivíduos en el trabajo. Si llevamos esto a la Gestión de Proyectos, nos encontramos con dos estilos de gestión:

  • Predictiva, al estilo de la Teoría X. De acuerdo a la teoría, los seres humanos tienen un rechazo inherente al trabajo y por lo tanto hay que hacer predominar el control, vigilar riesgos y contar con mecanismos de castigo.
  • Ágil, al estilo de la Teoría Y. Este tipo de gestores se caracteriza por dar lo mejor de ellos en su trabajo, velar por la calidad de los entregables, el establecimiento de metas y darle mucha importancia al compromiso personal y del equipo.

¿Se sienten identificados por alguna?

Obviamente, distintos tipos de proyectos necesitan distintos tipos de gestores, los que deben ser capaces de balancear entre ambos estilos para lograr los resultados esperados.

xy11.jpg

Desde la perspectiva de los programadores la cosa también puede cambiar de acuerdo al tipo de gestor que tengan como supervisor.

xy21.jpg

Fuente: http://www.navegapolis.net/content/view/761

Ideal para las vacaciones… Uno menos en mi WishList

13 April, 2009 (23:54) | General, Java | By: jose.selman

Luego del que ha sido, probablemente, el verano con más trabajo de toda mi vida, me voy de vacaciones el 30 de Mayo por un poco más de una semana… ¡Realmente lo necesito! Eso sí, no me puedo arrancar sin un buen libro para leer en mis ratos de ocio (que espero que sean muchos), así que hace un rato encargué a través de Amazon el libro 97 Things Every Software Architect Should Know que promete ser un libro livianito ideal para esta ocasión.

Pronto voy a poder transformar:

  • Leer 97 Things Every Software Architect Should Know

a:

  • Leer 97 Things Every Software Architect Should Know