Las mismas discusiones durante 33 años

Estoy leyendo "The Mythical Man-Month" (TMMM para abreviar), libro de obligada lectura para todo informático. 

En la estantería he ido acumulando libros cuya vigencia es limitadísima, especialmente todo aquello que se refiera a lenguajes. Por ejemplo, "Beginning JavaServer Pages" fue un muy buen libro para comenzar con J2EE, pero ya caduco, a pesar de provenir de revisar otro que apenas tendría dos o tres años. Sin embargo, TMMM está sorprendentemente vigente.
Es un libro cuya primera edición data de 1975. Contiene un conjunto de ensayos sobre el desarrollo de grandes sistemas de información, que resumen la experiencia de su escritor, Frederick P. Brooks, conocido por participar en el desarrollo del IBM System 360. 
Seguramente este no sea la última reflexión aquí que genere este libro, pero ya en los primeros capítulos se puede comprobar que en ingeniería del software llevamos 33 años con las mismas discusiones.

El capítulo 2, que da título al libro, comienza diciendo que las técnicas de estimación en proyectos software son pobres, y que además confunden esfuerzo con progreso (al tomar como medida hombre y mes). Y que cuando algo va mal, nos empeñamos en meter más gente en el proyecto. No sé vosotros, pero para mí esto es el pan nuestro de cada día.

En ese mismo capítulo se habla de las pruebas, y de no contar con ellas en la planificación.

También detalla unas medidas que supuestamente demuestran que meter gente retrasa el proyecto. Esto me parece muy exagerado (concretamente, las precondiciones del cálculo me lo parecen), pero el concepto está ahí.

Las reflexiones sobre la comunicación, del capítulo 6, también son muy interesantes. Seguramente si lo escribiese hoy tendría muchísimas cosas que decir, gracias a la distribución de contenidos en red de la actualidad.

En resumen, un libro sobre ingeniería del software que 33 años después sigue siendo vigente.

PD: el capítulo 7 es genial, mostrando la Torre de Babel como el 2º trabajo de ingeniería de la Humanidad =D

Posted by Juan Ignacio Sánchez Lara 12:41 Enlaces a esta entrada  



El empleo en la informática

La opinión generalizada sobre el empleo en informática, al menos en mi entorno, es que hay trabajo, aunque podría ser mejor y estar mejor pagado. Hoy, en El Mundo, bajo un titular que reza "¿En paro? Conozca dónde es posible encontrar trabajo pese a la crisis económica", encontramos el siguiente párrafo:

Telecomunicaciones e informática: La gestión de software y bases de datos de las compañías necesitan más técnicos de los que las facultades y módulos forman. Los puestos más requeridos son analistas, programadores y jefes de proyecto.
Que me perdonen los telecos que lleguen aquí, pero ni la gestión de software, ni la de bases de datos, ni los puestos de analistas ni programadores ni jefes de proyectos deberían ser competencia de gente formada en telecomunicaciones. Por supuesto que hay muchos telecos válidos, inteligentes, que se autoforman y que desempeñarían un gran papel en estos cargos, incluso mejor que muchos informáticos, pero igual que lo habrían hecho si fuesen ingenieros industriales, químicos, o hubiesen estudiado magisterio. Comprendo que los trabajos de informático sean a veces desempeñados por gente que no tiene ninguna titulación de informática (universitaria o de formación profesional), pero me gustaría que desapareciese esa equiparación entre telecomunicaciones e informática por defecto. Los telecos tienen sus virtudes, y serán mejores que otros en muchos aspectos, pero no son informáticos

Dicho esto, me gustaría hablar de un amigo. Tras años dedicado a Bellas Artes, por vocación, la frustración sumada de la confrontación con el profesorado y con el mercado laboral le hace dejarlo en favor de una titulación de Informática de Gestión. Es el típico cacharrero, cariñosamente hablando: es de esos que le encanta trastear con ordenadores, destriparlos, probar programas nuevos... Ya sabe que la carrera no tiene nada que ver con eso, pero no tiene miedo. Las matemáticas no se le daban mal, y aunque no ha programado nunca no cree que vaya a tener problemas con ello, y quiere el título para trabajar. No sé si habría sido mejor dirigirse a un módulo en vez de a una carrera, pero la decisión está tomada -y le deseo toda la suerte del mundo-.

Obviamente su decisión bien tomada por la percepción del primer párrafo. Aunque el mercado laboral informático es mejorable, está infinítamente mejor que los demás. En mi opinión, si una persona quiere destacar de la marabunta de profesionales que hay en este mercado, debe potenciar los siguientes aspectos:
  • Autoformación: el contenido de la carrera vale como base, pero no vale para la vida profesional. Si no quieres eternizarte en cargos de desprestigiado programador junior, lee y programa por tu cuenta. Tanto en el trabajo (¡es sorprendentemente raro encontrar gente que se documenta por su cuenta, ya no digamos que lee las referencias oficiales en vez de googlear!)  como en casa (menos telebasura y más leer).
  • Especialización: está bien poder poner veinte tecnologías en un CV, pero si todas están al mismo nivel la impresión será mala. Si te han llamado a una entrevista especialmente por una de ellas y no puedes responder a la mayor parte de las preguntas que te hagan por ella, ni se preocuparán por las otras. Hay que dominar dos o tres (bases de datos, J2EE,Hibernate, clustering...)...
  • ...pero hay que tener versatilidad: vale, te han contratado para programar J2EE, pero si surge un proyecto para montar un CMS, no te niegues. La aptitud y la actitud para el aprendizaje son fundamentales.
  • Iniciativa: propón mejoras, cuida el detalle... No basta con que la aplicación funcione para que tenga éxito. Si ves que dos botones son indistinguibles, propón los cambios. Haz componentes reutilizables cuando veas elementos repetidos aunque el diseño no lo haya especificado. Si los estilos de una página son mejorables, hazlo... Si ves que una página va a ser incómoda para el usuario, dilo. Si ves que código que no has hecho tú está mal, mejóralo, y avisa a quien lo haya hecho para que lo tenga en cuenta. Las jerarquías dan igual, el desarrollo es un trabajo en equipo. Si alguien se enfada porque "un igual" le diga algo, el problema lo tiene él. "Nadie es tan pobre como para no tener nada que enseñar, ni tan rico como para no tener nada que aprender". Eso sí, no recrimines, sé constructivo.
Ojo. Me parece totalmente respetable la gente que no tiene especial vocación y que está en esto sólo porque hay trabajo. Esa gente a veces ni tiene ordenador en casa, y ni se plantea tocarlo fuera del horario laboral para otra cosa que no sea ocio. De verdad, perfecto. Pero esa gente tiene que asumir que su desarrollo profesional va a venir delimitado por lo que consiga de las empresas. Uno no se puede quejar de "lo mal que está esto" si no pone nada de su parte.

Posted by Juan Ignacio Sánchez Lara 11:40 Enlaces a esta entrada  



Si tuviese que organizar una empresa de informática...

Vamos a jugar al "Si fuera...", con la tranquilidad que da saber que esto es un blog y que no van mis habichuelas en ello :).


