Feb 28

Tutorial de JTree

Aunque llevaba con él en mente desde hace tiempo, me ha costado empezarlo. Parece que ya va adelante.

Acabo de hacer un primer tutorial de uso sencillo del JTree. Tengo intención de continuarlo con otro tutorial más sobre cómo cambiar el aspecto del JTree (supongo que estará entre hoy y mañana) y ya veremos a ver si puedo sacarle jugo para hacer algún otro más.

Los siguientes pasos no sé muy bien qué hacer.

Por un lado veo en la Chuwiki que los temas de Jasperreport y de J2EE tienen bastante éxito. En poco tiempo se han puesto en las primeras posiciones de los más vistos de la wiki. Me apetece por un lado añadir algún tutorial más sobre el tema (jsp, instalación de tomcat, etc), pero es un tema que desconozco, así que puede ser una tarea lenta. Por otro lado, aprenderé cosas nuevas. Además, cuento con la colaboración de Pete.

Por otro lado, tengo varios tutoriales más sencillos en mente, por ejemplo, dentro de la parte de diseño orientado a objetos querría meter en algún momento un grupo de tutoriales en el que se expliquen pequeños tips para la programación orientada a objetos, el uso de refactoring con eclipse, etc. También tengo que arreglar y ampliar el java con mysql, o el ejemplo del chat con java. Tengo la librería gráfica pendiente de ampliar un poco…

Vaya, una trabajera en cualquier caso, pero que ire haciendo poco a poco, en cada caso lo que me parezca más entretenido.

Feb 27

Currito avanzado

Últimamente ando algo despistado con esto de la programación. Ni escribo en el blog, ni hago tutoriales ni nada de nada.

El problema es que en el trabajo nos han reorganizado. No sé muy bien todavía dónde he caído ni exactamente ni lo que tengo que hacer, porque estamos acostumbrados a organizaciones secretas, en las que cuatro jefes se reúnen, deciden cómo nos van a organizar … y luego no dicen nada a nadie. No sería la primera vez que cambiamos de jefes y nadie nos dice nada. Lo sabemos por radio-macuto o porque de repente alguno de ellos se pone a organizar y entonces pensamos… "debe ser nuestro nuevo jefe". Luego igual el sueldo te lo sube otro o el que se cabrea si no le avisas de que te coges unos días libres es un tercero. ¿Será que al final han decidido que todos son jefes?

Yo por mi lado sigo con lo mismo que estaba antes, con otra persona tratando de sacar adelante un proyecto que además quiero que nos sirva para futuros proyectos. Encantado con la nueva forma de codificar con poco diseño y mucho refactoring.

Pero por otro, parece que pretenden que deje ese proyecto y me dedique a otras labores más de supervisión y de menos código (me han debido ascender de currito de decimotercera clase a currito avanzado, aunque todavía no lo tengo muy claro).

Pero veo varios peros…

Por un lado lo que se supone que debo supervisar es algo que ya está en gran parte hecho y en lo que no he participado, con lo que me va a llevar tiempo meterme en el ajo y además no sé que hay que supervisar después. Aunque queda todavía una gran parte sin hacer, posiblemente siga sólo por inercia sin que nadie supervise nada.

Por otro lado, el proyecto en el que estaba tiene pruebas dentro de tres meses, pero todavía no me has puesto sustituto ni nadie que lo lleve. Me da cosa dejar sin más el proyecto huérfano, más que nada por el cariño que le había ido cogiendo a la forma de trabajar de menos diseño y más refactoring, y por que sigo pretendiendo que eso se pueda reaprovechar más adelante.

En fin, que así ando, dándole vueltas a la cabeza y "sufriendo" las organizaciones secretas de la empresa. Supongo que al final lo que realmente pasa es que se fían de mi capacidad infinita de liar a los que curran de verdad, meter las narices en todos lados y no hacer nada, pero estar metido en todo.

Feb 22

Metodologías ágiles y refactoring

Hace tiempo comenté que iba a empezar un proyecto en el trabajo, con la ambición de que fuera reutilzable en otros proyectos similares. En aquel post comentaba que como ando últimamente un poco desencantado con el diseño global desde el principio, decidí ir haciendo pequeñas iteraciones, con un pequeño diseño sólo para esa itración, codificación sólo para esa iteración y mucho refactoring en las siguientes iteraciones.

