Archivos del sitio software

Hudson. Eligiendo nuestro entorno de Integración Continua (IV).

Posteado por Félix García Borrego en November 5th, 2008

Nos encontramos ante un software relativamente novedoso, pero que se ha convertido en uno de los referentes en cuanto a sistemas de Integración Continua. Es una herramientas software libre desarrollada en Java y mantenida por Sun Microsystems desde su web java.net. La herramienta puede ser descargada desde https://hudson.dev.java.net/.

  • Instalación

La instalación de Hudson es extremadamente sencilla, pudiéndose realizar una evaluación del software utilizando un instalador Java Web Start desde la web del producto. Así mismo, se puede descargar e instalar la aplicación de forma standalone, o se puede desplegar sobre un servidor de aplicaciones mediante el fichero empaquetado hudson.war.

El sistema está pensado para que nunca sea necesario editar ningún fichero de configuración externo, ofreciéndonos una administración web sencilla pero que contempla una configuración visual integral (incluyendo por ejemplo la parametrización de SMTP, base de datos, seguridad, etc.).

La documentación de instalación oficial del producto es buena, e incluye incluso algunos vídeos screencasts. Por otro lado, si en algún momento nos sentimos confundidos con la configuración, el sistema ofrece una completa ayuda en linea y contextual que facilita mucho la tarea de configuración para personas no familiarizadas a priori con este tipo de sistemas.

  • Administración, gestión de proyectos

La herramienta ofrece una interfaz muy intuitiva para su administración, por lo que como hemos comentado antes, no será necesario personal especializado para su administración, pudiéndose realizar todas las tareas desde la propia consola web.

La herramienta permite la definición de tareas periódicas desde su interfaz web mediante un editor similar a cron dotado de una completa ayuda contextual.

Por otro lado, durante las pruebas, la migración de los proyectos a Hudson ha resultado ser muy rápida y sencilla, consiguiendo un entorno totalmente configurado y funcional en poco tiempo.

Respecto a su mecanismo de actualización, Hudson es el mejor de los sistemas analizados, ya que sólo es necesario descargar el nuevo empaquetado .war y sustituir el existente, asegurándose la plataforma de mantener la compatibilidad de forma automática. Por otro lado, es el propio Hudson el que nos avisará de la existencia de nuevas versiones, tanto del sistema completo como de sus plugins.

  • Seguridad

El sistema ofrece un sistema de seguridad completo y muy flexible, y totalmente configurable desde la consola web, permitiéndonos o bien integrarnos con sistemas externos de autenticación (LDAP, bases de datos externas) o delegar la seguridad en el propio Hudson.

Si optamos por que Hudson gestione la seguridad, dispondremos de múltiples opciones que cubren todo el abanico de necesidades, como seguridad basada en perfiles, asociación de permisos por proyectos o por matriz de acciones.

  • Integración con sistemas externos

Hudson ofrece un mecanismo de extensión muy completo, que junto con el gran número de plugins ya existentes le permiten su integración con un gran número de sistemas y herramientas. Por otro lado, aunque está preparado (al igual que Continuum o LuntBuild) para utilizar directamente los plugins Maven, proporciona los mecanismos adecuados para no depender de una correcta configuración de estos plugins en el fichero pom.xml de los proyectos. Esta centralización de la configuración constituye una ventaja muy importante respecto a sus competidores, ya que garantiza que, independientemente de lo contenido en el pom.xml, se puedan ejecutar los procesos de chequeo y validación deseados.

Por otro lado, existe una integración plena entre Hudson y sus plugins. Los resultados de éstos podrán ser visualizados en la herramienta web, incluyendo tanto conclusiones de testeo, estilos, pruebas unitarias, etc… como los resultados de los procesos de despliegue. Nuevamente Hudson es la única plataforma en permitir este tipo de funcionalidad avanzada.

Por otro lado, permite la integración con la mayoría de sistemas de control de versiones (SVN, CVS, etc.), ya sea de base, o mediante la inclusión de los plugins necesarios.

Es de especial interés el mecanismo de instalación y gestión de plugins, ya que la herramienta nos permite la descarga e instalación automática desde su interfaz web, avisándonos incluso de la aparición de nuevas versiones de los mismos de forma automática.

Otro factor muy importante es la completa documentación para poder desarrollar nuestros propios plugins, que nos permitirán adaptar el sistema a las particularidades propias de cada entorno.

También resulta curiosa la integración con sistemas como Twitter, Jabber, etc., que nos permiten hacernos una idea del avanzadísimo nivel de los mecanismos de integración incorporados en la plataforma. Sin duda, esta es la característica en la que más se destaca Hudson frente a Continuum o LuntBuild.

  • Tipos de proyectos

Aunque la herramienta esta principalmente enfocada a proyectos Java, gracias sus plugins tiene soporte para gran multitud de formatos como por ejemplo Ivy, Nant, Rake, Ant, Maven, Phing, Shell scripts, y para lenguajes como .Net, Groovy, Rails, PHP.

  • Facilidad de uso

La herramienta ofrece una interfaz potente y muy usable, que permite que personal no cualificado o con poca experiencia en este tipo de herramientas se adapte a su uso con facilidad.

La documentación oficial es completa, y junto con la ayuda contextual en todos los elementos de la interfaz hace que la curva de aprendizaje sea muy rápida.

  • Estabilidad

Nos encontramos ante un software muy estable, al igual que ocurría con sus dos competidores directos. Prueba de ello es que está siendo utilizado para todos sus proyectos en grupos de desarrollo como JBoss. Como sistema de Integración Continua, tiene una política de publicación de actualizaciones muy dinámica que hace que se liberen versiones cada pocas semanas, lo cual podría ser un inconveniente de no ser por las posibilidades de actualización automática comentadas. A continuación se indican las principales versiones liberadas:

En lo referido al rendimiento, el sistema permite la gestión de hilos de ejecución dedicados a tareas de compilación y la ejecución de compilación distribuidas, lo que le confiere excelentes características de escalabilidad y adaptabilidad al entorno disponible.

Hudson 1.256

Julio 2008

Hudson 2.00

Marzo 2008

Hudson 1.100

Abril 2007

  • Conclusiones sobre Hudson

La herramienta, gracias a su sistemas de plugins, ha resultado ser muy versátil y fácilmente adaptable a necesidades particulares. Por otro lado, su sencilla interfaz la hacen ideal para su uso por personal no especializado en este tipo de herramientas.

Aunque la herramienta es la más joven de las estudiadas, está teniendo una rápida aceptación y divulgación en el mercado, y ha demostrado completamente su fiabilidad.

Próximamente: Conclusiones finales. Eligiendo nuestro entorno de Integración Continua (V).

Formul@ 2.0

Posteado por Javier Echeverría Usua en October 20th, 2008

Formul@ (léase Formula) es un software desarrollado por VIAVANSI (cuyo desarrollo finalizó en 2007), que permite diseñar visualmente (mediante una interfaz Ajax con funcionalidades de drag&drop) formularios dinámicos que posteriormente pueden ser utilizados remotamente por otras aplicaciones. Ello es debido a que la necesidad de gestión visual de “dynamic forms” es cada vez más común y recurrente en multitud de proyectos. ¿En cuántos sistemas de información existe el requisito de disponer de formularios de entrada de datos, y cuánto esfuerzo de desarrollo y mantenimiento evolutivo implica?