Si tuviese que organizar una empresa que desarrollase aplicaciones...
  • Utilizaría Scrum como metodología de trabajo. Creo que las metodologías tradicionales (RUP, Metrica...) son demasiado pesadas y recargadas de documentación y burocracia. Ojo, que lo que tengo en mente son aplicaciones de gestión, "convencionales". Si tuviese que desarrollar el software de un satélite o de instrumental médico, otro gallo cantaría. Para cada situación, la mejor herramienta.
  • Me olvidaría de certificaciones ISO, CMMI y demás a menos que realmente me obligasen, al menos al principio. Tenerlas no garantiza realmente nada. Yo soy el primer interesado en desarrollar software de calidad, y voy a hacer todo lo posible por lograrlo. Si a lo que ya hago puedo ponerle un sello, perfecto. No quiero andar parcheando, como todas las empresas, la semana antes de una revisión.
  • Si tuviese que fijar una única plataforma de trabajo (es un requisito que se suele establecer en las organizaciones) sería Java, desarrollando con Seam. Hibernate es fantástico, RichFaces me parece la mejor librería JSF para Ajax... y Seam los integra y mejora.
  • Los desarrolladores tendríamos Eclipse, con JBossTools y otros plugins útiles como JadClipse.
  • En el repositorio, SVN, tendríamos los proyectos listos para construir con Maven 2.
  • Usaríamos Trac para gestionar los errores.
  • Y XWiki para la documentación a compartir (tutoriales, ayudas...).
  • Tendríamos un sistema de integración contínua (¿Hudson, quizá?) que nos monitorizase los proyectos, ejecutando...
  • ... pruebas con JUnit, TestNG y/o Unitils, y...
  • ... medidas de calidad del código como Eclipse Metrics, PMD (¡con CPD!), Crap4J, Coverage.
  • ... pero escucharía comentarios y leería sobre herramientas para usar lo mejor posible :).
Algunas de estas decisiones se basan en la experiencia y otras por ahora sólo en expectativas. ¿Qué opináis?

Otra de mis dudas es el servidor de aplicaciones y el SGBD. En función de la escala supongo que habrá que elegir puntos intermedios desde Tomcat+MySQL hasta WebSphere+Oracle...

Posted by Juan Ignacio Sánchez Lara 16:00 Enlaces a esta entrada  



Diseñando una arquitectura (Apéndice): Trabajo futuro

En este tiempo hemos ido dejando cosas por el camino y anotando "oportunidades de mejora". Algunas las incorporaremos en cuanto podamos, otras habrá que probarlas, otras quedarán para otros proyectos...


Todas las críticas y sugerencias adicionales serán bienvenidas, como siempre.

Objetivos:
  • Mejorar la productividad del desarrollo.
  • Reducir el desarrollo propio del framework al mínimo, maximizando el uso de herramientas open source disponibles.
  • Solventar o al menos atenuar las limitaciones de la plataforma (J2EE) y de JSF.
  • Facilitar la integración de librerías.
JSF 1.2 (+ RichFaces 3.2)

Lo primero será migrar a JSF 1.2. Este estándar está estrechamente vinculado con el servidor de aplicaciones, y hacerlo exige migrar a SJSAS 9 (o al revés, como prefieras verlo, ya que tampoco se puede usar el 1.1 en el 9). No es un gran avance en sí mismo (se espera bastante de JSF 2, hay multitud de cosas inexplicablemente mejorables todavía en la actualidad), pero llevará consigo pasar a la rama 3.2 de RichFaces, lo cual sí es una gran mejora. Nuevos componentes, mejoras muy importantes en los actuales...

JavaRebel

Tener que reiniciar el servidor constantemente es un infierno. Esta librería promete mejorar esto, minimizando la necesidad de reinicios mejorando la sustitución de clases y ficheros de configuración en caliente. Hay que probarlo.

Pruebas orientadas a datos

Probar el código de una aplicación de gestión implica conocer y manipular el estado de la base de datos. Estoy seguro de que ya hay soluciones para facilitar esto (¿TestNG, Unitils...?).

JSFUnit

Quiero poder probar a nivel de vista, y JSFUnit sirve para esto. Por ejemplo, cuando me encuentre con un problema de visualización en una página, quiero poder programar (con un coste en tiempo bajo) una prueba que demuestre que existe dicho problema, y que me sirva para comprobar que la solución efectivamente lo resuelve.

Motor de workflow

Realizamos una formación en el motor Enhydra Shark, y fue francamente decepcionante. Sí, se podía hacer lo que dice que hace, pero no ayuda a realizar una aplicación. Al elegir un componte tan fundamental en una arquitectura no me vale con que proporcione algo de valor añadido, debe ser realmente productivo. Vimos que nos iba a dar más trabajo y problemas de lo que iba a aportar, y lo descartamos en favor de desarrollar uno propio. En la actualidad lo que hemos desarrollado nos permite implementar el diagrama de flujo de un modelo a nivel de base de datos. Sin programar una línea de código nuevo podemos hacer que un modelo pase por estados, controlar a nivel de lógica de negocio la seguridad de las acciones, asignar tareas automáticamente, delimitar plazos, realizar forks y joins, declarar la seguridad a nivel de propiedad (símplemente con las propiedades rendered y displayValueOnly en los componentes JSF el sistema calcula qué campos puede ver y/o editar un usuario) y un largo etcétera. La gran ventaja de "nuestro" motor con respecto al resto, aparte de poder hacer (casi) de todo sin programar una sola línea, declarando todo en base de datos, es que tenemos componentes JSF. Mediante una simple etiqueta se pueden hacer cosas como listar las tareas pendientes, generar una botonera para ejecutar las acciones que el usuario puede hacer, mostrar el historial de la tramitación... Tener todo esto es un auténtico trabajo tangible que permite tener un flujo funcionando en una aplicación en muy poco tiempo.

El desarrollo del mismo fue por imposición, pero creo que ha sido beneficioso (suelo decir que del desarrollo propio para el framework esto es lo único realmente útil). Sin embargo, no creo que desarrollarlo desde cero haya sido lo mejor. La decisión se tomó porque ya se había perdido demasiado tiempo con el Enhydra Shark como para plantearnos otras opciones, pero estoy casi seguro de que tiene que haber alternativas mejores. Tengo jBPM en el punto de mira. Si cumple mis expectativas, mi intención es, para nuevos horizontes (no pienso reemplazar lo existente en el Framework ya), adoptarlo y ampliarlo, que para algo es open source. Por ejemplo, hacer componentes JSF que reduzcan ese salto entre el interfaz y el modelo, principalmente.

Seam

Cuando se decidió la arquitectura del framework, Seam era un proyecto prometedor pero todavía inmaduro, como han demostrado los grandes cambios y mejoras incorporados en la 2. Por ello elegimos Spring, maduro, completo, y no nos hemos arrepentido en absoluto.
Sin embargo, a estas alturas la lista de características de Seam contiene todo lo que usamos de Spring, a la vez que complementa a JSF corrigiendo sus carencias. Lo que es más, está orientado a dar "en un paquete" toda la pila de librerías, desde Hibernate a RichFaces, e integrarlas a todos los niveles. También para nuevos horizontes (estoy muy contento con el uso que damos a Spring) mi objetivo es usarlo intensivamente. 

Posted by Juan Ignacio Sánchez Lara 16:05 Enlaces a esta entrada  



Diseñando una arquitectura (IV/IV): Conclusiones

Aquí acaba el trayecto en el que he pretendido volcar prácticamente mis últimos dos años de trabajo.


IV. Conclusiones

Generales

El uso de librerías más avanzadas con el fin de aumentar la productividad exige más del programador. Cualquiera puede picar código a destajo, pero no todo el mundo tiene la misma facilidad para abstraerse y pensar en términos de capas, de objetos... No es sólo una cuestión técnica, por ejemplo, de "saber Hibernate". El uso de estas herramientas revaloriza la capacidad para trazar errores, para hacer código correctamente encapsulado, para aprender nuevas tecnologías... La aptitud de los programadores es, por tanto, más importante que nunca.

Obviamente también lo es la actitud. Entre las quince o veinte personas que se han enfrentado con el "nuevo framework" y el nuevo entorno de desarrollo hemos encontrado actitudes muy diferentes. Por ejemplo, con un nuevo IDE, los hay que en tres días se han aprendido todos los atajos para las acciones frecuentes, y los hay que dos años después siguen usando el ratón para guardar un fichero. Los hay que incluso llegan a trazar el código de las librerías en busca del error (alguno llegó a mirar código nativo de la JVM) y otros que insisten en redesplegar cuando algo no funciona, "por si acaso". Los hay que en el foro o por correo exponen el problema enseñando trazas, código, etc, y los hay que dicen "no me funciona".