Bien, ya llevo unos meses con ello, dos meses largos.

La experiencia la verdad es que está siendo buena. Cojo un pequeño tema a implementar, me pienso un pequeño diseño para ello, hago el esqueleto, las clases de test de JUnit, entre otras personas y yo vamos rellenando código rápido y sin complicarnos la vida con generalidades hasta que funciona.

Luego cogemos otro tema, hacemos refactoring sobre lo ya hecho para aclopar el nuevo tema, más clases de JUnit y a codificar y así sucesivamente.

Las primeras iteraciones fueron un poco fustrantes. Estoy acostumbrado a tratar de hacer código general, tratando de que quede bien organizado desde el principio. El hacer código pensando sólo en lo que tengo que hacer en el momento y sin complicarlo, desde luego va más rápido, pero te queda la cosa de "esto podría estar mejor si lo hiciera más general".

Sin embargo, según vamos iterando y añadiendo funcionalidad, al hacer refactoring, las clases se van generalizando solas, el diseño bueno va surgiendo solo y además, estoy empezando a pensar que el diseño ha quedado mejor y más claro así que si hubiera pensado al principio un diseño general para todo.

Se pierde tiempo en el refactoring, pero también es cierto que al principio de cada iteración, se hace refactoring para acomodar la nueva funcionalidad y luego se implementa rápidamente. Las clases de JUnit junto con maven son además una maravilla. Cualquier metedura de pata en ese refactoring canta enseguida.

Otro detalle para pensar es ¿quién hace test de las clases de JUnit?. Al hacer el test antes que la clase, no hay forma de probar el test. En más de una ocasión hemos visto que la clase está bien implementada, pero el test inicial estaba equivocado y hemos tenido que corregirlo.

Resumiendo, a pesar de los pequeños peros, estoy encantado con esta nueva forma de trabajar. La cosa va más o menos rápida, con entregables cada poco tiempo (unos quince días) y las clases me asombra lo bien que se van organizando solas.

La pega de las entregas frecuentes, es que el reporte de bugs también te viene de muy pronto…

Feb 21

Password segura

Tengo un compañero que no solo no ha puesto la password más segura del mundo, sino que además se arregla para que cuando la introduce, a pesar de sólo verse asteriscos, se arregla para que la sepas.

Incluso aunque estés delante de él viéndole, introduce su nombre de usuario y, directamente, ¡¡ copy-paste del nombre de usuario sobre el campo de password. !!

Feb 20

Refactoring con eclipse

Sabía desde hace tiempo que eclipse tiene diversas opciones de "refactoring", opciones que nos permiten modificar fácilmente el código para hacelo más legible, diseño más claro, etc.

La primera opción tonta es la de renombrar o mover una clase entera de sitio. Sobre la clase le damos al botón derecho del ratón para sacar el menú, "refactor" y "move" o "rename". La ventaja de hacerlo así es que eclipse nos revisa el resto de las clases del proyecto y nos cambia automáticamente los import y el nombre de la clase donde aparezca.

Otra que uso mucho es la de extraer un método. Seleccionas varias líneas de código, botón derecho del ratón, "refactor" y "extract method". Si se puede hacer fácilmente, eclipse nos crea el método y nos cambia el código para que haga una llamda a ese método. Si el asunto no es trivial, tenemos que ayudarle un poco.

Otras muy útiles también es el de "convert local variable to attribute" o "extract constant". En el primero selecionando una variable y en el segundo un valor fijo (numérico o cadena de texto), eclipse nos crea un nuevo atributo o constante en la clase y reemplaza todas las apariciones en el código de esa clase.

Otro muy maravilloso es el cambiar la "signatura" de un método. Seleccionamos el nombre del método, botón derecho, "refactor", "change signature" y podemos ponerle o quitarle parámetros. Eclipse revisa todo el código para arreglar las llamadas. Este es muy útil cuando vemos un método que ha dejado de usar uno de los parámetros que en principio se le pasaban. Lo podemos hacer desaparecer de un plumazo.

