28 julio 2006

Mozilla SeaMonkey

Jugando con internet acabo de descubrir mozilla seamonkey. Miré a ver que era y ponía que es una especie de navegador, correo y editor de html todo junto.

Lo he instalado y me ha decepcionado un poco. Es casi exactamente lo que antes era netscape, que venía con navegador, composer, etc. No quiero decir que el programa esté mal, sino simplemente que es lo mismo que el antiguo netscape, pero con otro nombre.

Seguiré con el firefox y el thunderbird, que me gustaron bastante más nada más instalarlos.

En cuanto a editor de html, tradicionalmente he utilizado el netscape composer. Sin embargo, hace poco, que empecé a meter algun java script ajeno, me empezó a hacer cosas raras. Y desde luego, no he conseguido que se trague una página php sin descuajeringarla, a pesar del que el 90% de la página es html. Por eso me he acabado cambiando a dreamweaber y de momento estoy contento con él. No uso todo lo que tiene, puesto que mis páginas son muy sencillitas, sólo html y algo mínimo de php en alguna ocasión, y algún javascript ajeno que inserto (contadores de estadísticas, google adsense, etc), unas pruebas con css, pero me hace bien lo que quiero que haga. Sobre todo no me descuajeringa una página cuando su extensión es php.

Crear .exe de java

Aunque la forma normal de hacer un programa java es generar un fichero jar, su ejecución puede ser compleja para un usuario que no conozca java. Por ello, entregar una aplicación java a un usuario normalito de ordenador suele requerir entregar también un .bat de arranque, que revise si existe máquina virtual, que ponga cosas como el classpath, etc, etc.

Hay utilidades que permiten pasar nuestro .jar a un fichero .exe normal de windows, de forma que a un usuario no programador le resulte más fácil el arranque.

Algunas de estas utilidades, como JSmooth, simplemente crean un pequeño exe que arranca la aplicación, pero necesitan que la máquina virtual esté instalada.

gcj sí crea un verdadero ejecutable, pero gcj está pensado para el entorno de gnu, por lo que para ejecutarlo en windows es necesario instalar previamente el cygwin. gcj venga mejor posiblemente para usuarios de linux/unix.

java2exe (ahora JexePack) también permite generar .exe, pero es una aplicación de pago.

Algunos IDE, como JBuilder, también permiten generar el exe.

De todas formas, no he probado ninguno de ellos. De momento no tengo ninguna necesidad especial de generar .exe. Además, pienso que se pierde un poco la filosofía de java, que es que el "ejecutable" se pueda ejecutar en cualquier sistema operativo. Tampoco suelo hacer aplicaciones para usuarios no programadores.

27 julio 2006

Cambiar el icono de la taza de café en java

La forma normal de cambiar el icono de la taza de café en java en una aplicación consiste en llamar al método setIconImage() del JFrame principal de la aplicación. Luego, el resto de JDialog de la aplicación deben ser hijos, nietos o biznietos de este JFrame, heredando así su icono. Puedes ver más detalles de este cambio de icono.

Sin embargo, ayer un compañero de trabajo encontró una forma más bruta de hacerlo, de forma que queda cambiado para todas las aplicaciones java de nuestro ordenador (salvo que ellas lo cambien de forma expresa dentro).

Este método de fuerza bruta consiste en buscar dentro de nuestra instalación de java los ficheros rt.jar y awt.dll, que contienen dentro dicho icono de la taza de café y cambiarlo por otro. En Cambiar el icono de la taza de café están los detalles.

25 julio 2006

Dos programas opuestos

Aquí un par de programitas para java que pueden ser más o menos útiles y que sirven para lo contrario.

El primero es un "descompilador" de java. El DJ Java Decompiler es un programita que dándole los ficheros .class es capaz de sacarnos los fuentes .java. Tiene interface gráfica y es gratis.