La aptitud y la actitud son algo difícilmente controlable. Las medidas más importantes que se pueden tomar son mejorar los procesos de selección de personal, formación, e incentivar. En otra ocasión me extenderé más con la experiencia ganada en estos aspectos, quiero evitar otra entrada infinita como la anterior.

Entorno de desarrollo

A lo largo de casi dos años ya nos hemos encontrado varios bugs en MyEclipse, pero nada grave. Es un buen entorno de trabajo, aunque si no hubiésemos necesitado la integración de Matisse (no sé si ya habrá plugins gratuitos que lo integren, por aquél entonces no) yo me habría ceñido a Eclipse sin más. Fundamental el valor añadido que aportan otros plugins, como elJadClipse para la ingeniería inversa, o PMD y FindBugs para la calidad del código. La integración con JSF, Spring o Hibernate me parece decepcionante. Los asistentes para añadir capacidades de dichas librerías a los proyectos me parecen innecesarios y conflictivos. No está muy claro cómo decir, por ejemplo, que un proyecto ya existente "es JSF" o "es Spring", los asistentes están muy orientados a cuando se parte desde cero.

Eso sí, el detector de conflictos en el código CVS es lamentable. Especialmente cuando trabajas con varias ramas, resolver los conflictos con él es un suplicio. A veces estoy recurriendo al Araxis Merge para solventar las carencias del Eclipse en este sentido.

Tener que usar SJSAS 8 como servidor es un infierno. El problema no es los bugs que pueda tener (todas las aplicaciones los tienen), sino el soporte que existe en la comunidad open source sobre él. Las librerías están probadas y soportadas siempre sobre Tomcat y JBoss, los demás servidores sólo marginalmente. A menudo ni existe información (ni en la documentación ni en los foros) sobre otros servidores, y cuando hay suele estar obsoleta o incompleta. Además, el soporte técnico (la principal razón para utilizarlo) se suele lavar las manos cuando te encuentras con un problema, alegando que es un tema de la librería, no del servidor. En breve nos enfrentaremos a migrar a SJSAS 9, que esencialmente es el Glassfish 2, que sí es open source,  lo cual supongo que mitigará el problema.
No dudo que SJSAS sea un buen servidor, con buenas herramientas de administración, clustering y demás. Mientras todo funcione no hay problema. Sin embargo, cuando aparece un error, la sensación de desamparo es tremenda.

Generalidades sobre las librerías

Cuando te bajes las librerías, bájate también el código fuente y configúralo en Eclipse al configurar las librerías. Esto te permitirá tener el javadoc del código y depurar. No es que vayas a modificar su código, pero cuando te encuentres con una excepción inesperada podrás trazar para localizar el problema. El trabajo de documentación y de tratamiento de excepciones en librerías Java de código abierto suele ser excelente, pero cuando no lo es, disponer de esto es impagable.

El trabajo de integración (incluyendo resolver los problemas que aparecen a posteriori) de las librerías de vista (MyFaces, Tomahawk, Sandbox, Facelets y RichFaces) en el SJSAS es problemático. Así como la convivencia de Spring e Hibernate es perfecta, el resto no lo es. Por favor, ¡integración de Facelets en JSF ya!

Algunos dicen que el framework tiene demasiadas librerías, pero yo opino que incluso le falta alguna. En vez de utilizar un motor de workflow existente (jBPM, Enhydra Shark...) hemos desarrollado uno propio. Si bien creo que lo hecho está muy bien, IMHO ha sido un error. Habría sido mejor tomar uno existente y desarrollar sobre él para mejorar sus carencias.

Hibernate

Ya me he expresado varias veces muy en favor de Hibernate, el cual recomiendo encarecidamente. Aquí me centraré sólo en los puntos negativos.

Hibernate no es intrínsecamente lento ni devorador de memoria (de hecho, correctamente usado incluso puede optimizar ambos aspectos), pero hay que "atarlo en corto". Es muy fácil no darse cuenta y provocar que la carga de una página genere cientos de consultas. Abstraer el acceso a datos es fantástico, pero si no se pone cuidado es fácil que se vaya de las manos.

El polimorfismo y la herencia desde el punto de vista de la programación es elegante y potente, pero genera consultas monstruosas. Úsese con moderación. Nuestro DBA me miró asustado al ver que una consulta ocupaba aproximadamente siete folios (espacio simple, fuente 11 aproximadamente :) ). Sin embargo, hay que admitir que el rendimiento de Oracle en estos casos es espectacular. Bastó con mejorar una vista (era de sólo lectura, así que "materializarla" fue una solución óptima) para que se ejecutase sin problemas de coste. Mi recomendación es exprimir Hibernate al máximo, haciendo el código lo más elegante y correcto posible, y optimizar a nivel de BBDD. Si aún así algo se vuelve lento, siempre se puede optimizar ese punto en concreto.

Algo similar a nuestros problemas con el (nulo) soporte a SJSAS ocurre con el combo Hibernate + Oracle, especialmente en la gestión de datos binarios. Sin embargo, afinando un poco con el driver y utilizando alguna mejora que ofrece Spring al respecto, no hay problema sin resolver.

JSF

Como ya hemos dicho, sólo es una base. Facelets es imprescindible (¡estándar ya!). RichFaces es una gran librería para Ajax.

Posted by Juan Ignacio Sánchez Lara 14:58 Enlaces a esta entrada  



Diseñando una arquitectura (III/IV): Implantación

Para explicar esta etapa, la palabra es crisis. Pero no tanto la acepción extendida en la actualidad, sino el significado etimológico que recoge la Wikipedia

Coyuntura de cambios en cualquier aspecto de una realidad organizada pero inestable, sujeta a evolución; especialmente, la crisis de una estructura.
El éxito o fracaso de este cambio se producirá (no considero que ya se haya acabado este periodo de cambio) si hacemos una correcta gestión de la crisis. 

III. Implantación

En este apartado expondré cómo afrontamos este cambio, los problemas encontrados y las soluciones aportadas, y también los errores. Las oportunidades de mejora quedarán para el apartado IV, de conclusiones. Me intentaré ceñir a los hechos del cambio, dejando otras consideraciones para otro momento.

Entorno de desarrollo

El cambio del entorno de desarrollo consistía en dejar la combinación JDeveloper + OC4J como servidor local y SJSAS 8.1 en entorno de desarrollo compartido y sustituirlo por MyEclipse + SJSAS 8.2 en local.
Tras muchas pruebas vimos que la integración con el SJSAS tendría que ser mediante dos despliegues: uno packaged (internamente es generación del war + despliegue) inicialmente y para redespliegues, y uno exploded (internamente es copia de binarios al directorio de despliegue del servidor). Sin uno o sin otro el servidor no se da cuenta de los cambios.
Para hacer la migración preparé un escueto manual de instalación de ambas herramientas. Un mismo día hicimos que todos los desarrolladores (programadores y analistas) hiciesen el cambio. La verdad es que llevó bastante más de lo esperado. La instalación y configuración de ambos (adecuación al entorno interno y librerías), que por mi experiencia creo que se puede llevar a cabo en menos de media hora (yo lo he hecho, con un ordenador no especialmente rápido), en algunos casos rondó las dos horas, lo cual no me parece aceptable. Sin embargo, no recuerdo que ningún problema se debiese a otra cosa que no seguir las instrucciones. Redactarlas fue principalmente un ejercicio de repaso de lo hecho, que sirviese de guión para seguir todos los mismos pasos. Antes del cambio utilicé a un compañero de conejillo de indias, lo cual me sirvió para corregir los errores de la instalación, así que la versión definitiva usada estaba completa. IMHO ni siquiera debería haber escrito nunca el manual. La práctica totalidad de los desarrolladores somos ingenieros informáticos, un buen porcentaje ingenieros superiores (o en proceso de serlo), e instalar un IDE y un servidor no debería ser algo traumático. Sin embargo, quedó de manifiesto deficiencias en la formación (sin ánimo de ofender a nadie). Se puede salir de la carrera prácticamente sin programar, sin cacharrear, lo cual hace que nuestras aptitudes prácticas estén sin entrenar. A menudo incluso cuesta discernir entre lo que es un problema en el entorno de desarrollo y lo que es un problema en el servidor. Recomendaría exigir un trabajo más conciencudo en el proyecto de fin de carrera, de forma que este sirviese al menos para conocer las herramientas que se va a emplear al salir al mercado laboral, pero como, al menos en la Universidad de Valladolid, a "la competencia" se le regala la matrícula de honor en el proyecto, pues me parecería injusto. Antes de que surjan los trolls en los comentarios, por supuesto que hay ingenieros en telecomunicaciones realmente buenos, inteligentes, válidos y trabajadores, mucho mejores que muchos informáticos, pero el hecho es que a menos que insultes al tribunal durante la presentación, en esa carrera la nota por defecto del proyecto es matrícula de honor.