Y otro que he descubierto hace poco. Podemos mover un método de una clase a otra clase. Para que eclipse sepa hacerlo, la clase destino debe ser atributo de la clase origen, de forma que pueda reemplazar las llamadas a ese método por una llamada al método del atributo. Me explico, si la clase A tiene el metodo() y en algún sitio lo llama, debemos hacer una clase B que sea atributo de A. Al mover el método de A a B, eclipse nos cambiará las llamadas de metodo() por b.metodo().

Estas son las que recuerdo así por encima y que suelo usar. Es posible que me haya equivocado en los nombres de los menús (los puñeteros están en inglés), pero de todas formas es algo que merece la pena conocer, investigar y sacarle provecho. Puede ahorrar mucho trabajo y ayudarnos a dejar el código más limpio.

Feb 18

La belleza de las matemáticas

1 x 8 + 1 = 9
12 x 8 + 2 = 98
123 x 8 + 3 = 987
1234 x 8 + 4 = 9876
12345 x 8 + 5 = 98765
123456 x 8 + 6 = 987654
1234567 x 8 + 7 = 9876543
12345678 x 8 + 8 = 98765432
123456789 x 8 + 9 = 987654321

1 x 9 + 2 = 11
12 x 9 + 3 = 111
123 x 9 + 4 = 1111
1234 x 9 + 5 = 11111
12345 x 9 + 6 = 111111
123456 x 9 + 7 = 1111111
1234567 x 9 + 8 = 11111111
12345678 x 9 + 9 = 111111111
123456789 x 9 +10= 1111111111

9 x 9 + 7 = 88
98 x 9 + 6 = 888
987 x 9 + 5 = 8888
9876 x 9 + 4 = 88888
98765 x 9 + 3 = 888888
987654 x 9 + 2 = 8888888
9876543 x 9 + 1 = 88888888
98765432 x 9 + 0 = 888888888

1 x 1 = 1
11 x 11 = 121
111 x 111 = 12321
1111 x 1111 = 1234321
11111 x 11111 = 123454321
111111 x 111111 = 12345654321
1111111 x 1111111 = 1234567654321
11111111 x 11111111 = 123456787654321
111111111 x 111111111= 12345678987654321

Nada que comentar. Visto en Kinky Collections.

Feb 18

Programador torpe, programador estándar y programador astuto

Me he tropezado con tres tipos de programadores

Programador torpe:

Este programador, normalmente trabajador y bienintencionado, es al que el mandas hacer un programa de "asar castañas" y se pone a ello. Tarda mucho en hacerlo, pregunta cosas a todo el mundo porque no se aclara con su propio código ni tiene los conocimientos suficientes. Después de un tiempo largo te da el código ya hecho y quieres integrarlo en tu sistema de asadores de cosas. Miras y sólo ves un main(), con un código spagueti infumable. Arrancas el main() … y falla, ni siquiera arranca. El programa busca algo en c:\documents and settins\programador torpe\fichero configuracion.txt. Cuando pones el fichero, la resolución de pantalla no es la misma, así que no se ve nada y salta un excepción en no sé qué sitio.

Más adelante le encargas el programa de "asar peras". El programador copia su código, se pone a cambiarlo, no le funciona, sigue cambiando, tarda más que con el primer programa que empezó de cero y cuando termina, le das peras para asar y te devuelve castañas quemadas.

De estos no hay muchos y suelen acabar haciendo cosas ajenas a la programación (suelen ascender a jefes, por ejemplo).

Programador estandar:

Este programador suele ser competente y tiene conocimientos adecuados. Le encargas el programa de asar castañas y en un tiempo razonable, supongamos un mes debido a la complejidad inherente a la castaña, te devuelve un programa que funciona razonablemente bien. Luego le mandas el de asar peras. hace copy-paste, cambia castañas por peras, la temperatura del horno y en quince días te devuelve el programa funcionando bien. Luego le mandas el de asar nueces. Otro copy-paste, otros quince días y listo. Lo mismo para el de asar manzanas, el de asar pavos (este tarda un poco más, porque el pavo es más grande que la castaña) y así eternamente. En algún momento hace alguna función común que le evita parte del copy-paste, pero el código de estas funciones comunes puede ser un 5% del total y con ellas apenas ahorra un día de trabajo.

En este grupo suelen estar el 80% de los programadores.

Programador astuto:

