viernes, 14 de marzo de 2014

SLF4J: Multiple bindings were found on the class path logback

En el proyecto que estoy trabajando utilizamos SLF4J como framework de logging. Estaba teniendo un problema en el cual mis llamados para registrar entradas en el log no estaban apareciendo. Al principio pensé que era un problema con el archivo de log4j ya que esta era la implentación final que se estaba utilizando. Sin embargo luego me dí cuenta de unos mensajes apareciendo al principio del arranque de la aplicación:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/atg-dev/.m2/repository/ch/qos/logback/logback-classic/0.9.28/logback-classic-0.9.28.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/atg-dev/.m2/repository/org/slf4j/slf4j-log4j12/1.6.2/slf4j-log4j12-1.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
2014-03-13 21:30:46.718:INFO:/search-indexer:Initializing Spring root WebApplicationContext


Los mensajes estaban indicando que habían varios bindings, es decir, varias implementaciones de logging dentro del classpath. En específico pude ver que aparte de Log4j estaba LogBack, el cual no encontré ninguna referencia en el pom.xml. Había que descubrir la dependencia indirecta/transitiva.

La mejor manera para hallar la dependencia transitiva fue una idea de un compañero de utilizar el plugin de Maven en Eclipse que permite ver la jerarquía de dependencias.



De esa manera pude ubicar la dependencia que incluía al logback y agregar la exclusión:



        <dependency>
            <groupId>com.xxx.content</groupId>
            <artifactId>content-dao-jar</artifactId>
            <version>xx.xx.x.x</version>
            <exclusions>                
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

martes, 11 de marzo de 2014

Git: Lista de comandos útiles

Revertir cambios locales del branch al contenido remoto

git reset --hard origin/<branch>

Fusionar branch2 en branch1

git checkout branch1
git merge branch2

Enviar un branch local al servidor remoto

git push origin branc

Mostrar branches locales

git branch

Borrar branch remoto

git push origin --delete branchname

Borrar branch local

git branch -D the_local_branch

jueves, 6 de marzo de 2014

JMeter: Primeros pasos probando rendimiento de aplicaciones web

Una gran herramienta en la caja de herramientas de todo buen desarrollador de software, es aquella que te permite evaluar el rendimiento de una aplicación. En el caso de aplicaciones web es extremadamente necesario hacer estas pruebas de rendimiento simulando una alta concurrencia de usuarios  debido a la naturaleza concurrente de la web.

Una gran herramienta open source para realizar este tipo de pruebas se llama JMeter de Apache. Con ella puedo crear múltiples solicitudes a una dirección web y medir la respuesta para examinar el compartamiento en términos de rendimiento.


Apache JMeter

Pasos para crear un plan de pruebas sencillo:


  1. Descargar JMeter del sitio web oficial de Apache. En Ubuntu se puede instalar usando el comando: apt-get install jmeter
  2. Agregue un Thread Group al Test Plan: Clic derecho en el test plan ->Add->Threads (Users)->Thread Group
  3. Edite los campos del Thread Group como el número de usuarios y la cantidad de ciclos, entre otros.
  4. Agregamos un HTTP Request: Clic derecho en el Thread Group->Add->Sampler->HTTP Request
  5. Editamos los campos requeridos de acuerdo al tipo de request
  6. Agregamos un listener de acuerdo al tipo de reporte que desemos: Clic derecho en Test Plan->Add->Listener->Graph Results
  7. Damos Start y observamos nuestro gráfico crecer
  8. Interpretamos los resultados y/o ajustamos el plan para obtener la información que requerimos

miércoles, 12 de febrero de 2014

Tridion y sus bloques de construcción



Siempre es bueno guardar conceptos claves de las tecnologías que uno ha usado en el pasado. El aprender a reconocer debilidades y  fortalezas de una tecnología es vital para desarrollar un criterio ingenieril o arquitectural que nos ayuda a tomar mejores decisiones técnicas.

Hace un tiempo trabajé con un administrador de contenido propietario llamado Tridion de SDL. Sinceramente no me agradó mucho por algunas razones que no vienen al caso mencionar ahora, pero hubieron varios conceptos que me agradaron y que comentaré brevemente en algunas entradas de blog.

Unos de los conceptos que me llamó la atención es la manera muy clara en que separan el contenido de la presentación, y como lo hacen de una manera escalonada por medio de sus "bloques de construcción". Esta separación es sumamente importante en un buen administrador de contenido o CMS (Content Management System). Es altamente deseable que el contenido en un sistema de contenido se pueda preservar mientras su presentación evoluciona con el tiempo adaptando las nuevas tendencias de presentación web.

Esta facilidad permite también una excelente separación de roles donde tenemos editores de contenido que no se preocupan porque el contenido luzca agradable, y por otra parte los diseñadores web que maquillan el sitio web acorde a las tendencias de moda.

En organizaciones muy grandes, esta característica permite además imponer una serie de formatos, y/o plantillas para mantener uniformidad en sitios (o gama de sitios) web grandes y complejos donde muchas personas editan contenido.

La manera en que lo hace Tridion es definiendo los siguientes bloques de construcción de páginas web.

Los esquemas (schemas) definen los metadatos de un componente como lo son los nombres de los campos, sus tipos y si son mandatorios o no. En el ejemplo graficado abajo se muestra un esquema de comida con campos como título y subtítulo de tipo texto, y imagen de tipo imagen.

Luego un componente (component) es como la instancia de un esquema. Es decir, llenar los campos de un esquema con valores específicos. En el ejemplo se llena el esquema de comida con datos de una pizza.

La plantilla del componente (component template) viene a definir la disposición y estilos básicos de los distintos campos del componente. Un componente podría disponer de diferentes plantillas de acuerdo a las distintas necesidades de presentación. Por ejemplo, en el gráfico se muestra una alineación hacia la derecha de la imagen de la comida con el título y subtítulo encabezando a la izquierda, seguidamente del cuerpo del texto. Uno podría disponer otra plantilla que quizás se utilice para resultados de búsquedas donde la imagen se omite y solo se muestra el título con el texto de la descripción de la comida truncado.

La plantilla de la página (page template) establece los elementos globales de una plantilla web particula. Típicos casos de menús de navegación, encabezados, pies de página, etc.

La presentación del componente (component presentation) es la unión de un componente particular con una plantilla de componente. El resultado final es la presentación del contenido del componente en su forma agradable para el usuario.

Finalmente cuando se une la plantilla de la página con uno o más componentes de presentación tenemos finalmente una página web (web page).


Sin duda esta separación de contenido y presentación implica mucho trabajo al inicio con la definición de esquemas, plantillas y componentes, pero la retribución final es satisfactoria al explotar la gran flexibilidad que se alcanza con este modelo.