Una vez superado estos ligeros problemas iniciales, el día a día con estas herramientas ha tenido un problema: los redespliegues. No es algo exclusivo de estas herramientas, pero tener que reiniciar (o incluso redesplegar) un servidor con gran parte de los cambios es una pérdida de tiempo grandísima. Pronto detectamos que la gente hacía demasiados redespliegues. A menudo cada vez que algo no funcionaba se hacía un redespliegue o un reinicio, "por si acaso". Cada uno puede llevar uno o dos minutos como mínimo, y si vas sumando al final es mucho tiempo perdido, especialmente porque el "por si acaso" nunca sirve para nada. Para evitarlo, distribuimos los casos en los que, al menos con esta combinación de MyEclipse + SJSAS 8.2, es necesario hacer un reinicio o un redespliegue:
  • Si se añade, quita o modifica un método o atributo, o la declaración de una clase, el propio MyEclipse avisa de que es necesario reiniciar.
  • Si se modifican ficheros de JSF, Spring, Hibernate, Log4J, etc, es necesario reiniciar.
  • Si se modifica el web.xml, es necesario redesplegar.
  • En el resto de casos hacer otra cosa no servirá de nada. Si hay un problema, reiniciar o redesplegar no servirá de nada, así que ¡no lo hagas!
Para mitigar este problema se optó por orientar el desarrollo, hasta la capa de servicios, hacia las pruebas. Desarrollar orientado a pruebas no exige lentos reinicios o redespliegues de servidor, tan sólo relanzarla, que es mucho más rápido (aparte de las otras obvias ventajas).

El único problema grave que tuvo este cambio en sí (los problemas en la instalación fueron más sintomáticos que realmente costosos) fue el propio servidor. Casi nada (ni libreriás open source ni productos comerciales) tiene soporte para SJSAS. Todo se orienta a Tomcat y, si el producto es de JBoss, a su servidor. Comprendo que no es lo mismo para un administrador de un cluster de servidores Sun en producción tener SJSAS que tener Tomcat, pero para el desarrollador es un opción. Y desarrollar en Tomcat y después desplegar en SJSAS no es opción. Hay incompatibilidades, así, como suena. Basta con echar un vistazo a los foros para darse cuenta de ello.

Librerías del framework

Antes de desgranar los hechos por capas, debemos hablar en general del "lote" (JSF+Spring+Hibernate). Yo no soy ni mucho menos un experto en estas tecnologías, ni disponíamos de nadie con una gran experiencia en ellas, así que mi papel era conseguir dominarlas al máximo para poder solucionar los problemas que apareciesen. Ninguno de los programadores ni analistas tenía experiencia con ninguna de ellas. Por ello en estos dos años de investigación (creo que es como se debe denominar a esta tarea) he metido las manos en harina al máximo.
Para facilitar el cambio tomamos las siguientes medidas:
  • Inicialmente hicimos unas sesiones relámpago de introducción a estas tecnologías. Al menos deberían servir para responder a las preguntas "¿qué?", "¿para qué?" y "¿dónde me documento?" La pena es que sólo uno de los programadores que las siguió desarrolló con ellas en los siguientes meses (y además nos dejó en poco tiempo), por lo que cayeron en saco roto.
  • La contratación de nuevo personal se orientó a gente con experiencia en ellas o, al menos, con experiencia de años en diferentes tecnologías. Eso provocó alguna rotación indeseada, pero puso de manifiesto que es muy difícil conseguir personal realmente formado en tecnologías "avanzadas" de J2EE. Es difícil que a la llamada de "gente que sepa de Hibernate" aparezca gente, y aún en ese caso durante las entrevistas nos encontramos con muchos casos en los que en el CV aparecía dicha experiencia pero después no se sabía ni explicar qué era una LazyInicializationException.
  • Creación de wiki interno con documentación, FAQ, y guía de errores.
  • Todas las dudas se resolverían a través de un foro en vez de mediante teléfono o correos. De esta forma todo quedaría documentado.
Sobre la formación sólo puedo decir que no lo hicimos (o no lo pudimos hacer) como se debería. No dedicamos tiempo específico a formarnos, por lo que los problemas los ibamos resolviendo sobre la marcha. Tras esta experiencia me queda claro que todo el equipo debe conocer en cierta profundidad las tecnologías implicadas, especialmente Hibernate, incluso aspectos internos de funcionamiento. Es deseable que cada proyecto cuente con al menos una persona que realmente lo domine. Durante un desarrollo aparecen problemas complejos, no sólo errores, que no tienen una respuesta sencilla. Es fundamental contar con la capacidad de afrontarlos con solvencia. No sólo hablamos de problemas técnicos, sino también problemas de concepto. No podemos aumentar la produtividad sin aumentar la complejidad, aunque sí se puede reducir el coste. Utilizar herramientas avanzadas es la principal razón de aumento de la complejidad, y no se puede suponer símplemente que adoptando nuevas tecnologías se va a mejorar el proceso. Esta adopción requiere una gestión, especialmente en formación, y tiene un coste inicial. Y en este caso no basta con aprender sobre la marcha. Eso no es productivo. Es imprescindible pararase a aprender inicialmente antes de empezar a desarrollar.

Hibernate

Hibernate me sigue pareciendo sencillamente impresionante. Como con cualquier otra tecnología hay un coste de aprendizaje y todavía tiene algunos bugs y problemas, pero sigo opinando que no hay razón para no usarlo. Es una tecnología ya madura y contrastada.
Al emplear Hibernate hay dos problemas a solucionar: la formación del personal y problemas de integración con el SGBD específico. El primer punto está ya cubierto en el apartado anterior. Sobre el segundo, surgen problemas en la combinación de Hibernate y Oracle. El driver de Oracle, según los desarrolladores de Hibernate, está plagado de bugs. Es especialmente conflictiva la gestión de binarios (blobs, clobs...). Recomendaciones al respecto:
  • Lo primero es fijar el driver de Oracle. Localizar cuál es el que funciona en nuestro entorno (en los foros de Hibernate se habla al respecto) y agarrarnos a él sin soltarlo. Nada de actualizarlo.
  • Para solucionar los problemas con los blobs, Spring aporta el OracleLobHandler que te hace olvidar los bugs que aparecen al combinar Oracle con Hibernate.
Otras sugerencias aprendidas:
  • Usa Hibernate Validator para todas las validaciones de usuario. ¡DRY!
  • Usa Hibernate Annotations para configurar el mapeo relacional, mucho más cómodo que la configuración XML.
  • No te intentes adherir a EJB 3.0. Tiene limitaciones (consulta la documentación de Hibernate Annotations) con las que tarde o temprano te vas a encontrar.