Este también es competente. Le encargas el programa de asar castañas y al igual que el estandar, en un mes te devuelve un programa funcionando correctamente. Cuando le mandas el de asar peras, hace copy-paste y lo saca, igual que el programador estándar en quince días… pero empieza a reconcomerle por dentro un gusanillo. El programa se parece demasiado al anterior y debe haber alguna forma de extraer una parte común bastante grande. Seguro que hay una forma de no tener que ir por todo el código cambiando castaña por pera.  Con el de asar nueces te pregunta si va a tener que hacer muchos más de esos y se pone a reorganizarlo todo para que le resulten más fáciles este tipo de programas. Consigue sacarse unas librerías e incluso un framework asador. Tarda mes y medio en entregarte el de asar nueces, un programa pequeño junto con una librería grande. Cuando le encargas el de asar manzanas ¡sólo tarda dos días!. Te entrega un programa pequeñito y te dice que uses además la librería ya compilada que te entregó con el de asar nueces. El de asar pavos tarda también dos día y a partir de ahí los programas asadores salen como churros.

De estos hay realmente pocos y se les saca verdadero rendimiento cuando llevan a sus espaldas dos o tres proyectos. La empresa no los aprecia porque tardan demasiado en entregarte el programa de asar nueces y cuando hace en un día el de asar manzanas, la empresa piensa que ese programa era más fácil que el otro.

Feb 17

Maven, Jasperreports y MySQL

Hace tiempo que tengo ganas de meterme con jasperreports. Es una herramienta que he visto que usa mucha gente y de la que no tengo ni idea. Además, en su día Pablo metió un pequeño tutorial en la Chuwiki y se convirtió rápidamente en uno de los más visitados. Así que dicho y hecho, me puse con el ejemplo de ese tutorial a ver si sacaba algo en claro y a jugar un poco.

Lo primero que me dio pereza cuando me puse, fueron los jar que tenía que bajarme. En la página de jasperreports vienen tres jar que, ante la duda, se bajan los tres. En el tutorial de la Chuwiki, al final, pone otros jar necesarios, de apache-commons y similares, que también tendría que ir bajando. Todo esto me hizo retrasar el comienzo … hasta que se me ocurrió una genial idea.

Jasperreports y todos esos jar de apache son libres, así que posiblemente estén disponibles para maven. Fui a google y busqué ibibilio jasperreports. ibiblio es el repositorio de jars de maven, Poniendo eso en google y el nombre del jar que deseas, es fácil de encontrar. Así fué. Lo encontré y dije, la mejor forma de bajarse todo lo necesario es con maven.

Cree un proyecto maven así

mvn archetype:create -DgroupId=chuidiang.ejemplos.jasper -DartifactId=jasper -Dpackaging=jar

Esto me creo la esctructura de directorios para mi proyecto/ejemplo y el fichero pom.xml, en el que se describe el proyecto. Edité el pon.xml y le añadí la dependencia con jasperreports y de paso con mysql, que me haría falta.

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.0.4</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>1.3.0</version>
        <scope>compile</scope>
    </dependency>

Los nombres exactos de groupId, artifactId y versión los obtuve leyendo los ficheros .pom encontrados en internet: el de jasperreports y el de mysql.

Una vez hecho, me bastó compilar, sin haber hecho nada de código, con mvn compile para que maven se encargara solito de bajarme esos dos jar y todos los jar de los que estos dos dependen. Estos son todos los jar que se bajaron

GroupId ArtifactId Version Classifier Type Optional
avalon-framework avalon-framework 4.1.3 - jar
com.lowagie itext 1.3.1 - jar
commons-beanutils commons-beanutils 1.7.0 - jar
commons-collections commons-collections 2.1 - jar
commons-digester commons-digester 1.7 - jar
commons-logging commons-logging 1.0 - jar
eclipse jdtcore 3.1.0 - jar
javax.servlet servlet-api 2.3 - jar
jfree jcommon 1.0.0 - jar
jfree jfreechart 1.0.1 - jar
log4j log4j 1.2.12 - jar
logkit logkit 1.0.1 - jar
xml-apis xml-apis 1.3.02 - jar

