Dec 10

Qué es Spring Boot

Hace unos meses estuve jugueteando con Spring Boot, pero el ponerme a hacer código a lo loco mirando la documentación y algunos tutoriales, no me dio una idea de lo que realmente es Spring Boot.

La idea de Spring Boot es que podamos hacer aplicaciones Spring, pero con cero configuración. No tenemos que hacer ningún fichero de configuración, ni ficheros XML. A Spring Boot, usando una herramienta propia, le decimos qué tipo de aplicación queremos (web, con jpa, con postgres, etc) y él solo nos genera una proyecto maven/gradle con todo lo necesario y que se autoconfigura en el arranque.

Por ejemplo, si decimos que queremos una aplicación web, Spring Boot automáticamente nos embebe un Tomcat y nos lo configura con el servlet de Spring. Por supuesto, si no nos gusta la configuración por defecto (no queremos Tomcat, por ejemplo), sí podemos cambiar cosas para usar jetty, jboss o el que nos guste.

¿y cómo hace esta magia Spring Boot?

Pues añadiendo en nuestro proyecto Maven/Gradle dependencias estilo "spring-boot-starter-****". Por ejemplo, si añadimos la dependencia "spring-boot-starter-web", es la que se encarga de añadir todo lo necesario para embeber un Tomcat y el que nos crea (sin que ni siquiera lo veamos en nuestro proyecto) el fichero web.xml de nuestra aplicación correctamente configurado para Spring. Si añadimos "spring-boot-starter-data-jpa" junto con la dependencia de algún driver de base de datos, como por ejemplo h2, es Spring Boot el que automáticamente en el arranque nos configurará automáticamente los DataSource para esa base de datos y todo lo necesario para acceder a esa base de datos usando JPA.

La magia de Spring Boot va incluso más allá. Una vez añadida la dependencia "spring-boot-starter-data-jpa" y la del driver de nuestra base de datos, sólo tenemos que crear nuestras clases de base de datos con las consabidas anotaciones @Entity, @Id, etc …  y una interfaz (adecuadamente anotada) que herede de la interfaz de Spring CrudRepository<MyBean, Long>, siendo MyBean la clase persistente que nos hemos creado y cuyo id es un Long. Y listo, no tenemos que implementar la interfaz, Spring Boot lo hace por nosotros en tiempo de ejecución, dándonos todos los métodos típicos de consulta/inserción/modificación y borrado de MyBean en base de datos.

Dentro de nuestro proyecto Spring Boot, en src/main/resources hay un fichero, en principo vacío, de nombre applicacion.properties. En ese fichero podemos poner properties propias de Spring Boot para cambiar las configuraciones por defecto de Spring Boot. Un ejemplo tiípico es cambiar el puerto por defecto 8080 de tomcat por otro. Basta añadir en ese fichero la linea server.port=8000 siendo 8000 el puerto que queremos en vez de 8080. Aquí tienes todas las posibles propiedades a poner y valores por defecto.

 

En fin, estoy con ello todavía, pero promete mucho y merece la pena echarle un ojo. Lo comentado aquí es un pequeño resumen de lo que se dice en este vídeo

 

 

Jun 21

Mis dudas con Spring para aplicaciones de escritorio

Logo spring frameworkTodos nuestros sistemas se parecen, unos llevan determinados módulos, otros no. Por eso, siempre he estado pensando la forma de hacerlos modulares de forma que sea fácil quitar o poner módulos de un sistema a otro, cada uno con su configuración. Cuando me puse a pensar en ello llegué a la conclusión de que sería buena idea hacer que cada módulo fuera un jar, independiente de los otros. Luego, en un sistema, es cuestión de instanciar y configurar aquellos módulos que nos interesen, trayendo sólo los jar necesarios.