Por último, en mi opinión, al contar con una herramienta así merece la pena cambiar la forma de afrontar la creación del modelo de datos. Tradicionalmente, el analista debe crear el modelo de datos para soportar los datos, el cual será transformado por el diseñador en un modelo físico de datos, un modelo de tablas y relaciones entre ellas que utilizará la aplicación. Sin embargo, esto ni es cómodo ni encaja bien a la hora de trabajar con Hibernate. Aunque los puristas supongo que me desollarán por lo siguiente, creo que hay que olvidar la creación del modelo de datos y pasar diréctamente al modelo de clases. No hagas diagramas. Haz diréctamente clases, y anótalas con @Entity, Hibernate hará el resto. Si puedes, utiliza claves surrogadas en vez de complejas claves compuestas. Con esto no quiero decir que no haya que tener en cuenta principios semejantes a los que se usan al crear el esquema de datos. Símplemente veo más operativo generar el esquema a partir de las clases en vez de trabajar en hacer el esquema y después verse encorsetado por él a la hora de programar.

Spring

No recuerdo ni un sólo problema real con Spring. Así como nuestra "guía de errores y excepciones" tiene infinidad de entradas en el apartado de Hibernate, ya que la transición de hacer SQL a mano a pasar a Hibernate es bastante compleja, la de Spring creo que está vacía. Usamos el módulo de IoC, el de seguridad, la gestión transaccional (programáticamente), y los añadidos que tiene para integración de otras librerías (Hibernate, servicios web...), al menos explícitamente. Ni siquiera la formación supuso un problema, ya que una vez se tiene organizado y configurado, basta con saber añadir e inyectar los beans en los xml para usarlo.
Es cómodo, útil, completo y maduro. Premia buenas prácticas y además aporta valor añadido, como publicación de servicios, inicialización de beans o planificación de tareas (mediante integración con librerías externas). Como queda claro, apuesta por la integración (lo cual queda claro cuando ves sus dependencias).
Lo único que lamento es la deficiente integración en el IDE (autocompletar es mejorable, escasa detección de errores) y que exija reiniciar el servidor al hacer cambios (cosa que tampoco ocurre tan a menudo).

JSF

Este no es el momento para criticar JSF, pero es imprescindible hacer una puntualización: JSF no es un framework completo, sólo es una base (mejorable) sobre la que usar otras cosas. Si pretendes usar sólo lo estándar, no estás comprendiendo su finalidad.
Optamos por MyFaces + Tomahawk + Sandbox + RichFaces + Facelets. Hacer funcionar todo esto sobre SJSAS 8.x no es una tarea trivial. 
  • Sobre la versión 8 del servidor no se puede usar JSF 1.2, estamos limitados a JSF 1.1.
  • El servidor de aplicaciones trae su propia implementación, y no usa la de la aplicación símplemente con incluirla. En el wiki de MyFaces hay más información al respecto.
  • Hacer componentes con "trozos de página", algo utilísimo para reutilizar código a nivel de vista, sólo con JSF es una tarea hercúlea. Como mínimo, tres clases más la configuración en el faces-config. Para mitigar esto hay que usar Facelets (imprescindible, creedme).
  • Facelets exige tener un taglib de las librerías usadas, no basta con el tld que ya tienen. De las librerías open source habituales hay taglibs disponibles, pero tenemos alguna librería propietaria que no lo incluye.
  • Nula gestión de excepciones.
  • Los errores a veces son crípticos. Facelets mejora algo esto, pero tampoco demasiado. Además, a veces aparecen problemas rarísimos de identificadores duplicados, solicitudes que se repiten, etc., sobre los que no hay respuesta clara.
  • Incompatibilidad entre navegadores. Lo habitual es trabajar en Firefox (por FireBugs y Web Developer Toolbar) y probar después sobre Internet Explorer, y es raro no llevarse sorpresas.
  • Olvídate de los editores gráficos. No merecen la pena. Ni para los ficheros de configuración, ni para las páginas, ni para nada. Codifica. Escribe cada línea de tu código, no pierdas el tiempo con vendedores de humo. Deja los editores gráficos para los diseñadores, los desarrolladores debemos manejarnos entre código.
Aún con todo esto, RichFaces me parece una buena razón para usar JSF. Uno de los objetivos del cambio es incorporar Ajax al interfaz, y la forma en la que afronta esta librería este problema es muy buena, la mejor posible en JSF. Sus componentes son buenos, pero ya sólo el a4j:support justifica su elección. Permite añadir Ajax a cualquier página JSF existente. "It just works". Nos hemos ido encontrando con bugs y problemas, pero el trabajo que se está haciendo en ella es muy bueno, y el soporte en el foro, también. Además, perfectamente documentado (en amplitud y profundidad), no como Dojo y otras tantas. Áltamente recomendable.

Pruebas

Las pruebas de una aplicación web de gestión tienen varios problemas intrínsecos: el estado de la base de datos, el perfil del usuario en sesión, y probar el interfaz.

¿Cómo podemos probar si una búsqueda filtrada paginar funciona si no sabemos si hay datos? La solución que hemos adoptado en estos casos es combinada. Por un lado, podemos consultar el estado actual de la base de datos. Por otro, modificamos su estado para hacer la prueba. Por ejemplo, ¿cómo saber si funciona el listado de 'tareas pendientes'? Primero consultamos las tareas pendientes de un usuario. Después hacemos una inserción que genere una tarea pendiente. Después hacemos otra consulta y comprobamos que hay una más de las que había antes. Por último, limpiamos lo insertado. Esto tiene dos problemas (al menos). La prueba es más compleja, aunque realmente no es un problema, porque como haremos una prueba de búsqueda y otra de inserción no tenemos más que programar una tercera que combine ambas, por lo que el coste de programar las pruebas apenas aumenta. Sin embargo, al hacerlo estamos metiendo una gran dependencia entre las pruebas, y eso es incorrecto.

Con el perfil del usuario el problema es similar. A menudo estamos obligados a asegurarnos de que existen usuarios con el perfil deseado, lo cual exige más control sobre el estado de la base de datos.

Tengo pendiente estudiar soluciones a este problema. Creo que TestNG y/o Unitils incorporan soluciones a esto, pero no he podido probarlo. De todas formas, siempre tendremos que especificar un estado concreto, con lo cual no estamos probando el sistema en cualquier caso, sino sólo en el especificado. Esto nos lleva a la discusión de cuánto probar, en la que no entraré en este momento :).

Para probar el interfaz por aquél entonces había alguna alternativa, pero demasiado costosas para mi gusto. BadBoy y Selenium añaden funcionalidad de prueba al navegador, pero preparar las pruebas sigue siendo costoso. Reciéntemente ha aparecido JSFUnit, que todavía no he podido probar.




Hasta aquí la exposición de los hechos de los últimos años. Ha acabado siendo un conglomerado de problemas, apaños (¿por qué usar el término 'workaround' teniendo alternativas propias?), opiniones y decisiones, pero en el fondo es de lo que se compone la experiencia diaria. Próximamente, las conclusiones, y seguro que otros posts que amplíen problemas aquí enunciados.

Espero con avidez los comentarios y críticas sobre todo esto. Estos dos años están siendo un proceso de aprendizaje del que esta entrada es sólo un paso más.

Posted by Juan Ignacio Sánchez Lara 16:04 Enlaces a esta entrada  



Diseñando una arquitectura (II/IV): Alternativas de solución

Estaba claro que la situación era mejorable. La industria llevaba años generando grandes productos que no se estaban aprovechando. Ahora era el momento de elegir e implantar.

II. Alternativas de solución

He de agradecer que se confió en mí plenamente -espero que no haya habido demasiados arrepentimientos sobre esto-. Se me exigió informes, pruebas de viabilidad, etc., pero la libertad de la que disfruté fue máxima. Se mantuvieron las siguientes restricciones:
  • El entorno sería J2EE. Java es con lo que se trabaja en todo el departamento, y así iba a seguir siendo. Esto favorece la movilidad de personal, facilita la formación, la reutilización de código, etc.
  • El SGBD sería Oracle. Es lo que se ha venido usando siempre, es de lo que se cuenta con personal cualificado, soporte, etc.
  • El servidor de aplicaciones sería el Sun Java System Application Server 8.1. Esto viene impuesto por la superorganización.