Nuestra idea consistió en desarrollar un componente específico especializado que se responsabilizase de esta tarea dentro de una arquitectura de servicios, del mismo modo que se usa un servidor de base de datos para persistir información o se usa un servidor SMTP para enviar un email.

Básicamente y a grandes rasgos, Formul@ se encarga de las siguientes tareas:

  • Definición visual de formularios complejos.
  • Almacenamiento de la definición en un metamodelo XML.
  • Rendeo de los formularios bajo demanda de aplicaciones cliente. Nótese que al basarse en una definición modelada en XML, del mismo modo que un formulario se rendea en web, podría rendearse en una aplicación de escritorio, en un teléfono móvil, etc… Un sólo trabajo de definición, múltiples salidas para el formulario.

Te invitamos a que pruebes la demo del diseñador de formularios Formul@.

A nivel técnico Formul@, que inicialmente surgió como desarrollo interno de I+D, hace uso de las últimas tecnologías disponibles en el mundo Java como son Java Server Faces (JSF), Java Persistent Api (JPA, Ajax, Maven, Web services usando JSR 181, XSL-FO, etc.

A nivel funcional, si probáis la demo del diseñador podréis observar que pueden crear varias páginas, dentro de las páginas bloques de varios tipos, dentro de éstos contenedores para maquetar, dentro de los contenedores campos de diversos tipos… Y luego las aplicaciones cliente pueden usar y controlar el comportamiento de los formularios a través de un API.

Formul@ ha sido desarrollada para la Junta de Andalucía, por lo que está liberada como software libre dentro del Repositorio de Software Libre de la Junta de Andalucía.

Actualmente estamos trabajando para la Junta con el objetivo de incluir muchas mejoras en el motor. ¡Pon Formul@ en tu vida!

PD: Formul@ no sólo se ha utilizado en varios proyectos de desarrollo de VIAVANSI, como no podría ser de otra forma… por ejemplo, otras empresas (como nuestros colegas de Guadaltel, ahí va una referencia gratuita en agradecimiento por el paintball) lo han utilizado (dentro del ámbito local andaluz) como motor visual de formularios dinámicos en la Oficina Virtual del Ayuntamiento de Córdoba, en el sistema de Comunicaciones Internas eCO de la Junta de Andalucía, en el ambicioso Sistema de Gestión Global del Gasto (G3) de la Junta de Andalucía, etc.

Apache Continuum. Eligiendo nuestro entorno de Integración Continua (II).

Posteado por Félix García Borrego en October 16th, 2008

Apache Continuum

Continuum es una potente herramienta de Integración Continua desarrollada por Apache; su descarga está accesible en la URL: http://continuum.apache.org/download.html

  • Instalación

La instalación de Continuum Server es sencilla; para una instalación básica basta con descargar el paquete de instalación apropiado de la web de Continuum, descomprimir el paquete en el directorio destino escogido y configurar las conexiones a base de datos a utilizar. Una vez instalado, para su ejecución solo se requiere lanzar uno de los scripts incluidos en el directorio bin.

Como hemos podido comprobar, la configuración básica es realmente sencilla, pero en la mayoría de los casos necesitaremos configurar conexiones a bases de datos, sistemas de correo, gestión de permisos avanzada, etc., además de desplegar Continuum sobre un servidor de aplicaciones. Para este tipo de configuraciones deberemos modificar los ficheros de configuración basados en xml o properties según el caso.

En términos generales la documentación del producto es buena, si bien resulta algo pobre. Esto suele ser tradicional en la mayoría de los proyectos del grupo Apache; existen algunos apartados con documentación muy completa, pero quedando otros aspectos de la documentación por terminar.

En Continuum nos enfrentamos a una curva de aprendizaje relativamente lenta para personal no especializado, debido a algunas configuraciones no documentadas y multitud de conceptos que hay que saber manejar desde el principio. Por ejemplo, se suele requerir adaptar el fichero continuum/conf/application.conf, o los ficheros pom.xml de los proyectos Maven de forma acorde a lo que espera Continuum.

  • Administración, gestión de proyectos

Con esta herramienta muchas de las tareas administrativas podrán ser realizadas mediante la consola web. Aunque otras  tareas avanzadas requieran la modificación de ficheros de configuración.

La herramienta permite la definición de tareas periódicas desde su interfaz web de una forma sencilla, pudiendo automatizar tareas. Si bien la configuración de estas operaciones es sencilla, la documentación oficial al respecto es nula.

Respecto a las gestión de copias de seguridad, sólo se contempla un backup basado en un cliente xml-rpc, no existiendo documentación asociada a este cliente. Por otro lado, la opción alternativa se basa en realizar copias externas de la base de datos y los ficheros de trabajo, en función del tipo de instalación y base de datos utilizada.

Se puede destacar que no existe documentación en linea mientras se utiliza la herramienta. Ello, unido a la escasa documentación, provocó que durante nuestra evaluación tardásemos más tiempo del esperado en configurar nuestras primeros proyectos Maven sobre Continuum.

Continuum es un software en constante crecimiento, el cual ha mejorado mucho en las últimas versiones. Sin embargo, la actualización a nuevas versiones no resulta siempre directa; en la mayoría de los casos resulta necesario ejecutar alguna herramienta de migración para actualizar desde versiones anteriores.

  • Seguridad

El sistema dispone de un mecanismo de seguridad muy completo, basado en usuarios, roles, y permisos sobre operaciones o proyectos, permitiéndonos la definición de una matriz completa de permisos. Sólo necesitaremos modificar el fichero de configuración security.properties cuando estemos realizando configuraciones avanzadas.

  • Integración con sistemas externos

Apache Continuum no ofrece mecanismos de extensión o plugins, limitándose a permitirnos la llamada a plugins Maven desde los comandos de compilación asociados a los proyectos. Esto hace que dependa de la correcta configuración de plugins Maven report y build en los ficheros pom.xml de los proyectos gestionados.

Por este motivo, si requerimos que Continuum ejecute procesos de testeo, bugtrackers, validación de reglas de estilo, etc., necesitaremos definir éstos en el fichero pom.xml del proyecto. Sin embargo, no obtendremos una integración completa entre Continuum y los plugins Maven utilizados (Continuum lanza los procesos, pero no integra sus respuestas para plasmar los resultados en pantalla). Del mismo modo, la integración con el sistema de control de versiones dependerá de la correcta configuración del plugin SCM en el fichero pom.xml del proyecto gestionado.

Otro aspecto que se echa de menos es un mecanismo para despliegue de aplicaciones y librerías que sea independiente de la definición de estos mecanismos en Maven. Nuevamente se exige una correcta configuración de estos aspectos en el pom.xml del proyecto.

En general, esta parece una debilidad grave de Continuum, ya que depende en exceso de que los ficheros pom.xml estén perfectamente configurados, y por ello la realización de procesos de verificación es dependiente de la buena voluntad del desarrollador, no de las personas responsables de estas tareas (como gente de Desarrollo o de Calidad).

  • Tipos de proyectos soportados

Apache Continuum está especialmente enfocado a proyectos Maven, si bien también ofrece soporte a proyectos con scripts Ant y otro tipo de proyectos sin formato basados en scripts de compilación. Aunque las limitaciones se podrían solventar mediante proyectos shell, se echa en falta la integración con otros lenguajes o mecanismos como ivy, rake, etc.

  • Facilidad de uso

Nos encontramos ante una herramienta con una potente interfaz web, que utiliza un conjunto de iconos preestablecidos para indicar los estados y acciones disponibles, ofreciéndonos a su vez una leyenda para su fácil interpretación.

El único apartado negativo es que no aporta ayuda en línea sobre los diversos conceptos y elementos de la interfaz, por lo que es necesario un mínimo conocimiento previo de los conceptos tratados.

Respecto a la documentación oficial, ofrece una documentación muy escueta con multitud de apartados tan sólo esbozados, siendo por ello recomendable recurrir a artículos externos o libros especializados.

  • Estabilidad 

Estamos ante un software estable y fiable como la mayoría del software desarrollado por el grupo Apache. A continuación se detallan las últimas versiones liberadas de la plataforma:

Apache Continuum 1.2

Septiembre 2008

Apache Continuum 1.1

Noviembre 2007

Apache Continuum 1.0

Octubre 2005

Una buena prueba de estabilidad del software es que está siendo utilizado internamente por varios de los proyectos gestionados por la propia Apache.

Respecto al rendimiento, el principal defecto es que no dispone de gestión de hilos de compilación, ni de mecanismos para la compilación distribuida, aunque es posible ver el listado de tareas pendientes y detenerlas si se desea. La ausencia de aquellas opciones hace que en ocasiones se puedan causar picos de caída de rendimiento, o falta de adaptación a las prestaciones de estaciones multiprocesador.

  •  Conclusiones finales sobre Continuum

Apache Continuum es aún un producto relativamente joven con mucho espacio para crecer y mejorar. Ha avanzado en buena medida desde sus primeras versiones, las cuales no alcanzaban el nivel de calidad mínimo exigido a este tipo de soluciones. Sin embargo, las nuevas funcionalidades que han ido apareciendo en las últimas versiones, unido a su intuitiva consola de administración, lo hacen una buena herramienta y una opción seria para implementar una infraestructura de desarrollo basada en esta plataforma de Integración Continua.

Los principales puntos negativos encontrados han sido la falta de algunas funcionalidades típicas disponibles en otras soluciones de Integración Continua, donde destaca sin duda la inexistencia de un mecanismo de extensión de funcionalidad que permita la inyección de plugins. Continuum se basa al 100% en la configuración previa establecida en el pom.xml (reporting, checkstyle, scm, etc.), exigiendo así que la definición del proyectos sea completa para su correcto funcionamiento. Por decirlo de una forma reducida, ello implica que todos y cada uno de los proyectos deben disponer de la misma configuración, y si se desea ampliar una funcionalidad, ello implica la modificación del fichero pom.xml de todos los proyectos. Sin duda, Continuum adolece de una gestión centralizada de extensiones que permitiese configurar este tipo de funcionalidades a nivel plataforma, no a nivel proyecto.

  • Comentario personal

Apache Continuum resultó un software genial durante el tiempo que estuvimos utilizándolo en los proyectos internos del departamento de I+D, pero causó demasiados problemas cuando comenzamos la migración de todos nuestros proyectos de desarrollo a un entorno de integración continua. Hay que aclarar que la mayoría de los problemas que encontramos no son directamente achacables a Continuum, sino a la poca experiencia con este tipo de soluciones del grupo de desarrolladores y a las exigencias que se imponían sobre proyectos que, por falta de tiempo, nunca eran configurados al 100%. Finalmente lo descartamos eligiendo una solución más sencilla en su manejo y con menos exigencias respecto a la configuración completa de los proyectos gestionados.

Continuación: LuntBuild. Eligiendo nuestro entorno de Integración Continua (III).

Eligiendo nuestro entorno de Integración Continua (I).

Posteado por Félix García Borrego en October 8th, 2008

Objetivos

El objeto de este artículo es en plasmar la metodología y conclusiones obtenidas en una comparativa técnica que hemos realizado sobre algunas de las herramientas de integración  continua disponibles en el mercado. Para ello se establecen unas bases para la elección de la plataforma y se realiza una comparativa completa partiendo de una selección de herramientas.

Existe un buen número de herramientas de Integración Continua en el mercado: Continuum, CruiseControl, LuntBuild, Hudson, Atlassian Bamboo, etc… Para facilitar el estudio se ha realizado una primera preselección consistente en las herramientas estrictamente Open Source más utilizadas en el mercado: Apache Continuum, LuntBuild y Hudson.

Antes de entrar en detalles, comentaremos cúales son los principales objetivos funcionales que se buscan a la hora de implantar un sistema de Integración Continua:

  • Reducción del tiempo de integración. Se trata de agilizar el proceso de integración de los diversos proyectos y aplicaciones, buscando un sistema que se responsabilice de automatizar la compilación, ejecución de tests y despliegues, así como de avisar de posibles problemas a los diversos participantes en el desarrollo de un proyecto.
  • Reducción de errores. Uno de los objetivos más importantes que se persiguen con este tipo de sistemas es la detección de errores y conflictos en un estado temprano.
  • Testeo de la calidad de código y reglas de estilo. Para asegurar un mínimo de coherencia de los nuevos desarrollos con las políticas de calidad establecidas, se busca un sistema capaz de automatizar este tipo de tareas de manera sencilla.
  • Reducción del riesgo. Permitiendo que versiones tempranas del producto estén disponibles lo antes posible, con un número de incidencias minimizado de forma automática, y con una gestión de la configuración automática que reduce errores en despliegues.
  • Disponibilidad continua de la última versión del código para pruebas, agilizando los procesos de despliegue de nuevas versiones en los diferentes entornos.

Metodología del análisis

Para seleccionar el sistema de Integración Continua más adecuado, hemos procedido a analizar las diversas características funcionales y técnicas de interés. Para ello se ha procedido a instalar las tres plataformas objeto del estudio (Continuum, LuntBuild y Hudson) y se ha puesto en marcha al menos un proyecto Maven sobre ellas, tratando de evaluar una serie de variables de interés.

A continuación se indican los criterios de selección utilizados en la comparativa:

  • Instalación.

Evaluaremos la facilidad de instalación y configuración de las herramientas, con parámetros como la documentación oficial de instalación, posibilidades de configuraciones avanzadas, dificultad de la instalación, etc.

  • Administración, gestión de proyectos.

Partiendo del hecho de que el entorno en el que se va a realizar la implantación no tiene por qué contar con personal especializado y dedicado exclusivamente a la gestión y administración de la plataforma, será recomendable que las tareas de administración asociadas al sistema elegido sean las mínimas, y que su ejecución sea lo más sencilla posible. Se analizarán parámetros como la documentación oficial destinada a esta temática o si el sistema permite una fácil generación y restauración de copias de seguridad (tanto de la definición de los proyectos y tareas configuradas como del histórico de compilaciones). También se estudiará si las tareas de administración relacionadas con la plataforma se puedan realizar mediante la interfaz Web. Así mismo, verificaremos si se permite recuperar el historial de las últimas tareas de compilación realizadas, así como poder configurar el número de días y compilaciones que se mantendrán en el historial. Con respecto a la gestión de tareas periódicas, comprobaremos si el sistema permite la definición de tareas periódicas, para facilitar la automatización de tareas repetitivas. Además, teniendo en cuenta que este tipo de herramientas están en continua evolución, se evaluará la facilidad de instalación de nuevas actualizaciones. Por último se estudiará el rendimiento de la solución. Dado que las compilaciones son tareas muy pesadas, se evaluarán los diferentes mecanismos que aporta cada sistema de Integración Continua para la gestión de hilos de compilación y la ejecución distribuida de tareas.

  • Seguridad.

Se evaluará la versatilidad y potencia en la gestión de roles, perfiles y permisos asociados a proyectos y acciones disponibles en la herramienta. Resulta interesante además poder definir perfiles de usuario específicos. Así mismo, se estudiará la posibilidad de definición de permisos especiales para proyectos concretos. Por último evaluaremos la complejidad a la hora de establecer una política avanzada de permisos, observando el nivel de personalización que permite la plataforma.

  • Integración con sistemas externos.

En la mayoría de los casos es necesario que la herramienta de Integración Continua interactúe con otros sistemas específicos, por lo que puede ser necesario el desarrollo de nuevos plugins que extiendan la funcionalidad de la plataforma. Por este motivo evaluaremos la sencillez y los mecanismos que ofrecen estos sistemas a la hora de inyectar funcionalidad personalizada.

Evaluaremos también el nivel de integración que tienen las diferentes herramientas de Integración Continua con sistemas de control de versiones, así como el nivel de integración con herramientas de evaluación de código (como checkstyle, PMD, etc…). Analizaremos además el nivel de integración con sistemas de gestión de incidencias, particularizando en el sistema Mantis BT. Por último evaluaremos el nivel de integración de soluciones con sistemas de test como Junit o JMeter .

  • Tipos de Proyectos soportados.

Evaluaremos los diferentes tipos de proyectos soportados, así como sus posibilidades de extensión para futuros modelos. Aunque haremos especial hincapié en el soporte completo de proyectos basados en Maven2, si bien también es relevante que el sistema permita la gestión del mayor número posible de formatos.

  • Facilidad de uso.

Ya que la plataforma de Integración Continua elegida deberá convertirse en una pieza central de nuestro entorno de software, la herramienta deberá ofrecer una interfaz sencilla, usable e intuitiva, de forma que se facilite la interacción con la herramienta por personal no especializado, sin problemas serios de aprendizaje. Haremos especial hincapié en las ayudas en línea disponibles y en la organización de la interfaz.

  • Documentación de usuario.

Evaluaremos la cantidad y calidad de la documentación de usuario disponible.

  • Estabilidad.

La herramienta elegida deberá disponer de unas excelentes características de estabilidad. El objetivo no es elegir la última tecnología relacionada con la Integración Continua, sino disponer de un entorno funcional operativo lo más robusto posible.

Próximamente:
Apache Continuum. Eligiendo nuestro entorno de Integración Continua (II).

Hudson. Parte 1 - Introducción.

Posteado por Félix García Borrego en September 17th, 2008

¿Qué problemática resuelve?

En entornos en los que el desarrollo de software se realiza por un equipo o equipos en los que la evolución y mantenimiento del código se subdivide,  el coste de la integración entre las diferentes piezas de software tiende a aumentar, apareciendo conflictos y haciendo de la generación de distribuibles una ardua tarea.  Con idea de rebajar los costes adicionales provocados por la gestión del proceso de compilación, integración, empaquetado y generación de entregarles, aparecen herramientas de Integración Continua (CI) como Hudson.

¿ Por qué elegir Hudson?

Aunque es un productor reciente ha evolucionado rápidamente y actualmente es uno de los productos de referencia en el sector de las aplicaciones para Integración Continua de software, gracias a la simplicidad de su interfaz y lo sencillo que resulta el desarrollo de nuevos plugins. Prueba de este crecimiento es que actualmente es utilizado por un gran numero de proyectos entre los que se encuentra por ejemplo JBoss.

Para hacernos una idea los principales motivos que en nuestro caso nos hicieron elegir Hudson son:

  • Fácil instalación y uso. Como buen producto cuya utilidad es la de simplificarnos la vida, la instalación y ejecución de Hudson es realmente trivial. Es suficiente con descargar el  fichero hudson.war y ejecutarlo con “java -jar hudson.war” o bien desplegarlo en un servidor de aplicaciones.  Y esto no queda aquí, gracias a su sencilla interfaz, podemos tener nuestros primeros proyectos configurados en pocos minutos.
  • Un sistema de plugins fácilmente extensible. Lo que permite la instalación y creación de nuevos plugins de forma sencilla. Esto ha permitido que exista una gran cantidad de plugins disponibles y que sea muy sencilla la creación de plugins específicos. Como ejemplo, gracias a esta simplicidad pudimos crear un plugin específico para adaptar el comportamiento de Hudson a nuestras necesidades en solo unos días.
  • Un soporte completo de Maven, lo que nos ha permitido una migración rápida de todos nuestros proyectos al nuevo sistema.
  • Soporte para compilación distribuida basada en sistemas esclavos y maestros, para mejorar los tiempos de compilación y evitar la sobrecarga.
  • Soporte para múltiples equipos y grupos de proyectos, lo que nos permite la colaboración.
  • Es un Sistema completamente Software Libre.
  • Nos permite establecer un sistema de alertas a los desarrolladores sobre el estado de sus proyectos.
  • Permite la detección de actualizaciones realizadas en el SCM ( en nuestro caso Subversion) para generar de forma automática los nuevos empaquetados o a intervalos regulares.
  • Y el principal motivo. Tras estar utilizándolo en el departamento de I+D durante unos meses, el software no nos dio ni un solo problema, por lo que actualmente la mayoría de nuestros proyectos están ya bajo el control de Hudson.

Listado de proyectos gestionados por Hudson en Viavansi

Instalación

Como se comenta arriba, la instalación del software es realmente sencilla, y el único requisito es tener instalada una versión de Java reciente y opcionalmente un servidor de aplicaciones como por ejemplo Tomcat, si no se desea ejecutar sobre el servidor que trae embebido.

Para la instalación, en primer lugar necesitara descargar la última versión estable de  http://hudson.dev.java.net.

Si desea ejecutar Hudson en modo autónomo sera suficiente con ejecutar “java -jar hudson.war”y acceder con el navegador al puerto 8080 (http://localhost:8080) para poder utilizar Hudson.  Si lo desea, en la web oficial tambien puede encontrar los scripts para convertir hudson en un servicio.

Por otro lado la instalación más común de Hudson es su despliegue en un servidor de aplicaciones. Por ejemplo, para su despliegue en un Tomcat, bastara con copiar el fichero hudson.war dentro del directorio webapps.

Hudson utiliza un directorio especial para almacenar toda la configuración propia y de los proyectos que gestiona, por lo que no hay peligro de perdida de datos si posteriormente actualizamos a versiones más recientes del software. Por defecto el directorio es “.hudson”, localizado en el home del usuario, pero  es posible modificar este directorio estableciendo la variable de entorno HUDSON_HOME.

Primeros pasos

En Hudson cada proyecto de desarrollo es una tarea, por lo que para hacer que un proyecto este gestionado por hudson es suficiente con darle un nombre a la tarea y asignarle un tipo entre los disponibles (Build a maven2 project, Build a free-style software project, …)

Paso 1. Crear Un nuero proyecto (Job) en Hudson

En adelante a modo de ejemplo vamos a considerar un proyecto de tipo Maven 2. Una vez que tenemos el tipo de proyecto seleccionado, pasamos a la pantalla de configuración, en la que entre otras muchas opciones, tendremos que seleccionar el SCM en el que se encuentra proyecto(en nuestro caso Subversión), el pom.xml asociado al proyecto y el conjunto de goals que deseamos ejecutar. No entraremos en detalle a explicar cada uno de las opciones de configuración, ya que otra de las ventajas de Hudson es que ofrece ayuda en linea para todas sus opciones.

Una vez guardada la nueva tarea, ésta podrá ser ejecutada automáticamente si hemos configurado algún Build Triggers o lanzada de forma manual pulsando sobre Build Now, y una vez que la tarea esta en ejecución podremos ver en todo momento su estado y consola.

Administración

Desde el menú “Manage Hudson”, situado en la página principal, es posible acceder a todas las opciones de configuración. En particular desde la opción “Configure System” podremos acceder a todos los parametros generales como configuración del  SMTP, proxy, rutas a Maven, Ant, …
Y de nuevo para cada opción de configuración dispondremos de ayuda contextual que nos hara la vida mucho más facil.

Como ya hemos comentado, uno de los puntos fuertes de Hudson es su sistema y manejador de plugins, al que podremos  acceder desde la opción “Manage Plugins”. Esta opción nos permitirá añadir nuevas características (como herramientas de control de estilo, nuevos SCM soportados, …) directamente desde su interfaz.

Consola de administración de Hudson

La lista de todos los plugins está disponible en la siguiente dirección:  http://hudson.gotdns.com/wiki/display/HUDSON/Plugins

Conclusión

Hudson es un es un fantastico software para realizar las tareas de Integración Continua, y aunque aquí se han presentado solo las características básicas, a pesar de la simplicidad de su interfaz es un software altamente extensible y con un gran potencial.

Por otro lado, y aunque se enfoca principalmente hacia proyectos Java, Hudson permite gestionar proyectos de cualquier tipo, como por ejemplo proyectos C o Ruby on Rails, lo que lo hace muy recomendable enentorno heterogéneos.

En general, los productos de Integración Continua suelen ser complejos de manejar y gestionar, y como hemos visto, este no es el caso de Hudson, lo que resulta esencial si queremos convertir esta herramienta en una plataforma horizontal en nuestra empresa o grupo de desarrollo. Su facilidad de uso la ha demostrado durante el tiempo que llevamos utilizándolo, ya que no solo no ha requerido de personal especializado en este tipo de tareas para su gestión, sino que tampoco ha necesitado de una compleja explicación para que nuestros grupos de desarrollo empezaran a utilizarlo.

En resumen una herramienta para simplificarnos la vida a los desarrolladores que ofrece lo que promete.

Próximamente: Hudson.  Parde 2. Crea tus propios plugins

Arroz con Mango: Seam + Logger & Finder Interceptor + Lucene…

Posteado por Guido Medina en September 5th, 2008

Bueno, tuve unas necesidades en un proyecto, así que comencé por hacer un GenericDAO, luego le agregué un FinderInterceptor el cual permite que cuando hagas findByWhatever te busque un NamedQuery que esté definido en la Entidad de JPA, como tip le agregué un logger el cual loguea cada método conjunto con los parámetros pasados, aqui comienzo a explicar uno por uno:

GenericDAO; interfase que define el contrato del JPA DAO el cual implementa de forma genérica las funcionalidades del mismo; esta interfase está interceptada por un Finder del cual hablaremos más tarde; tuve que usar Lucene ya que el proyecto corre sobre MSSQL Server y el bendito no soporta translate:


package com.viavansi.fdu.persistencia.DAO;
import java.io.Serializable;
import java.util.List;

import org.apache.lucene.queryParser.ParseException;

import com.viavansi.framework.core.persistencia.servicios.excepciones.ExcepcionPersistencia;/**
 * Interface for data access objects.
 *
 * <p>
 * Generic Interface DAO which provides the basic contracted operations for
 * every DAO; an implementation is also provided.
 *
 * @param <T>
 * The persistent class.
 * @param <PK>
 * The class of the primary key of the persistent class.
 */
@FinderExecutor
public interface GenericDao<T, PK extends Serializable> { /**
  * Merge.
  *
  * @param persistentObject
  */
 void update(T persistentObject) throws ExcepcionPersistencia; /**
  * Make the instance persistent.
  *
  * @throws ExcepcionPersistencia
  */
 void create(T newInstance) throws ExcepcionPersistencia; /**
  * Make the object transient.
  *
  * @param persistentObject
  * @throws ExcepcionPersistencia
  */
 void delete(T persistentObject) throws ExcepcionPersistencia; /**
  * Returns a persistent object specified by its key.
  *
  * @throws ExcepcionPersistencia
  */
 T read(PK id) throws ExcepcionPersistencia; /**
  * Returns all persistent entities.
  */
 List<T> findAll() throws ExcepcionPersistencia; /**
  * Resolves and executes a finder. <p/>
  * <p>
  * This implementation uses the short name of the type class, appending a .
  * and the method name so the name of the query to look up becomes
  * Pet1.findByName if the method is findByName and the type Pet1. <p/>
  * <p>
  * An other implementation would be useful as well that does not return a
  * list but a single object.
  */
 List<T> executeFinder(String method, Object[] queryArguments)
  throws ExcepcionPersistencia; List<T> searchByText(String expresion) throws ExcepcionPersistencia,
  ParseException;

Ahora definimos el DAO que contiene injectado el EntityManager:


package com.viavansi.fdu.persistencia.DAO;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.jboss.seam.annotations.In;

import com.viavansi.framework.core.excepciones.CodigoError;
import com.viavansi.framework.core.persistencia.servicios.excepciones.ExcepcionDatosNoEncontrados;
import com.viavansi.framework.core.persistencia.servicios.excepciones.ExcepcionPersistencia;

/**
 * Generic data access object.
 *
 * @param <T>
 * The persistent class.
 * @param <PK>
 * The class of the primary key of the persistent class.
 */
public abstract class GenericJpaDaoFDU<T, PK extends Serializable> implements
  GenericDao<T, PK> {

protected Class<T> type;

@In("fduPersistenceContext")
 protected EntityManager entityManager;

public EntityManager getEntityManager() {
  return entityManager;
 }

public void setEntityManager(EntityManager entityManager) {
  this.entityManager = entityManager;
 }

public void create(T newInstance) throws ExcepcionPersistencia {
  try {
  this.entityManager.persist(newInstance);
  } catch (Exception e) {
  throw new ExcepcionPersistencia(CodigoError.ERROR_NO_DEFINIDO, e);
  }
 }

public void delete(T persistentObject) throws ExcepcionPersistencia {
  try {
  this.entityManager.remove(persistentObject);
  } catch (Exception e) {
  throw new ExcepcionPersistencia(CodigoError.ERROR_NO_DEFINIDO, e);
  }
 }

public T read(PK id) throws ExcepcionDatosNoEncontrados {
  T t = (T) this.entityManager.find(type, id);
  if (t == null) {
  throw new ExcepcionDatosNoEncontrados(
  CodigoError.ERROR_DATOS_NO_ENCONTRADOS,
  "Datos no encontrados");
  }
  return t;
 }

public void update(T transientObject) throws ExcepcionPersistencia {
  try {
  this.entityManager.merge(transientObject);
  } catch (Exception e) {
  throw new ExcepcionPersistencia(CodigoError.ERROR_NO_DEFINIDO, e);
  }
 }

@SuppressWarnings("unchecked")
 public List<T> findAll() throws ExcepcionPersistencia {
  try {
  return entityManager.createQuery(
  "select obj from " + this.type.getName() + " obj")
  .getResultList();
  } catch (Exception e) {
  throw new ExcepcionPersistencia(CodigoError.ERROR_NO_DEFINIDO, e);
  }
 }

/**
  * Resolves and executes a finder. <p/>
  * <p>
  * This implementation uses the short name of the type class, appending a .
  * and the method name so the name of the query to look up becomes
  * Pet1.findByName if the method is findByName and the type Pet1. <p/>
  * <p>
  * An other implementation would be useful as well that does not return a
  * list but a single object.
  *
  * @throws ExcepcionPersistencia
  */
 @SuppressWarnings( { "unchecked" })
 public List<T> executeFinder(String method, Object[] queryArguments)
  throws ExcepcionPersistencia {
  try {
  String queryName = queryNameFromMethod(method);
  Query query = entityManager.createNamedQuery(queryName);
  for (int i = 0; i < queryArguments.length; i++) {
  query.setParameter(i, queryArguments[i]);
  }
  return query.getResultList();
  } catch (Exception e) {
  throw new ExcepcionPersistencia(CodigoError.ERROR_NO_DEFINIDO, e);
  }
 }

/**
  * Resolves the name of the named query.
  *
  * @param finderMethod
  * "findPerson, etc."
  * @return
  */
 protected String queryNameFromMethod(String finderMethod) {
  return type.getSimpleName() + "." + finderMethod;
 }

/*
  * (non-Javadoc)
  *
  * @see
  * com.viavansi.fdu.persistencia.DAO.GenericDao#findWhere(java.lang.String)
  */
 @SuppressWarnings("unchecked")
 public List<T> searchByText(String expression)
  throws ExcepcionPersistencia, ParseException {
  PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance()
  .getPropertyUtils();
  StringBuilder builder = new StringBuilder();
  boolean firstField = true;
  for (PropertyDescriptor descriptor : propertyUtils
  .getPropertyDescriptors(type)) {
  if (firstField) {
  firstField = false;
  } else {
  builder.append(" OR ");
  }
  builder.append(descriptor.getName() + ":" + expression);
  }
  FullTextEntityManager fullTextEntityManager = Search
  .createFullTextEntityManager(entityManager);
  QueryParser parser = new QueryParser("id", new ISOLatin1Analyzer());
  org.apache.lucene.search.Query luceneQuery = parser.parse(builder
  .toString());
  Query query = fullTextEntityManager.createFullTextQuery(luceneQuery,
  type);
  List result = query.getResultList();
  if (result.size() == 0) {
  throw new ExcepcionDatosNoEncontrados();
  }
  return result;
 }

/**
  *
  * @param <T>
  * @param expression
  * @param entityManager
  * @param type
  * @return
  * @throws ExcepcionPersistencia
  * @throws ParseException
  */
 @SuppressWarnings("unchecked")
 public static <T> List<T> searchByText(String expression,
  EntityManager entityManager, Class<T> type)
  throws ExcepcionPersistencia, ParseException {
  PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance()
  .getPropertyUtils();
  StringBuilder builder = new StringBuilder();
  boolean firstField = true;
  for (PropertyDescriptor descriptor : propertyUtils
  .getPropertyDescriptors(type)) {
  if (firstField) {
  firstField = false;
  } else {
  builder.append(" OR ");
  }
  builder.append(descriptor.getName() + ":" + expression);
  }
  FullTextEntityManager fullTextEntityManager = Search
  .createFullTextEntityManager(entityManager);
  QueryParser parser = new QueryParser("id", new ISOLatin1Analyzer());
  org.apache.lucene.search.Query luceneQuery = parser.parse(builder
  .toString());
  Query query = fullTextEntityManager.createFullTextQuery(luceneQuery,
  type);
  return query.getResultList();
 }

}

Nuestro 1er DAO para una Entidad; como verán, se apoya en el GenericDAO, y en su implementación:


package com.viavansi.fdu.persistencia.DAO;
import java.util.List;

import org.jboss.seam.annotations.Name;

import com.viavansi.fdu.persistencia.VO.ProcessInfoVO;

/**
 * @author gmedina
 *
 */
@Name("processInfoDAO")
public class ProcessInfoDAO extends GenericJpaDaoFDU<ProcessInfoVO, Long> {

public ProcessInfoDAO() {
  this.type = ProcessInfoVO.class;
 }

public List<ProcessInfoVO> findByProcessName(String name) {
  return null;
 }

public List<ProcessInfoVO> findByJbpmName(String jbpmName) {
  return null;
 }

public List<ProcessInfoVO> findByArea(String area) {
  return null;
 }

}

Vamos a mostrar nuestro Finder interceptor el cual sigue el Interceptor pattern y está soportado por Seam; muy sencillo, si el método se llama findByWhatever el busca un named query llamado findByWhatever, en tu implementación del DAO solo debes retornar null, si retornas algo entonces el finder se anula automáticamente:


package com.viavansi.fdu.interceptor;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.intercept.InvocationContext;

import com.viavansi.fdu.persistencia.DAO.GenericDao;

/**
 * @author gmedina
 *
 */
public class FinderInterceptor { /**
  *
  * @param invocation
  * @return
  * @throws Throwable
  */
 @AroundInvoke
 @SuppressWarnings("unchecked")
 public Object executeFinder(InvocationContext invocation) throws Throwable {
  String methodName = invocation.getMethod().getName();
  if (methodName.startsWith("findBy")) {
  GenericDao dao = (GenericDao) invocation.getTarget();
  Object result = invocation.proceed();
  return result == null ? dao.executeFinder(methodName, invocation
  .getParameters()) : result;
  } else
  return invocation.proceed();
 }

Nuestro persistence.xml con la configuración de Lucene que necesita:


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence
 xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” version=”1.0″
 xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd“>
 <!–
  Conexión por defecto de la aplicación utilizando POOL de conexiones
 –>
 <persistence-unit name=”fduPersistenceUnit”
  transaction-type=”RESOURCE_LOCAL”>
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <jta-data-source>java:comp/env/jdbc/fdu</jta-data-source>
  <class>com.viavansi.fdu.persistencia.VO.UsuarioVO</class>
  <class>com.viavansi.fdu.persistencia.VO.MiembroVO</class>
  <class>com.viavansi.fdu.persistencia.VO.RolVO</class>
  <class>com.viavansi.fdu.persistencia.VO.ProcessInfoVO</class>
  <properties>
  <property name=”hibernate.show_sql” value=”true” />
  <property name=”hibernate.dialect” value=”org.hibernate.dialect.SQLServerDialect” />
  <property name=”hibernate.cache.provider_class” value=”org.hibernate.cache.EhCacheProvider” />
  <!–
  Configuración para el soporte de prefijos en Hibernate. Estrategia
  para generación de nombres de tablas asociadas a anotaciones Table
  EJB3.0.
  –>
  <property name=”hibernate.ejb.naming_strategy”
  value=”com.viavansi.framework.persistencia.jpa.NamingStrategy” />
  <property name=”hibernate.search.default.directory_provider”
  value=”org.hibernate.search.store.FSDirectoryProvider” />
  <property name=”hibernate.search.default.indexBase”
  value=”/Java/lucene/fdu/app” />
  </properties>
 </persistence-unit> </persistence>

Finalmente nuestro DAO el cual tiene anotaciones de JPA y Hibernate Search/Lucene


package com.viavansi.fdu.persistencia.VO;
import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.DateBridge;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Resolution;
import org.hibernate.search.annotations.Store;

import com.viavansi.fdu.persistencia.DAO.ISOLatin1Analyzer;

/**
 * @author gmedina
 *
 */
@NamedQueries( {
  @NamedQuery(name = "ProcessInfoVO.findByProcessName", query = "from ProcessInfoVO processInfo where processInfo.processName = ?"),
  @NamedQuery(name = "ProcessInfoVO.findByJbpmName", query = "from ProcessInfoVO processInfo where processInfo.jbpmName = ?"),
  @NamedQuery(name = "ProcessInfoVO.findByArea", query = "from ProcessInfoVO processInfo where processInfo.area = ?") })
@Indexed
@Analyzer(impl = ISOLatin1Analyzer.class)
@Entity
@Table(name = "`${PREFIX_FDU}PROCESS_INFO`")
public class ProcessInfoVO implements Serializable {

private static final long serialVersionUID = 1570433106072090149L;

private Long id;
 private String processName;
 private String jbpmName;
 private Date startDate;
 private Date dueDate;
 private boolean active;
 private String area;

/**
  * @return the id
  */
 @Id
 @DocumentId
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 public Long getId() {
  return id;
 }

/**
  * @param id
  * the id to set
  */
 public void setId(Long id) {
  this.id = id;
 }

/**
  * @return the processName
  */
 @Field(index = Index.TOKENIZED, store = Store.NO)
 @Column(name = "PROCESS_NAME", unique = true, nullable = false, insertable = true, updatable = true, length = 255)
 public String getProcessName() {
  return processName;
 }

/**
  * @param processName
  * the processName to set
  */
 public void setProcessName(String processName) {
  this.processName = processName;
 }

/**
  * @return the jbpmName
  */
 @Field(index = Index.TOKENIZED, store = Store.NO)
 @Column(name = "JBPM_NAME", unique = true, nullable = false, insertable = true, updatable = true, length = 255)
 public String getJbpmName() {
  return jbpmName;
 }

/**
  * @param jbpmName
  * the jbpmName to set
  */
 public void setJbpmName(String jbpmName) {
  this.jbpmName = jbpmName;
 }

/**
  * @return the startDate
  */
 @Field(index = Index.UN_TOKENIZED)
 @DateBridge(resolution = Resolution.DAY)
 @Temporal(TemporalType.DATE)
 @Column(name = "START_DATE", unique = false, nullable = true, insertable = true, updatable = true)
 public Date getStartDate() {
  return startDate;
 }

/**
  * @param startDate
  * the startDate to set
  */
 public void setStartDate(Date startDate) {
  this.startDate = startDate;
 }

/**
  * @return the dueDate
  */
 @Field(index = Index.UN_TOKENIZED)
 @DateBridge(resolution = Resolution.DAY)
 @Temporal(TemporalType.DATE)
 @Column(name = "DUE_DATE", unique = false, nullable = true, insertable = true, updatable = true)
 public Date getDueDate() {
  return dueDate;
 }

/**
  * @param dueDate
  * the dueDate to set
  */
 public void setDueDate(Date dueDate) {
  this.dueDate = dueDate;
 }

/**
  * @return the active
  */
 @Column(name = "ACTIVE", unique = false, nullable = false, insertable = true, updatable = true)
 public boolean isActive() {
  return active;
 }

/**
  * @param active
  * the active to set
  */
 public void setActive(boolean active) {
  this.active = active;
 }

/**
  * @return the area
  */
 @Field(index = Index.TOKENIZED, store = Store.NO)
 @Column(name = "AREA", unique = false, nullable = false, insertable = true, updatable = true, length = 100)
 public String getArea() {
  return area;
 }

/**
  * @param area
  * the area to set
  */
 public void setArea(String area) {
  this.area = area;
 }

/*
  * (non-Javadoc)
  *
  * @see java.lang.Object#hashCode()
  */
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((id == null) ? 0 : id.hashCode());
  return result;
 }

/*
  * (non-Javadoc)
  *
  * @see java.lang.Object#equals(java.lang.Object)
  */
 @Override
 public boolean equals(Object obj) {
  if (this == obj) {
  return true;
  }
  if (obj == null || !(obj instanceof ProcessInfoVO)) {
  return false;
  }
  ProcessInfoVO other = (ProcessInfoVO) obj;
  if (id == null) {
  if (other.id != null) {
  return false;
  }
  } else if (!id.equals(other.id)) {
  return false;
  }
  return true;
 }

}

Nota: Lucene necesita construir un indice inicial, les pegaré un pedazo de código de como hacer esto:


@SuppressWarnings("unchecked")
 public void reIndexLuceneDB() {
  FullTextEntityManager fullTextEntityManager = Search
  .createFullTextEntityManager(entityManager);
  Class[] entityClasses = { UsuarioVO.class, RolVO.class,
  ProcessInfoVO.class };
  for (Class entityClass : entityClasses) {
  for (Object object : entityManager.createQuery(
  "select obj from " + entityClass.getName() + " obj")
  .getResultList()) {
  fullTextEntityManager.index(object);
  }
  }
 }

Bueno, he pegado tanto código que explicarlo todo en un solo post es difícil, asi que manden sus preguntas.

Que lo disfruten.

Guido.

www.viafirma.com

Posteado por Félix García Borrego en September 3rd, 2008

Debido al gran interés que esta generando Viafirma, nuestra plataforma de Autenticación y Firma Digital en su versión comercial, hemos creado viafirma.com, en la que se recoge toda la información relacionada con las versiones comerciales de la plataforma ( Versión Standard y Advanced).

 ¿Por qué una versión comercial de Viafirma?

En la mayoría de los casos, nuestros clientes desean utilizar Viafirma sobre aplicaciones que no son compatibles con GPL; además, nos exigen soporte técnico, mantenimiento, plazos para nuevos desarrollos, tiempos de respuesta, una documentación completa, y en resumen, unas garantías que no ofrece la versión GPL. Por este motivo y para poder financiar los nuevos desarrollos a los que nos estamos enfrentando, hemos creado el portal  viafirma.com.

¿Implica esto un cambio de filosofía de la versión Software Libre?

No. Tenemos tanto que agradecer a la comunidad que nuestra intención sigue siendo apostar por una plataforma libre . De hecho acabamos de liberar como GPL la nueva versión de Viafirma 1.3.2, si lo desean pueden consultar la lista completa de nuevas funcionalidades en viafirma.org.

 

Nuevo cocktail: Windows Vista con una pizca de iTunes y Quicktime, precio recomendado “Error 46″

Posteado por Manuel Navarro Almuedo en September 3rd, 2008

Hola buenas a tod@s,

esta vez os escribo para comentaros un quebradero de cabeza más que me ha dado Windows Vista e iTunes (con Quicktime), un par de problemas:

1) Cada vez que arranco el iTunes, se vuelve a reinstalar.

2) Se produce un error de ActiveX al abrir el Quick Time Player: Error 46

Para el primero de los problemas, la solución fue un poco drástica: eliminar el acceso directo del iTunes que tenemos en el Escritorio y crear un nuevo acceso directo al iTunes.exe que tenemos en nuestra carpeta de “%Program Files%/iTunes”, lo colocamos en nuestro Escritorio y aquí no ha pasado nada :-D

Para solucionar el segundo error ya tenemos que hacer un par de cosillas más.

Primero os comento cuál es la causa de este error:
Parece ser que al instalar QuickTime Player las claves introducidas en el registro  de Windows Vista no adquieren permisos de acceso correctos. Exactamente lo que ocurre es que nuestro usuario (sea Administrador o no) no tiene acceso ni siquiera de lectura a dichas claves.

Esto os lo cuento yo y queda muy bonito ¿verdad?, pero ¿cómo podeis comprobar esto vosotros mismos?
Pues descárguense el programa Process Monitor  de Microsoft. Tras instalarlo y dejar abierta la aplicación, intenten abrir QTPlayer y miren los errores que se muestran en el Proces Monitor producen al intentar abrir el QuickTime Player, seguro les aparecerá “ACCESS DENIED” a distintas claves del registro (podeis filtrar las lineas que se muestran).

Pues bien, parece que tenemos claro ahora cuál es el problema, ¿cómo “repcuperar” los permisos de lectura sobre dichas claves?

Si hacemos lo típico, ejecutar “regedit” e intentar modificar los permisos manualmente veremos que no tenemos autorización para realizar estos cambios en esas claves afectadas. ¡Vaya chasco!

Bien, busquemos otra forma de modificar estos permisos. Usemos ahora otro programa de Microsoft llamado SubInACL: esta es una herramienta de administración, para modificar y consultar distintos parámetros del sistema como claves del registro, servicios, etc., pero vamos al grano.

Con este programa tenemos ahora que modificar los permisos asignados a estas claves que no pudimos modificar con “regedit.exe” .

Una vez descargado e instalado, debemos copiar el script que contiene Script.zip y descomprimir el .cmd en la carpeta”%Program Files%\Windows Resource Kits\Tools“, que es donde se debe haber instalado SubInACL.
Este script es parecido a otros que aparecen en algunos foros, pero este en concreto contiene algunas correcciones realizadas por mi y adaptado a Windows Vista en Español, no en Inglés. Recomiendo hacer una copia de seguridad del registro antes de ejecutar nada, siempre es conveniente trabajar sobre seguro.

A continuación, abramos una terminal de consola (Inicio / Ejecutar / cmd.exe para los no iniciados) y vayamos a la carpeta donde copiamos el script. Ejecutemos en la consola “resetSpanish.cmd” y veamos en el log mostrado que no salgan errores:

Done:        X, Modified        X, Failed        0, Syntax errors        0

lo importante es que “Failed”  y “Syntax errors” salgan a cero.

Este script hay que lanzarlo con un usuario Administrador y recomiendo desactivar el sistema de protección de cuentas de que dispone Windows Vista (Panel de Control / Cuentas de Usuario / Activar o desactivar el control de cuentas de usuario),
una vez lanzado el script podeis volverlo a activar.

Una vez hecho esto, podremos abrir “QuickTime Player” sin obtener el dichoso error 46.

Y recordad: siempre tenemos una alternativa en LINUX …

Namasté.

Viavansi ya es proveedor oficial de soluciones OpenCms

Posteado por Javier Echeverría Usua en August 28th, 2008

Los señores de Alcakon han tenido a bien introducirnos en la lista de “Professional OpenCms solution providers in Europe“… Con nosotros ya somos 9 las empresas españolas que desarrollan sobre OpenCms recogidas en el listado: Adequa (Barcelona), Consoltic (Málaga), Drago Solutions (Madrid), Encamina (Valencia), GPM Factoría Internet (Salamanca), inxtenso (Barcelona), Open Sistemas (Madrid), openTrends (Barcelona) y Viavansi (Sevilla). Eso sí, como está por orden alfabético, salimos los últimos del listado de proveedores :-D

Enhorabuena a mis compañeros del departamento de Desarrollo de OpenCms.

Códigos INE de municipios

Posteado por Javier Echeverría Usua en July 29th, 2008

He venido observando que hay una codificación INE de 6 dígitos en lugar de los 5 dígitos tradicionales. Por ejemplo, donde Sevilla solía tener un código INE 41091, ahora tiene un nuevo código 410917. Este código es el mismo que el anterior, más un dígito adicional que a priori parece ser un dígito de control.

Estos códigos nuevos se pueden descargar en formato Excel de la URL:

http://www.ine.es/daco/daco42/codmun/codmun08/08codmunmapa.htm

Parece ser que la codificación es la anterior, con la adición de un sexto dígito de control, como se menciona en esta dirección (”el último es un dígito de control que, asignado mediante una regla de cálculo, permite la detección de errores de grabación y modificación”).

Sin embargo, no he sido capaz de encontrar ninguna referencia a cómo se realiza este cálculo. En anexos de algunos documentos he encontrado referencias a un cálculo basado en un módulo 11, pero he comprobado que ésta no es la vía correcta.

Posibilidades:

  • El dígito se calcula mediante una fórmula arcana guardada en secreto por alquimistas que perduran desde la época de la piedra filosofal.
  • Es más fácil, pero no está en Google.
  • Está en Google, pero no sé buscar.
  • Es un número aleatorio para jorobar, realmente es una nueva codificación y punto, a guardarla en base de datos. Lo que pusieron mencionando una “regla de cálculo” era para despistar.

Se acepta ayuda. Gracias!