Puesto que los módulos interaccionan entre ellos y cuando uno de ellos quiere hacer algo normalmente necesita datos de otro módulo, o a veces cuando un módulo genera algo necesita avisar a los otros para que sigan el proceso, también me puse a pensar en ello. Una especie de mecanismo de suscripción de eventos, de forma que en algún sitio cerca del main, donde se instancian y configuran módulos, también se hicieran suscripciones a determinados eventos de un módulo y se avisara de ellos a los otros módulos.

Afortunadamente, antes de ponerme a codificar algo como esto, se me ocurrió investigar por internet y me encontré con los contenedores de inversión de control y en concreto con Spring Framework. Aunque el framework está muy pensado para aplicaciones web, está bien diseñado y puedo bajarme y usar sólo el núcleo, lo que me permite a través de ficheros XML instanciar los distintos módulos, configurarlos y hacer que se vean unos a otros. También me proporciona un sistema de publicación y suscripción de eventos entre módulos. Justo lo que quería.

Así que como suelo hacer en estos casos, cogí a un grupo de gente afín a mis ideas peregrinas, les conté lo fácil y bien que podiamos usar Spring Framework en nuestras aplicaciones y lo usamos en uno de los proyectos que empezaban. La experiencia fue buena y todos quedamos bastante contentos en general, así que decidimos ir aplicándolo a más proyectos.

Pero al empezar a usarlo en más proyectos e involucrar a más gente, empecé también a encontrar más oposición y otros puntos de vista. Un compañero mío más crítico que yo con las innovaciones comentó que "Spring no es más que una forma "friky" de hacer news". No obstante, él también andaba buscando una forma de configurar con ficheros sus módulos, ya que se ve repitiendo código de configuración prácticamente igual de un proyecto a otro.

Y el otro día sucedió algo que me ha hecho empezar a dudar de la utilidad de Spring Framework, al menos usando sólo el núcleo y en aplicaciones de escritorio. Este compañero en uno de los proyectos en los que tiene cierta responsabilidad me dijo que se estaban instanciando en Spring dos módulos iguales con configuración distinta, pero que habían cambiado los requisitos y debíamos eliminar uno de ellos y cambiar el otro por un tercero distinto. Nos pusimos a ello.

Borrar uno de los módulos es fácil, sólo hay que ir borrando las referencias en los ficheros XML y en algunos sitios muy concretos del código. Cambiar el otro fue algo más complejo, buscarlo para reemplazarlo, cambiar nombre de clases, parámetros a inicializar, buscar referencias para ver si son compatibles, etc, etc. Una vez que creímos todo estaba hecho, arrancamos la aplicación y nos saltan un par de errores, nos habíamos equivocado en el paquete de una de las clases de un bean de Srping Framework. Más cambios, nueva prueba y nuevo fallo. Esta vez, a la tercera fue la vencida y todo funcionando. Pero mi compañero hizo el comentario que me metió la duda en el cuerpo: "Si en vez de hacer los news y la configuración en ficheros XML los hubieramos hecho en código, todo esto habría cantado en el mismo IDE. Prefiero ver los errores mientras escribo que verlos después arrancando la aplicación".

Y tiene razón, hacer news y configurar en XML tiene la pega de que errores que se verían inmediatamente mientras escribes en el IDE (un new de una clase que no existe por ejemplo, o la llamada a un set para configurar algo) no los vemos hasta que arrancamos la aplicación.

Hay un plugin para eclipse que permite ver si lo que escribes en el XML de Spring es correcto (las clases existen, los métodos existen, etc), pero no lo tenía instalado y lo de que hayan cogido Spring los de SpringSource, me da "mal rollo", parece que se quieren dedicar a cobrar por dar cursos y que este tipo de plugins o incluso las descargas están cada vez más escondidas previo registro.

Instalaré el plugin, miraré la posibilidad de hacer un test de JUnit que verifique que un XML de Spring es correcto y a ver qué pasa. De todas formas, empiezo a pensar que sólo para hacer news no merece la pena. Me queda el tema de los eventos al que sí sacamos partido….

 

Jul 23

Pensamientos sobre proyectos grandes y Spring Framework