Entorno de desarrollo
Lo primero fue cambiar el entorno de desarrollo. Se venía usando JDeveloper por inercia, por ser lo utilizado en la superorganización, pero no respondía a ninguna restricción real. La principal razón a la que nos agarramos para el cambio fue el servidor de aplicaciones. El JDeveloper integra OC4J y no había forma de hacerlo funcionar contra el SJSAS 8, que era lo deseable. Además, para cualquiera que haya usado otro IDE el OC4J es antediluviano. Aunque sobre el papel las características sean similares, en el día a día deja mucho que desear.
La política de la empresa es tender hacia el Open Source y a evitar gastos innecesarios, así que se barajó Eclipse y NetBeans. El primero es al desarrollo como Firefox a los navegadores: cuenta con infinidad de plugins útiles. El segundo, sin embargo, tiene un killer, Matisse. Una buena parte del desarrollo se hace en aplicaciones standalone de escritorio, con swing, y al parecer Matisse es infinitamente mejor que otros diseñadores gráficos. Yo ni los había usado ni los iba a usar, y la decisión no me correspondía. Los responsables de ello lo querían a toda costa, pero también deseaban Eclipse, debido a ciertos plugins. Tras descartar usar dos entornos diferentes, se optó por MyEclipse. Este entorno es Eclipse con ciertas mejoras desarrolladas específicamente para él, e integra Matisse, por lo que era una solución ideal. El coste es muy bajo y las primeras pruebas resultaron satisfactorias, así que fue el elegido. Eso nos permitió trabajar con el servidor adecuado, además de disfrutar de todo lo que se desarrolla para él.

Persistencia
Hibernate me parece LA razón para desarrollar en Java. Es potente, flexible, completo, eficiente... Desde que lo usé por primera vez no se me ocurre comenzar un desarrollo sin él. Escribir SQL por defecto me parece algo totalmente atrasado e indeseable. Está claro que en ciertas ocasiones es lo mejor y se debe recurrir a ello, pero la potencia de poder guardar y recuperar árboles de información completos sin necesidad de escribir una consulta es inigualable. No sólo por el hecho de escribir las consultas, sino porque el no tener que escribirlas hace que no haya que modificarlas ni mantenerlas nunca. Esto, que parece perogrullo, no lo es. Si has escrito las consultas, un cambio en el modelo es dramático. Hibernate hace que ni siquiera sea necesario pensar en el modelo de datos. Piensa en el modelo de clases, piensa en términos de objetos, que es lo que la aplicación va a manejar en último término.
A día de hoy la aplicación que ha servido de arranque a esta nueva infraestructura gestiona datos de unas 140 tablas de varios esquemas, tanto propios como comunes. Sin Hibernate esto no habría sido posible.
Toplink es una alternativa similar, pero por lo que pude leer, más limitado. Se ciñe más al estándar (o el estándar a él), asumiendo ciertas limitaciones que Hibernate se salta mediante extensiones propias.
Hay otros motores diferentes que también son viables, notablemente iBatis. Sin embargo, la productividad que se obtiene no tiene nada que ver.

Unido a Hibernate se adoptaron otros proyectos hermanos: Hibernate Validator e Hibernate Annotations. El primero permite definir validaciones mediante anotaciones en los modelos, y el segundo, incorporar la configuración de persistencia en los propios modelos.

Middleware
Por aquél entonces la elección natural era Spring. Era ya un framework completo, estable, probado... Google sacó su Guice más tarde, y Seam acababa de nacer. Spring nos resolvería la organización de la capa de lógica de negocio, simplificaría las pruebas, servicios web...
El uso de Spring nos llevó además al uso de Acegi (ahora llamado Spring Security) como sistema de seguridad. Este, a su vez, a instalar un servidor CAS. Todo esto nos ha permitido implantar un sistema de single sign on del que se llevaba hablando mucho tiempo.

Pruebas
Con las pruebas tiramos por lo directo: JUnit 4. Había oído hablar de otras alternativas, pero hasta la fecha en la organización no se programaban pruebas en absoluto, así que nos contentaríamos con que consiguiésemos acostumbrarnos a usar este sistema con cierta soltura.
Adicionalmente pronto vimos que sería conveniente el uso de Unitils. Por aquel entonces Spring no soportaba JUnit 4 correctamente, y esta librería facilitaba la inyección de los beans.

Vista
Otra de las grandes justificaciones para el cambio fue la introducción de Ajax, como valor añadido para los usuarios. De nada nos serviría hacer mejor "las tripas" de la aplicación si el usuario no veía novedades.
IMHO (como siempre ;) ) si piensas en Ajax en Java tienes que pensar en JSF. Al menos por aquél entonces. En mi opinión, el planteamiento de orientación a componentes de JSF lo hace perfecto para esa tecnología. Para explicar esta opinión, siempre hablo de Struts como división "vertical" y JSF como "horizontal". Lo natural es que una solicitud en Struts vaya a un Action que realice un procesamiento y muestre una página (imagino esta generación del código como un proceso de arriba a abajo).  En JSF, sin embargo, "trozos (horizontales) de página" tienen entidad propia. Tienen comportamiento y orígenes de datos propios. Está claro que con ambos sistemas se puede hacer, y de forma correcta, pero por aquél entonces parecía que lo más adecuado era JSF.
Como implementación del estándar se optó por MyFaces, debido principalmente a que un componente (que posteriormente se descartó), FCKFaces, dependía de él. Sobre MyFaces usamos también Tomahawk y Sandbox, que incorporan componentes interesantes. Pronto quedó claro que Facelets era una decisión obligada al hacer JSF (aunque nunca he dejado de echar de menos Tiles, que junto al Validator me parecían la verdadera razón para usar Struts). Para hacer pseudocomponentes con "trozos" de páginas es muy útil, y también para organizar las páginas como plantillas (aunque no es ni de lejos tan potente como es Tiles). Todo esto estamos hablando de JSF 1.1, debido a la versión del servidor.
La gran duda vino a la hora de elegir la librería Ajax. Tras dar tumbos entre varias opciones quedó claro que había dos grandes contendientes: Ajax4JSF (con RichFaces) e ICEFaces. ICEFaces tenía un conjunto de componentes mayor, más completo. Por el contrario, Ajax4JSF me parecía más flexible. Ambos tenían una intensa actividad. El ritmo de mejoras de Ajax4JSF parecía mayor, debido principalmente a sus obvias carencias respecto a la competencia (ni tenía un componente de calendario por aquél entonces). Ambos estaban bajo la tutela de JBoss, así que la continuidad parecía garantizada. A la hora de probarlos, éste no me dio ningún problema al combinarlo con otras librerías, mientras que ICEFaces sí. Al ser incompatibles entre sí, opté por el primero, aunque ICEFaces seguramente también habría sido una decisión válida. Para las cosas en las que estas librerías se quedaban cortas las completamos con componentes hechos con Facelets encapsulando código de Dojo.

Por tanto, íbamos a pasar de JDeveloper con OC4J y servlets a la vieja usanza a MyEclipse sobre SJSAS 8.1 y Oracle, desarrollando con Hibernate, Spring, JUnit, JSF y Ajax4JSF/RichFaces. Está claro que el cambio iba a ser grande. En la siguiente entrega iremos recapitulando sobre los problemas que nos han aparecido al hacerlo, los aciertos y los errores.

Posted by Juan Ignacio Sánchez Lara 0:24 Enlaces a esta entrada  



Diseñando una arquitectura (I/IV): Estudio de la Situación Actual

Hace aproximadamente año y medio me embarqué en lo que está siendo ha sido mi experiencia profesional más compleja, importante e interesante: mejorar la forma de desarrollar aplicaciones web de una organización. Es un buen momento para mirar atrás.

Lo haré en cuatro entradas:
I: estudio de la situación actual (actual por aquél entonces, claro).
II: selección de las alternativas de solución.
III: implantación de la solución.
IV: conclusiones.

0. Antecedentes