Son todas las dependencias mezcladas de jasperreports y de mysql. Supongo que son todas las dependencias necesarias para los casos más raros de uso que se nos ocurran de jasperreports, porque veo cosas como javax.servlet y jfreechart, que imagino servirán para algún tipo de reporte publicable en jsp o con gráficos.

En fin, lo de maven tiene algunas pegas, pero en ocasiones es una maravilla. Buscar y bajarme todos esos jar a mano me habría llevado un buen rato. Además de evitarme varios ensayo y error para ver si me faltaba alguno (de mano no sabes a ciencia cierta qué jar necesitas exactamente, hasta que compilas y te lo dice el compilador). Además, los jar habrían acabado en un directorio perdido del que luego no me acordaría. Ahora están en un repositorio que maven organiza en mi pc y él sí se acordará en otros proyectos de dónde están. Y el proyecto de eclipse para la prueba lo he creado con un comando simple, con todos las dependencias añadidas y todo

mvn eclipse:eclipse

Una pequeña maravilla.

Feb 16

Imágenes aleatorias en PHP

Sigo jugando con PHP. Lo siguiente que se me ocurrió fue poner un chiste aleatorio en mi página. Así que cogí unos cuantos chistes de internet (esta es la parte divertida) y los guardé en un directorio en el servidor de mi página. Luego a investigar con php cómo se lee el contenido de un directorio para poner la imagen.

Me encontré con la función scandir(), que te devuelve un array con los nombres de los ficheros dentro del directorio. También devuelve los subdirectorios "." y "..".

A partir de ahí fué fácil, simplemente llamar a rand (2, $numeroFicheros). Lo de 2 para que se salte el 0 y el 1 que corresponden a los dos subdirectorios "." y "..". List todo. Lo pruebo en mi ordenador con mi propio servidor web de prueba y va estupendamente. Lo subo a mi servidor oficial, lo prueba y no va.

Una cosa que me llama poderosísimamente la atención es lo fácil que es todo en la teoría y como se complica la realidad. Me pongo a investigar y resulta que scandir() está disponible a partir de PHP 5. En casa tengo PHP 5, en el servidor del hosting tengo PHP 4. A buscar más.

Al final encontré la función glob(), a la que le pasas un patrón, estilo "imagenes/*" y te devuelve todos los ficheros que cumplen el patrón. No es lo mismo que scandir(), pero vale perfectamente. Esta función si es válida …. a partir de PHP 4.3.0 … Me voy al servidor, con más miedo que verguenza, a ver qué versión exacta tiene, no vaya a ser …  ¡¡Buff!!, tiene la 4.4.4.

glob() no devuelve los subdirectorios "." y "..", así que a cambiar el rand() por rand(0,$numeroFicheros)

Al final el código PHP quedó así

<?php
        $fichero = glob (‘chistes/*’);
        $chiste = rand(0,count($fichero)-1);
        print(‘<img src="’.$fichero[$chiste].’" alt="chiste" /> ‘);
?>

Feb 15

Bugzilla en Windows

En relación con un post anterior de Bugzilla en Windows, al final me decidí a escribir a la gente de Bugzilla un correo para "ofrecerles mis servicios como traductor", a pesar que de inglés se más bien poco.

Como no contestaron, lo he hecho por mi cuenta. He cogido su "Installing Bugzilla in Microsoft Windows" y he hecho una traducción literal al español. Me ha costando un horror ser literal y no meter mis propios comentarios, ya que así como a otros les cuesta contener la lengua, a mi se van los dedos por el teclado ellos solos.

Así que ahora tengo dos: mi propia experiencia de instalación en la Chuwiki, más la instalación de bugzilla en windows que acabo de traducir. Luego he intentado ir a la página de bugzilla a modificar el enlace, ya que es una wiki editable. Pero no, no es tan fácil, hay que registrarse y eso ya me ha dado pereza.

He estado mirando su manual de Bugzilla también, para ver si es traducible. Pero no, no es traducible, sólo es muy largo y mi inglés se acaba después de tres o cuatro párrafos.

Lo que sí estoy pensando es que se podía hacer una traducción (más que una traducción unos tutoriales bien hechos) sobre maven. Veo por el número de visitas que es un tema que tiene aceptación y la verdad, la documentación oficial de maven deja bastante que desear. Es bastante incompleta y muy caótica (más que mi página).