En su día, para nuestros proyectos grandes, teníamos muchas librerías y módulos separados. Cada programador solía ser responsable de uno de los módulos y tenía su proyecto independiente, con sus programas de prueba, simuladores y todo lo que le hiciera falta.

Eso estaba bien, pero tenía una ligera pega. No usábamos algo como maven y no teníamos control ninguno de dependencias cruzadas. Cada programador ponía sus dependencias de otros módulos según lo necesitaba. El problema, al final, es que no había forma de compilar eso desde cero, ya que era fácil que un módulo necesitara del jar de otro módulo, que a su vez necesitaba de un tercero y tras una cadena más o menos larga, había un módulo que necesitaba del jar del que estamos compilando. Sí, ya sé que es una falta grave de diseño y debería haberse pensado al principio y dejar claras esas dependencias, pero también es cierto que entre lo que lo pensado antes y la realidad después hay muchas diferencias.

Al usar maven, decidimos hacer un proyecto grande con subproyectos debajo (uno por módulo). Así maven comprueba las dependencias y si un programador pone una dependencia que no debe, maven le protesta. Sin embargo, esto también tiene una gran pega. El compilado desde cero se hace desde arriba del todo y el fallo de un módulo hace que los demás ni siquiera intenten compilar. Además, la dependencia se hace entre fuentes, por lo que para estar a la última, necesitas hacer update de todos los fuentes. Eso, en un proyecto grande, puede ser un buen rato casi todos los días.

Al descubrir que se puede usar el core de Spring Framework, aunque sean aplicaciones de escritorio, para instanciar los módulos y usar los eventos de Spring Framework para comunicarlos entre sí, me da la impresión de que se puede hacer relativamente fácil que los módulos hablen entre ellos y se pasen datos sin necesidad de que tengan dependencias entre ellos. Los primeros mini-proyectos en la que hemos usado este framework y hemos hecho módulos indpendientes totalmente, comunicados a través del framework y de código de transformación de tipos de datos de un módulo a los tipos del otro en el main, están resultando una pequeña maravilla en cuanto a organización.

Así que me estoy planteando el volver a módulos separados, en proyectos independientes, y con prohibición de poner dependencias de otros módulos, salvo algunos muy concretos pensados más como librerías comunes que como módulos a instanciar como beans de Spring Framework.

La pega es la de siempre, la paliza de mover todos los repositorios de CVS para que tengan otra estructura y el retocar todo el código, sobre todo quitando dependencias de unos módulos con otros. Todo se andará, poco a poco.

Una pequeña aclaración sobre las dependencias entre módulos. Suponamos que tenemos modulo1.jar y modulo2.jar y que modulo1.jar necesita llamar a cosas de modulo2.jar. Para no meter la dependencia a lo bestia, normalmente hacemos una InterfaceModulo2 con las llamadas a las cosas del módulo2 que sean de interés desde fuera. Por supuesto, esa interface está en modulo2.jar. Y por supuesto, los parámetros y retornos de los métodos de la interface son tipos primitivos de java o bien tipos que están en modulo2.jar. Pues bien, eso hace que modulo1 dependa de modulo2, ya que ve al menos a la interface y a los tipos de parámetros y retornos. Por supuesto, una opción es hacer un tercer módulo InterfaceModulo2.jar con la interface y los tipos, pero me parece multiplicar el número de jars a lo tonto.

La opción que estamos planteando ahora es que modulo1 no vea en absoluto a modulo2. Cuando necesite algo de módulo2 (en realidad, cuando necesite algo, lo que sea), debe lanzar un "evento" indicándolo. Es el código del main el encargado de recoger ese evento y hacer la petición a modulo2, para pasar luego los resultados a módulo1. Esto puede parecer costoso, sobre todo si hay mucha necesidad de cosas de modulo2 por parte de modulo1, pero… si hay tanta necesidad de cosas ¿no estará mal pensado hacer dos modulos? ¿no estará mal pensada la funcionalidad de cada módulo?.