En los últimos años había estado trabajando con tecnologías J2EE, tanto profesionalmente como "en casa", para proyectos propios. Anteriormente había hecho alguna cosa en PHP, y me gustaba mantenerme al día de las novedades de la industria (RoR, Phyton...), aunque no le pudiese dedicar tiempo en profundidad. En general, todo para, en mayor o menor medida, aplicaciones de gestión de datos (quien esté buscando sistemas de tiempo real o simuladores aeroespaciales me temo que tiene que cancelar su suscripción a este sitio).
De esta experiencia formé una serie de axiomas que suelo tomar como ciertos (aunque al estudiar informática la conclusión que te queda es que la única respuesta que siempre es válida es 'depende'):
  • La separación entre capas es una Cosa Buena:
    • Debe haber una capa de acceso a datos "tonta", que no tome decisiones y que símplemente sirva para acceder a bases de datos. Debe tener esencialmente 4 métodos (buscar, insertar, actualizar y borrar), salvo añadidos por eficiencia.
    • La capa de lógica de negocio, por encima de la de datos y por debajo de la de presentación, es en la que se programa todo lo que aparece en las especificaciones, desde el flujo de la aplicación al control de datos ("quién puede ver/editar qué en cada momento").
    • Las dependencias van hacia abajo, los datos hacia arriba.
  • No te repitas (DRY).
    • Corolario: no cortapegues (mejor: ¡¡NO CORTAPEGUES!!).
  • Para aplicaciones pequeñas, PHP o RoR o similar, para aplicaciones grandes, J2EE.
    • Por favor, no empecemos un flamewar aquí. Ya sé que Flickr, por ejemplo, es PHP y un montón de ejemplos más. Sin embargo, intenta hacer consumir a algo que no sea Java o .Net unos cuantos servicios web de terceros y verás lo "estándar" que son. Sí, con PHP puedes hacer OO y otro buen montón de buenas prácticas, pero si ya es difícil mantener el código bajo control con Java, no quiero ni pensar lo que ocurre con otros. Por no hablar de las herramientas, claro... Fin del tema :). Para discutir sobre esto, otro día :).
  • Hacer páginas con etiquetas es bueno (claridad, uso de librerías de componentes...), meter código Java en las JSPs es malo: inmantenibilidad, dificultad para trazar errores...
  • Ajax es bueno, hecho con Javascript a mano puede no estar mal, pero si tienes una librería que te lo proporcione es mucho mejor.
    • Esto tiene un corolario: ajaxificar los datos (posiblemente) es más eficiente, ajaxificar el interfaz es (posiblemente) más productivo. Escribir Javascript a mano (o con con Dojo, por ejemplo) suele llevar a hacer solicitudes Ajax que devuelvan datos. Esto consume menos recursos. Sin embargo, usar librerías de servidor (Ajax4JSF, ICEFaces...) suele llevar a que lo que se solicita son "trozos del interfaz". Esto no es siempre cierto (GWT, por ejemplo, es una excepción) pero era lo más habitual por aquel entonces.
I. Estudio de la situación actual

Corrían finales de 2006. Struts (Action, 1) comenzaba a ser considerado demodé, y Ajax era lo que tenías que decir en una entrevista si querías atraer la atención. JSF seguía con su mala salud de hierro, como ahora. Una miríada de frameworks web (Spring Web, Wicket, Web Works, Tapestry...) esperaban que comenzase a morir de verdad para regodearse sus despojos. Microsoft, tras la guerra con Sun, había publicado .NET, y la pregunta entre todos los encorbatados era ¿J2EE o .NET?. Dojo era la librería Javascript por excelencia, con sus estándares de no documentar (y si documentas, hazlo mal, sin actualizar y sin completar). Si querías mantener una conversación geek tenías que saber que lo cool era Ruby On Rails, que Google había roto todas las convenciones con GWT.

Al llegar a la nueva organización me encontré con una situación... poco habitual. Mientras el resto del mundo se empeñaba en optimizar la productividad y mejorar la calidad del desarrollo mediante librerías Java, o diréctamente renegaban del mundo J2EE para salir a otras alternativas, allí se seguía desarrollando como hablaban los manuales de 5 años atrás: servlets y JSPs (¡o sólo JSPs!). Estamos hablando de un entorno con grandísimas restricciones y los responsables de la arquitectura de las aplicaciones estaban en gran medida con las manos atadas. La superorganización (la casa matriz, la "nave nodriza", aquellos de quien dependíamos) imponía su ley (muchos, en mi modesta opinión, debidos al síndrome NIH), con sus problemas:
  • Desarrollo con una versión bastante antigua de un IDE:
    • El cliente CVS era muy malo y problemático. Eso no era un problema para la superorganización porque ellos no usaban ningún repositorio de código para trabajo compartido (así hasta el 2008, increible pero cierto), pero sí para nosotros, y eso nos hacía tener que usar un cliente externo.
    • Desarrollábamos sobre el OC4J integrado, que no era el de producción.
  • Servidor propietario, por lo que al no ser libre apenas hay documentación ni soporte sobre él.
  • Uso de framework propio:
    • Clases que generan código html (había que hacer cosas como new DropDown() en las jsps).
    • Diseño en una capa (todo en JSPs), llegando al extremo de programar SQL en las JSPs.
      • Aquí hay que decir que en la organización se hizo un diseño MVC que simulaba la estructura de Struts, de forma que nuestras aplicaciones sí seguían dicho patrón (aunque las de la superorganización no).
    • Wrappers para clases existentes (un envoltorio, por ejemplo, para Connection, que impide obtener el objeto propiamente dicho. En resumen, envoltorios limitados de clases existentes.
    • No disponíamos del código fuente.
    • Documentación sin actualizar.
    • Ninguna librería "estándar": ni siquiera Log4J, así que ni hablar de cosas como Hibernate, Struts, Commons-X...
    • Dependencia (oculta, sin documentar), de variables de sesión.
    • Las aplicaciones sólo funcionaban en Internet Explorer.
Estas restricciones habían llevado a otras malas prácticas adicionales:
  • Se repetía muchísimo código, por una mezcla de los problemas y restricciones impuestos y descuido propio. Ejemplos:
    • Las clases de acceso a datos tenían tantos métodos de consulta como páginas, así que la separación entre capas era pobre.
    • Cortapega entre páginas en vez de inclusión.
    • Cortapega entre clases en vez de agregación o herencia.
  • Muchas validaciones de datos de usuario (sólo) en Javascript.
Como podéis imaginar, la situación actual chocaba frontalmente con mi visión del desarrollo de aplicaciones web (y de la informática en general). Conviví con todo esto en el desarrollo de una aplicación, en papel de analista. Es cierto que las cosas iban saliendo así, pero no creo que esta fuese la mejor forma de hacerlo:
  • Se genera código de mala calidad, inmantenible. Seguramente este problema habría sido mucho mayor de no ser porque la naturaleza de muchas aplicaciones desarrolladas era casi de usar y tirar, con un ciclo de vida muy corto (uno o dos años de vigencia). Sin embargo, por ejemplo, la aplicación con la que comencé ya está sufriendo estos problemas. Comenzó con el objetivo de ser una aplicación pequeña y simple y desarrollada rápidamente, y las mejoras que se le están metiendo están provocando problemas que no tendríamos con otro tipo de desarrollo.
  • Todo se hace a medida para cada ocasión (lo más sangrante es escribir una SQL para cada situación, un simple cambio de nombre de una columna podía llegar a ser un cambio dramático).
Tras esta primera aplicación se me dio la oportunidad de hacer una propuesta de un diseño nuevo, una nueva arquitectura para nuestras aplicaciones partiendo de cero, una nueva forma de trabajar. Este será el contenido de los siguientes posts. Como anticipo del último, puedo decir que estoy satisfecho con las decisiones tomadas, pero no del todo con los resultados, así que hay que recapitular en qué cosas hemos hecho mal. Podéis también ir imaginando el contenido del post siguiente al último ;).

Posted by Juan Ignacio Sánchez Lara 10:15 Enlaces a esta entrada  



Google Chrome: primeras pegas