El otro programa, en realidad son varios, son los ofuscadores de código java. Precisamente para evitar que nuestros programas java puedan ser "descompilados", existen estos ofuscadores. Básicamente lo que hacen es cambiar los nombres de clases, métodos y variables por nombres crípticos. El programa .class puedes descompilarse igualmente, pero no es lo mismo intuir que el método setNombre(String nombre) de la clase Persona mete el nombre de la persona en la clase Persona, que intuir qué demonios hace afaewser(String afew) de la clase Xdañsiñwe. Supuestamente, además de ofuscar y ya puestos a tocar el jar, la mayoría de ellos llevan a cabo labores de optimización, tratando de reducir el jar lo máximo posible, eliminando código innecesario, variables no usadas, métodos no usados, etc. De hecho, la ofuscación de código es más bien un "efecto secundario" de este proceso. Para reducir el tamaño del jar, no hay nada como llamar a las clases, métodos y variables con nombres lo más cortos posibles. No he probado ninguno, pero por lo que he leido es lo que intuyo que hacen...

ProGuard es un ofuscador gratuito y en la misma página tienes un listado de otros ofuscadores de código.

21 julio 2006

Método toString() de Element de org.w3c.dom

Me he tropezado con un pequeño problemilla que cuento aquí por si a alguien más le pasa lo mismo.

Resulta que trabajando con la versión 1.4 de java, cuando tengo un Document correspondiente a un fichero xml guardado en memoria, haciendo toString() del Element raiz del Document, me devuelve un String con el contenido del fichero xml.

Sin embargo, ¡sorpresa!, en la versión 1.5 de java este método toString() ya no devuelve el String el formato xml, sino que devuelve una cosa rara, cortita, que no vale.

En Bug ID: 6181019 REGRESSION: org.w3c.dom.Element.toString() no longer returns the xml document: "toString" está comentado este problema con más detalle.

Contar líneas de código

Hay una cosa que descubrí hace ya bastante tiempo, pero que me llamó mucho la atención por su simplicidad, y es el cómo se pueden contar las líneas de código de un programa de una forma simple.

En su momento, cuando me ví en la necesidad de contar las líneas de código que habíamos hecho en el trabajo, y de esto hace mucho y no había las herramientas que hay ahora o, al menos, no se encontraban de forma gratuita en la red, me puse a pensar en ello y buscar por internet.

Lo de contar líneas tal cual (contar retornos de carro) me parecía poco fiable. Si alguien deja muchas líneas en blanco, no hace muchas líneas de código, pero se cuentan como tales. Los comentarios también contarían como líneas de código. Si alguien abre las llaves "{" en una nueva línea