En fin, un pequeño rollo, pero como indico en el título, son símplemente "pensamientos".

Nov 30

Springide

Llevo casi toda la semana entretenido, cambiando un poco los módulos ya hechos de una aplicación de escritorio para poder instanciarlos usando Springframework e instanciándolos con Springframework.

El primer módulo lo abordé con la ilusión de probar algo nuevo. Sin embargo, a la hora de escribir el fichero xml de configuración de Springframework empecé a intuir que ese fichero puede ser un verdadero infierno. Tenía abiertos dos editores, en uno la clase java principal del módulo/bean y en el otro el fichero XML. Iba mirando el nombre exacto de los métodos set() para poner el property con el mismo nombre en el fichero XML. Me reordaba a los viejos tiempos en que programaba en C++ con el vi, sin ningún tipo de IDE. Tenías que ir abriendo los ficheros .h para ver cómo se llamaba exáctamente el método y su parámetros para poder hacer la llamada en tu fichero .cpp

Indagando por google, descubrí que efectivamente, ese es uno de las pequeñas pegas de Springframework: XML grandes y pesados de construir.

Pero me dije, como todo está inventado, seguro que hay un plugin de eclipse para Springframework. Efectivamente, en Springide tienen un estupendo plugin de Springframework para eclipse. Se puede instalar desde eclipse, con "help" -> "software updates" -> "find and install" y poniendo la dirección http://springide.org/updatesite_dev/

La instalación me dio un pequeño problema. No se deja instalar completo, posiblemente porque la versión de eclipse que tengo es la más última y el plugin debe andar un poco por detrás. No obstante, la parte básica del plugin sí se instaló.

Una vez instalado Springide, la construcción del fichero XML es muy agradable. Eclipse ya ofrece ayuda contextual para los ficheros XML, de forma que en cualquier sitio del fichero, pulsando Ctrl-espacio, podemos ver los posibles tags o atributos XML que se pueden añadir siguiendo el DTD que se indique en la cabecera. Con Springide, la ayuda contextual incluye además las clases accesibles para el proyecto o las referencias a los beans ya declarados en el fichero XML.

Me explico, si empezamos a escribir

<bean id="nombre" class="MiC

y justo depués de la C de MiC pulsamos Ctrl-espacio, aparecerá el típico menú con todas las clases accesibles que empiecen por MiC. Seleccionamos una en el menú y se añade automáticamente, incluyendo el paquete.

De la misma forma, si escribimos

<property name="

y pulsamos Ctrl-espacio, aparece un menú con todos las propiedades de la clase en la que estemos poniendo este tag property. Elegimos una y seguimos escribiendo

<property name="propiedadElegida" ref="

y ahora, pulsando Ctrl-espacio sale un menú con todos los beans que ya tenemos declarados, para elegir uno.

Me queda comprobar si se pone en rojo si escribimos una clase, propiedad o bean que no exista.

Nov 24

Creo que me he metido mucho con Hibernate

Sigo con mis pruebas de herramientas/librería de persistencia en base de datos.

Con Hibernate conseguí que funcionara. El ejemplo tonto con una única tabla funcionó casi a la primera. Las HibernateTools – Middlegen para sacar los .xml y los .java a partir de la base de datos me dieron más problemas, pero también funcionaron.

Luego hice pruebas con iBatis. La filosofía de trabajo es distinta, pero el plugin de eclipse me funcionó bien e iBatis genera código hasta un nivel más alto, genera una interface de DAO y una implementación iBatis.

Investigando, descubro que hay una especificación de Java, llamada JPA -Java Persistent API, parte V del tutorial de JEE-, que pretende indicar cómo trabajar con objetos java persistentes -que se guardan más o menos solos en base de datos, sin que el programador tenga que preocuparse de los SQL-.

También descubro que la gente de Apache ha hecho otra especificación similar, JDO, para lo mismo, pero que pretende ser más completa que JPA.