Micropost con las primeras pegas:

  • Obviamente no soluciona el handicap de que Windows esporádicamente se congele y no puedas ni moverte entre ventanas, por mucho que sean procesos independientes.
  • No es Firefox, así que no tienes las extensiones. De hecho, por ahora no admite extensiones.
  • No encuentro que se pueda ver a pantalla completa. Ni F11, ni CTRL/alt/shift+f . La ayuda no devuelve nada por "pantalla completa", ni la lista de atajos.
  • A priori me gustaba más el uso de motores de búsqueda de Firefox, con CTRL+arriba/abajo. De las opciones existentes la primera no me convence porque me exige poner el nombre del buscador, y la segunda porque me obliga a personalizar y aprender palabras clave. Habitualmente tengo unos diez motores, no más, y moverme entre ellos con el cursor es suficientemente rápido.
Un último apunte:
  • Con Shift+Esc se puede ver el administrador de tareas, para gestionar los procesos. En estos momentos GMail me consume 31MB, lo mismo que el incremento que noto en Firefox cuando lo abro.
PD: mil perdones a los que se han ofendido por el spam en meneame ;)

Posted by Juan Ignacio Sánchez Lara 21:47 Enlaces a esta entrada  



Google Chrome: segundas impresiones

Segundas impresiones


1.- La tendencia a quitar el tradicional menú de opciones me descoloca, son muchos años conviviendo con él. La solución que aportan las aplicaciones de Microsoft, que aparezca al pulsar Alt, me sabe a chapuza, y me parece que las ventanas son poco más que skins. Chrome ha optado por botones en un lateral. Más elegante, pero hay que acostumbrarse para no tener que buscarlo. La ganancia en limpieza merece la pena, de todas formas.
2.- El historial es una pestaña, las descargas otra... y todas con buscadores.
3.- Las opciones no dan mucho de sí. Las mínimas e imprescindibles. Menos que Firefox o Internet Explorer, muchísimas menos que Opera.
4.- La sensación es "Safari meets Google": apariencia limpia, eficiente.
5.- Han respetado los atajos de Firefox :).
6.- La omnibox muestra resultados más elaborados que la tradicional sugerencia ordenada alfabéticamente. Supongo que cuanto más se use, más útil será.
7.- nhpatt, un amiguete, me sugiere esta prueba: http://nontroppo.org/timer/progressive_raytracer.html.  Chrome acaba el full render en 19.22 segundos, Firefox en 667 (habría que hacer muchas pasadas para ser estrictos, pero nos permite hacer una idea del orden de magnitud de la mejoría). Por supuesto, el resto de pestañas en Firefox no están operativas, mientras que en Chrome sí. PD: nhpatt me pasa una media, tras 10 pasadas, de unos 14.8 segundos, con poquísima desviación (menos de un segundo). La media de Opera en esas condiciones es de 17 segundos aproximadamente.
8.- Me ha importado la configuración de buscadores personalizados (lo uso muchísimo), hasta el punto de que el omnibox me está usando un traductor para buscar. He tenido que editar la configuración de buscadores. El método del Firefox de alternar entre ellos pulsando ctrl me parecía comodísimo, lo que cuentan en la ayuda no me parece tan claro. Ya veremos...

PD: conclusiones de hoy:

Mientras era (probablemente justamente) trolleado en meneame (por autopostear una noticia basada en los primeros cinco minutos con una herramienta) he seguido probándolo y va realmente bien. Ningún problema con ninguna página. Estoy con el video de la presentación, mientras abro de golpe unas veinte pestañas (10-30MB cada una), y todo funciona maravillosamente bien. Esto son sólo unas primeras impresiones, pero no pueden ser mejores (con la salvedad de los motores de búsqueda, estaba muy cómodo con los de Firefox, hay que ver los nuevos más en profundidad).

Posted by Juan Ignacio Sánchez Lara 20:33 Enlaces a esta entrada  



Primeras impresiones con Google Chrome

Primeras impresiones:

  1. Se ha descargado e instalado sin problemas en un visto y no visto, importando mi configuración de Firefox.
  2. Tengo tres pestañas (la de inicio, la de presentación y esta con blogger), y 4 procesos. En total consumen aproximadamente 95MB. Firefox, con lo mismo, 60MB. En el comic ya advertían que el modelo una pestaña-un proceso tendría más sobrecarga inicial. A mí me vale si no acaba ocupando lo que ocupan el resto (¿he oído Internet Explorer?) una vez he cerrado todas.
  3. El look de las ventanas es Vista... pero optimizando. Nada de bordes laterales o inferiores, y las pestañas se colocan en la barra del título, que es más pequeña que la estándar en XP. Muy limpio.
  4. La página de marcación rápida contiene tanto enlaces frecuentes como las últimas búsquedas.
  5. El Organizr del Flickr va MUY rápido, y se nota que no provoca que el resto del navegador se arrastre... El Javascript es la clave y la razón de ser de Chrome, está claro...
  6. Moverte entre pestañas no es rápido, es instantáneo.
  7. El Flash funciona desde el primer momento. La página del Marca nunca ha estorbado menos.
Esto para abrir boca, en breve, más...

Posted by Juan Ignacio Sánchez Lara 20:22 Enlaces a esta entrada  



Google Chrome: el sistema operativo de la web

Todos sabemos que un navegador no tiene nada que ver con el concepto tradicional de sistema operativo, pero si las aplicaciones siguen la tendencia de ponerse en la web el navegador será la plataforma de ejecución de nuestras aplicaciones.
Ese es el motivo por el que Google (va a) publica(r) Chrome, y lo dejan entrever en la página 4 del comic promocional: "we're applying the same kind of process isolation you find in modern operative systems".
El comic enseña otras cosas interesantes:

  • Al compilar el navegador un bot lo prueba contra "millones de páginas". ¿Os imaginais unas pruebas que tengan como entrada posible la web entera las n millones de páginas más usadas?
  • Han hecho una máquina virtual Javascript que es un compilador JIT a código máquina.
  • La 'omnibox': aplican el conocimiento aprendido de cómo la gente usa el buscador para renovar cómo funciona la barra de urls. Tiene pinta de ser terriblemente simple y terriblemente útil.
  • Modo "sigiloso" para no dejar traza de lo que se hace.
  • Colleja al modelo de seguridad de Vista, que permite leer hacia arriba en los niveles de seguridad, a pesar de lo sensible que sea la información. Chrome, sin embargo, no se basará en niveles predeterminados, sino en lo que el usuario solicita explícitamente. De nuevo se comparan con un SO, no con un navegador.
  • Aislamiento a los plugins en un proceso aparte.
  • Listas negras.
  • Las mejoras desde el punto de vista del desarrollador las van a seguir integrando en Google Gears, que Chrome incorpora. Así, este puede que vaya a ser el mejor navegador, pero Gears seguirá mejorando todos. Pero claro, si Chrome ofrece un rendimiento que los otros no tienen, o mejoran o Gears se arrastrará en ellos...
  • En la página 36 dejan claro que creen en el Open Source, no en los estándares (al menos no como "unificadores"). Traducción personal: "los estándares son una forma de ayudar a todos los navegadores a ser mejores. El equipo ha hecho cosas interesantes en velocidad, estabilidad, interfaz de usuario, como la nueva página de pestañas. Algunas se pueden convertir en estándares, otras no. Pero como todo es open source, los desarrolladores de los otros navegadores pueden coger lo que quieran".
    • En mi opinión esto es cierto... en parte. Si se "desestandariza" lo que hacen los navegadores (en la práctica eso ocurre), las páginas no se comportan igual. Sin embargo, IMHO es el planteamiento correcto. Los estándares, en la práctica, son lentos y sometidos a burocracia e intereses particulares.
A ver qué nos depara... Leer el comic me ha dado una gran envidia. ¡Cómo debe ser trabajar en Google ampliando los límites de la web en vez de maltrabajar con sus limitaciones!

Posted by Juan Ignacio Sánchez Lara 18:53 Enlaces a esta entrada