Skip navigation

Tag Archives: ejemplos

Contenido

 

            

Introducción

Este artículo intenta acercar al lector a la práctica de desarrollo orientado a la calidad utilizando la técnica de BDD, a partir de la descripción conceptual de su utilización, beneficios, casos de uso y un ejemplo.

Objetivos

Brindar la información y los beneficios sobre esta técnica para que el lector tenga la facultad de evaluar y decidir si dicha práctica es conveniente para el proyecto en el que está trabajando.  

Seguir leyendo

Anuncios

Tengo un post en el hornito listo para salir, pero primero algunas curiosidades.

Estuve trabajando un poco con reflection, una de las características mas fuerte de Java y poco explotadas que si son bien manejadas pueden construirse lindos frameworks como Spring, Seam o implementar el stack de EJB. Por el otro lado, el exceso del uso impacta directamente en la performance de la aplicación y si estamos haciendo cosas complejas utilizando Proxies podemos perdernos y el flujo de ejecución termina lejos de donde esperabamos.

Vamos a ver de que hablamos cuando hablamos de reflection. Aclaro que lo que vallan a leer es solo por la experiencia de uso, no soy ningún experto en la materia, así que cualquier corrección es bienvenida.

Supongamos que tenemos una tarea simple, le queremos listar todas las posibles acciones que nuestro EJB puede hacer al consumidor. Obviamente la primera respuesta es tenerlo en archivo de configuración posiblemente un xml blah blah blah… pero la verdad es que toda esta información ya está escrita y está en la interfaz del EJB. La pregunta es como hacemos para transformar este código en información visible, y no voy a dar mas vueltas.

Seguir leyendo

 

Un patrón muy utilizado dentro del mundo JEE es el conocido Service Locator, sobre todo para acceder a instancias de EJBs como vamos a ver en el ejemplo mas adelante.

Lamentablemente, aunque se detecta la necesidad de un componente que resuelva el problema de acceder ciertos servicios no siempre la solución implementada cumple con los requisitos o la manera de resolverlo tiene resultados no esperados, como por ejemplo hacer que dicho patrón sea estático o mezclarlo con un Singleton y sumar al caldo un cache _global_ de Stateful Session Bean (aka SFSB), aunque irónicamente se haga cache de Stateless Session Bean (aka SLSB) con el mismo fin. Está bien, en ciertas ocasiones un cache no vendría mal pero vale la pena analizarlo a fondo porque, como _toda_ solución de cache ( deberían anotarlo si no lo saben ), trae muchos efectos colaterales… muchos.

Primer problema, supongamos que decidimos hacer a la instancia del Service Locator (desde ahora SL) estática porque observamos que no importa el estado del SL, para un nombre de SB queremos que nos devuelva dicho SB sea SF o SL. Si la instancia del Service Locator es única los SFSB que quedan asociados van a ser los mismos para cada llamado dentro de la aplicación, haciendo a nuestro SFSB un servicio estático también.

Segundo problema, si la referencia que tenemos a cada SFSB se mantienen abierta durante mas tiempo de lo que necesitamos y tenemos un problema de conexión o cualquier otro imprevisto ya no hay manera de volver a usar dicho servicio si no renovamos la referencia, esto va sobretodo para aquellos que usan los SFSB con “métodos estáticos” o sin estados como por ejemplo “int sumarDos(int base)”. Para que se entienda, si tenemos un SFSB asociado a la sesión y el servidor de EJBs se reinicia entro dos llamados, el segundo llamado va a fallar porque el id de SFSB que tiene el cliente que consume dicho servicio no existe en el servidor de EJBs, tirando la siguiente excepción:

javax.ejb.NoSuchEJBException: Could not find stateful bean: <super_id_largo_y_horrible>

Los problemas, o mejor dicho las causas de perder la referencia a un SFSB pueden ser varias ( no siempre un problema ), las mas comunes:

  • Reinicio del servidor de EJBs, si tenemos el cliente y los ejbs en diferentes máquinas virtuales
  • Inactividad por un tiempo prolongado. Recuerden que los SFSB son uno por cliente, por lo que el contenedor de EJBs destruirá cualquier SFSB que esté inactivo por mas tiempo que por configuración se le indica.
  • Si llamamos a un método con la anotación @javax.ejb.Remove pero mantenemos la referencia al SFSB.
  • etc..

Solución: NO guardar ninguna instancia de Session Bean en un Service Locator, por mas tentadora que parezca la idea, por mas creamos que sea una buena optimización. En el único caso que vale la pena es cuando sabemos que vamos a consumir solo SLSB, pero como el cliente supuestamente no sabe nada sobre la implementación de los servicios esta solución nos puede traer mas dolores de cabeza mas tarde.

 

Dicho esto y como el titulo prometía hablar de JBoss Seam vamos a ver que les parece mi propuesta. Mi Service Locator, si bien van a ver que las clases tienen dependencias de runtime en Seam, la idea principal se puede usar sin este framework.

Empecemos por el principio, el punto de vista del usuario del patrón. ¿Cuál es el mejor Service Locator que conocen? Yo el @EJB, vamos a ver que tan parecido lo podemos hacer.

Hay una anotación de Seam muy parecida, @org.jboss.seam.annotations.In que nos permite inyectar dependencias, el problema es que no queremos hacer un componente diferente por cada implementación que valla a utilizar el cliente, a lo sumo llamaremos al SL con el nombre del EJB que queremos utilizar. Y como hacemos eso con Expression Language (EL) ? Un mapa de ejbs :D

Sería algo como esto:

    @org.jboss.seam.annotations.In("#{locator['myEJBImplBean']}")
    private MyEjbInterface mei;

Excelente, entonces _locator_ es nuestro componente encargado de encontrar los servicios, nuestro Service Locator. Pero como que es un Mapa? Veamos la implementacion

@Name("locator")
@Scope(ScopeType.APPLICATION)
public class EjbLocator implements Serializable {

    public Object locate(String name) throws RuntimeException {
        try {
            String jndi = Init.instance().getJndiPattern();
            return new InitialContext().lookup( jndi.replace("#{ejbName}", name) );
        } catch (NamingException ex) {
            log.error("Error inicializando el ejb " + name , ex);
        }
        return null;
    }

    @Unwrap
    public Map<string ,Object> getResource(){
        return new Map</string><string ,Object>(){

            public Object get(Object key) {
                return locate((String)key);
            }

            /* .... muchos metodos que no tiene sentido agregar ... */

            public Object put(String key, Object value) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

        };
    }

}

Nota:

  • Todas las anotaciones están bajo el paquete org.jboss.seam.annotations
  • La instancia de InitialContext se podría generar menos seguido
  • Obviamente quite código q no venia al caso :)

Entonces, tenemos un componente Singleton que nos sirve como Service Locator que cuando hacemos referencia a él lo que obtenemos es un mapa. Cuando busquemos un objeto dentro del mapa con la key X, el SL intentará encontrar una referencia a un EJB con el nombre X.

Claramente, los métodos pueden ser estáticos pero la verdad en este caso no hace la diferencia, la magia está en como esto se mezcla con Dependency Injection y Expression Language. Sientanse libres de mandar sugerencias, ideas, correcciones o simples comentarios.

Y como decían en Nivel-X, bueeeno.. esto fue todo y espero q les haya gustado. ( espero que no tenga copyright =P )