También descubro JPOX, una implementación que cubre las dos especificaciones anteriores: JPA y JDO. Sin embargo, no he conseguido que me funcione. Desde eclipse con el plugin correspondiente me falla al crear las tablas en base de datos y de momento me ha dado pereza crearlas a mano. En cuanto a maven, tienen una mezcolanza rara. Parece que se han quedado en maven 1 según la documentación, pero si te lo bajas con maven 2 está disponible, aunque no encuentro documentación para configurarlo.

Y descubro también que eclipse dali viene con una perpectiva y un "wizard" de proyecto para trabajar con objetos persistentes JPA. Por supuesto, tampoco me ha funcionado.

Y para marear más la perdiz, y todavía sin probar, Glassfish de java lleva una implementación de JPA, hay también otra implemantación de Apache OpenJPA,

En fin, todo un mundo y un abanico de posibilidades. Para probarlas todas no basta con que se paren dos meses la producción, harán falta varios años . De cualquier forma, Hibernate es uno de los que menos problemas me ha dado -descontando los de MiddleGen- y yo creo que sin duda es el más conocido. Aunque la filosofía de trabajo es distinta, iBatis también es conocido y da la impresión de que tienes más control sobre lo que estás haciendo. Ambos están "soportados" por SpringFramework –ver capítulo 12– que sí pienso empezar a usar, así que creo que me centraré un poco más en Hibernate e iBatis.

Nov 15

Jugando con SpringFramework

Hace tiempo que oi hablar de SpringFramework, pero siempre he oido hablar de él asociado a J2EE. Como lo mio son aplicaciones de escritorio y de J2EE no tengo ni idea, nunca he hecho caso de SpringFramework, al igual que no lo he hecho de Structs.

Sin embargo, en algún sitio leí que SpringFramework es un framework en capas, que puedes utilizar más o menos independientemente y algunas de ellas son útiles para cualquier tipo de aplicación, incluidas las de escritorio. Así que me puse a investigar y luego a jugar.

Efectivamente, entre las capas de SpringFramework, hay algunas claramente de J2EE y aplicaciones web -las de nombre JEE y Web-, pero hay otras que no lo son. En concreto, DAO y ORM sirven para acceso a base de datos, AOP para programación orientada a aspectos y Core es un "contenedor" de beans -y no precisamente EJBs-.

En principio me han llamado la atención DAO y ORM, ya que el acceso a base de datos lo uso mucho y cualquier cosa que te ayude es buena. Me hice mi primer ejemplo tonto con DAO y me ha parecido bien. Es sencillo y quita bastante trabajo repetitivo de JDBC -hacer bucles con los ResultSet, componer complejas sentencias SQL, etc-.

Lo de AOP -Programación orientada a aspectos- sé de qué va y no suelo usarlo, así que esa capa en principio me interesa menos y no he probado nada con ella.

En cuanto a Core, el "contenedor de beans", lo he mirado porque ando dándole vueltas a algo parecido y veo la posibilidad de que ya esté implementado algo similar a lo que ando dando vueltas. Mi intención es hacer un ejecutable que lea en un fichero de configuración qué módulos debe instanciar y que estos módulos, sean en principio independientes y sea el main el que "trasiega" datos de uno a otro. El contenedor de beans Core "suena" a algo parecido. De momento, ya me he hecho un ejemplo tonto con Core.

El uso de Core, básicamente consiste en hacer clases bean con métodos set() y get(). Luego, en un fichero XML, dices qué clases bean deben instanciarse, cómo deben inicializarse sus atributos y qué instancias de beans ven a qué otras instancias de beans. Luego, en tu "main", instancias uno de los BeanFactory, como la clase XmlBeanFactory de SpringFramework y listo, se instancian e inicializan automáticamente todos los beans.

Fuera de la web de SpringFramwork, hay una ampliación para clientes "ricos", es decir, para clientes con SWING. Esta ampliación en principio me resulta interesante, pero veo que anda en la versión 0.2.1 y la documentación escasa, por lo que no sé si está todavía bastante "evolucionada".

Seguiré investigando todo esto.