public void funcion ()
{
...

hace más líneas de código que uno que lo pone todo seguido

public void funcion () {
...

Investigando por internet, encontré la forma muy aproximada y sencilla de hacerlo. ¡¡Basta con contar los punto y coma ";" del código!!

Como cada línea de código acaba en punto y coma (En C, C++, java y otros muchos lenguajes) esto nos da una aproximación muy buena y simple del número de líneas de código.

Además, si alguien es vago como yo y no quiere demasiada precisión en la medida, basta con encadenar unos comandos de unix/linux para contar algo parecido al número de puntos y coma

$ cat `find . -name *.java` | egrep ";" | wc -l

La primera parte saca un listado por pantalla (cat) de todos los ficheros .java que encuentre del directorio actual hacia abajo.

La segunda parte, filtra (egrep) para que en el listado sólo salgan las líneas que contienen al menos un punto y coma.

La tercera parte, cuenta (wc) las líneas del listado anterior.

El resultado es el número total de líneas de los ficheros .java que contienen al menos un punto y coma, es decir, una aproximación más o menos buena del número de líneas de código.

De todas formas, alguien que sepa un poco más de linux seguro que encuentra la forma de contar el número de ; de una forma también sencilla ...

Tutorial C y C++ , Programación de sockets con C y linux

Veo en Tutorial C y C++ , Programación de sockets con C y linux que han puesto uno de mis tutoriales en un marco y justo encima han puesto una cabecera de ellos.

El marco es directamente mi página, no es una copia, y en la cabecera ponen la página original. En fin, me parece todo bien y correcto, pero me ha llamado mucho la atención el verlo ...

17 julio 2006

El PageRank de google está cabra

Acabo de ver que después de cuatro meses de mis apuntes de programación. por fin tiene un PageRank. Le dieron uno de cero al poco de crear la página/dominio. Ahora tiene uno de 4, que es más o menos lo que tenía mi antigua página www.geocities.com/chuidiang.

Sin embargo, veo que el page rank actual está un poco tonto.

Mi diario de correr y bicicleta tiene un pagerank de 3. Si miro, según google, las páginas que enlazan a él, no hay ninguna. Tampoco tiene apenas visitas. Sin embargo, este diario de programación tiene sólo un pagerank de 2. Hay varias páginas que enlazan a él (según google) aparte de la mía y además tiene unas cuantas visitas diarias.

¿Cómo es posible esto?.

También hay otro mito que no sé si es real. Supuestamente con un pagerank más elevado tus páginas salen más arriba en los buscadores. Sin embargo, desde que mis apuntes de programación han pasado de pagerank 0 a pakerank 4 (el viernes o el sábado pasado), no he notado ningún cambio en el número de visitas.

Sin embargo, de vez en cuando sí noto cambios bruscos que duran temporadas largas de vez en cuando. Por ejemplo, el número de visitas se ha reducido casi a la mitad, de forma progresiva, desde mediados de Junio sin razón aparente (ver gráfico).

13 julio 2006

Ficheros KK

En todo proyecto informático que se precie hay uno o más ficheros "kk", que no sirven para nada, que nadie usa, pero que si se te ocurre borrar el proyecto deja de funcionar.

También suele haber varias versiones de ejecutable, cuyos ficheros se llaman así ejecutable_bueno.exe, ejecutable_nuevo.exe, ejecutable_hoy.exe, ejecutable_ultimo.exe. Está claro que esta nomenclatura de nombres es la más adecuada para saber cual es el que hay que arrancar, en función de que se quiera el bueno, el nuevo, el de hoy o el último.

También suele haber varias versiones antiguas, etiquetads ejecutable_antiguo.exe, ejecutable.exe.bak, ejecutable.exe.old, ejecutable_viejo.exe. De esta forma también es fácil saber qué se debe recuperar, según se quiera el old, el viejo, el bak o el antiguo.

Rizando el rizo, a veces también hay líneas de código que nunca se llaman, ni poniendo un breakpoint con el debugger en ellas, ni System.out, ni printf, ni de ninguna manera, pero ¡Ay de tí como se te ocurra borrarlas!. El ejecutable dejará de funcionar.

07 julio 2006

Más sobre el patrón Decorador

Acabo de terminar mi primer cacho de programa usando el patrón Decorador como comenté en el post anterior.

Una primera ventaja que le veo, en mi caso concreto, es que puedo hacer todo el código sin necesidad de la base de datos y probarlo. Mi modelo de datos va en memoria implementando una interface, mis clases de ventanas y demás sólo ven la interface. Mis clases de mis librerías reutilizables sólo ven la interface, así que puedo usarlas tal cual sin tocar nada en ellas, sin necesidad de hererdar ni de configurarlas de ninguna manera.

Luego, hago el decorador del modelo que se encarga de la base de datos. Dentro de él meto el modelo de datos e implemento todos los métodos simplemente para que se redirijan al modelo interno. Con esto todo sigue funcionando igual que antes, sin base de datos.

Ahora sólo me queda, poco a poco, ir modificando los métodos del decorador para que hagan su trabajo en la base de datos.

Otra ventaja adicional que le veo es que todo lo de base de datos (las sql, la conexion, etc, etc) queda encapsulado en una única clase.

La verdad es que la experiencia me ha gustado bastante y pienso repetir en adelante.

05 julio 2006

Posibilidad para el patrón Decorador

Estoy experimentando con el patrón Decorador y de momento parece que tiene buena pinta.

Me explico. Es bastante habitual que tenga que hacer alguna aplicación con unas ventanas para mostrar datos recogidos de una base de datos. Desde dichas ventanas debe además poder modificarse los datos en base de datos. Los típicos añadir, borrar y editar.

Mi forma habitual de hacer esto era con el patrón Observador. Hago una clase que llamo modelo de datos en la que guardo los datos de la base de datos después de haberlos leido. A esta clase le pongo un mecanismo de suscripción, de forma que otras clases puedan enterarse cuando se modifican los datos.

Hago otra clase que se encarga de leer la base de datos y rellenar el modelo de datos. Tiene además los métodos para añadir, modificar y borrar elementos de base de datos.

Las ventanas son clases que están suscritas al modelo de datos, de forma que cuando el modelo de datos se rellena de datos, automáticamente las ventanas los muestran. Algo similar al DefaultTableModel de java y el JTable.

Los botones de las ventanas que permiten modificar los datos los suelo hacer que actuen directamente con la clase que se encarga de la base de datos. Si unos de estos botones debe añadir, borrar o modificar algo, lo hace contra la clase de base de datos. Esta se encarga de hacer la modificación en base de datos y si tiene exito, refleja el cambio en el modelo. Este a su vez por medio del patrón observador avisa a la ventana para que refleje el cambio.

Todo este es el mecanismo que uso habitualmente, pero no me acaba de convencer porque acaba todo entremezclado. Los botones, que son interface de usuario, deben ver a la clase de base de datos y esta a su vez ve al modelo de datos. Tengo botones ya hechos que hacen las tareas habituales de añadir, borrar y modificar elementos de una lista, pero siempre tengo que heredar de ellos o instanciarlos pasándoles la clase de base de datos y "capando" su comportamiento de actuar sobre le modelo directamente.

Ahora estoy intentando aplicar el patrón Decorador. Consiste básicamente en hacer que la clase de modelo de datos y la clase de base de datos cumplan la misma interface y puedan intercambiarse. Ambas tienen métodos añade(), borra() y modifica(). La clase de base de datos además admite que se le pase el modelo de datos.

El método añadir(), por ejemplo, en la clase de base de datos, inserta en base de datos y si la inserción tiene éxito, llama al añadir() del modelo de datos.

Tanto el modelo de datos como la clase de base de datos implementan un patrón observador, para notificar cambios en los datos. La de modelo de datos es normal. La clase de base de datos se suscribe al modelo de datos y notifica cuando notifique este. De esta forma, cuando la clase de base de datos añade() un dato, lo mete en base de datos y luego en el modelo. El modelo avisa a la clase de base de datos y esta a sus suscriptores, que serán las ventanas.

Al hacer que ambas clases implementen la misma interface, a las ventanas puedo pasarles indistintamente una u otra. Las ventanas y los botones actuarían directamente sobre la interface, con lo que no saben si lo están haciendo contra base de datos o contra el modelo de datos. Las ventanas se refrescarán también correctamente independientemente de qué modelo se les pase.

Esto tiene otra ventaja adicional, y es en el borrado. Habitualmente los modelos de java como TableModel, avisan del borrado después de haber borrado. Con mi antiguo mecanismo de suscripción, no podía obtener el elemento borrado para borraren la base de datos, únicamente sabía qué fila se había borrado, pero no podía obtener el elemento borrado, ni su clave en la base de datos. Con este nuevo mecanismo de patrón Decorador, me avisan cuando se quiere borrar, con lo que puedo borrar de base de datos, luego del modelo y luego se refresca la vista.

En fin, lo poco que voy probando va teniendo buena pinta y muchas ventajas respecto a mi antiguo mecanismo. En algún momento haré un pequeño tutorial para mi página en la que se haga una tabla con añadir, borrar y modificar de una base de datos usando este patrón.