Jun 24

Pretty URLs en el foro SMF

Gracias al comentario de fabbc, he descubierto el plugin pretty URLs para el foro SMF.

Me he puesto a instalarlo y por supuesto, por no variar y por seguir la costumbre, no me ha funcionado. De todas formas, las instrucciones de instalación no son nada claras, sobre todo un punto que pone

Enable the filters in the new Pretty URLs page

cosa misteriosa donde las haya. Después de instalar el plugin, no veo ningún "new Pretty URLs page" por ningún lado. Investigando por google, parece que debería aparecer un menú en algún sitio para activarlo (en la barra lateral creo que he leido), pero por más que busco, no aparece.

Finalmente, leyendo, leyendo, acabo encontrando en http://code.google.com/p/prettyurls/wiki/Filters que hay un panel de administración oculto en index.php?action=admin;area=pretty;sa=filters, así que voy a él. Por supuesto, siguiendo la sana costumbre de que nada funcione a la primera para garantizar lo más posible el entreteniento, la distracción y la posibilidad de descubrir cosas nuevas, ese enlace no funciona y no me muestra nada.

Leo también en algún sitio que la versión más última (la snapshot) de este plugin, sí tiene ese panel de administración, así que desinstalo la versión 0.8.4 "estable" e instalo la snapshot. Esta vez SÍ funciona. Me sale el panel de administración, pulso el botón "settings" (el enlace del panel es para ir a otro sitio, no para decir cómo se activa el plugin, aunque por todos los caminos se llega a Roma), le doy a activar los "rewrite" y maravilla de las maravillas, todo funciona correcto.

Tengo ahora mi foro con URL amigables. Supongo que ya puedo quitar el sitemap que hice en su día, más que nada por no liar al pobre google, que verá la misma página con dos URL distintas.

Jun 19

assembly, jar y snapshot incompatibles en maven

Me he vuelto a tropezar con un pequeño problema que esta vez, tampoco he conseguido resolver.

Con maven damos a los proyectos un número de versión, de forma que luego el jar generado lleva dicho número de versión. Así, por ejemplo, podemos tener un proyecto MiProyecto al que decimos a maven que es versión 1.0 y  maven generará un jar MiProyecto-1.0.jar. Mientras estamos desarrollando este proyecto, podemos decir a maven que es una versión "SNAPSHOT", de esta forma sabe que ese jar se va a generar muchas veces y que será posiblemente distinto cada vez. Al hacerlo así, maven genera el jar añadiendo la fecha y hora del compilado, tal que así: MiPoryecto-1.0-20080619-131234.jar.

Esto tiene una ventaja adicional. Si hacemos ahora otro proyecto que depende de la versión SNAPSHOT de MiProyecto, cada vez que compilemos este nuevo proyecto, maven buscará si hay un jar más moderno de MiProyecto y se lo bajará. De esta forma, sin nosotros molestarnos en actualizar el jar, nuestro nuevo proyecto siempre tendrá disponible la última versión snapshot de MiProyecto

A maven también podemos decirle que nos genere el fichero de manifiesto dentro de nuestro jar principal y podemos decirle que automáticamente ponga el Class-Path con todos los jar que necesite. Maven lo hace correctamente y pone en esta dependencia un MiProyecto-1.0-SNAPSHOT, así exactamente, con todas las letras y sin reemplazar SNAPSHOT por ninguna fecha.

Finalmente, hay un plugin de maven llamado assembly que permite meter automáticamente en un zip nuestro jar, nuestros ficheros de configuración y todos los jar de los que dependemos. De esta forma, eso sería un zip de distribución que, entregándoselo a otra persona, podría simplemente desempaquetarlo donde quisiera y ejecutar nuestro programa teniendo todo lo necesario.

Pues bien, este plugin assembly no está de acuerdo con lo del manifiesto del jar. El plugin assembly, al generar el zip, mete dentro la versión snapshot de mi proyecto con MiProyeto-1.0-20080619-131234.jar, con todas las fechas y horas habidas y por haber. Nuestro jar principal busca MiProyecto-1.0-SNAPSHOT.jar y claro, no lo encuentra.

Buscando y rebuscando, al final encuentro que es un bug de uno de los dos, bien de maven al generar el manifiesto, bien de assembly al guardar el jar de MiProyecto. Así que de momento me he auto-prohibido generar zips que dependan de snapshots.

Jun 16

El lado oscuro de Java

En un post del foro de java y gracias a chusterboy he descubierto que java tiene un lado oscuro.

Resulta que aunque no está en la API oficial de java, con el JRE y JDK de Sun vienen ciertas clases que están disponibles y se pueden usar. Me refiero en concreto a las de com.sun.image.codec.jpeg, que permiten el manejo de imágenes jpg. En la API advierten que otras implementaciones del JDK o JRE que no sean las de SUN pueden no tenerlas, pero el caso es que están y no sé qué porcentaje de JREs que hay por hay NO son las de SUN.

Supongo que es cuestión ahora de abrir los .jar que vienen con el JRE o JDK de sun y buscar más "java oscuro"

Actualización: Como bien comentan en los comentarios, conviene no usar estas clases del lado oscuro, ya que en siguientes versiones de java pueden no estar y no todas las implementaciones de JDK las tienen. Además, hay muchas implementaciones de JDK que no son java, en concreto las de MacOS.

Jun 13

more vs. less

Desde mis primeros tiempos en unix conozco el comando more. Permite sacar un listado largo por pantalla e ir paginando, de forma que vamos pulsando espacio o <intro> cada vez que queremos avanzar

$ more fichero.txt

$ cat fichero.txt | more

Sin embargo, acabo de descubrir porque no conocía, el comando less. Como dice el man de este comando, "less – opuesto de more". Básicamente hace lo mismo que more, pero hace más y mejor. Por un lado, no lee de primeras todo el fichero, por lo que empieza a mostrarlo mucho antes que more. Por otra lado, también permite "navegar" hacia atrás. Admite muchas de las teclas de desplazamiento de vi.

<intro> mueve una línea adelante
n<intro> mueve n líneas adelante
y mueve una línea atrás
ny mueve n líneas atrás
d mueve una página adelante
b mueve una página atrás
g va al principio del fichero
G va al final del fichero
y un largo etc….

Creo que me voy a cambiar de comando.

 

Jun 12

Problemilla con las properties de Maven

En el post anterior comenté que se podían usar las properties de maven para fijar el número de versión que queremos usar en los subproyectos del proyecto principal. Pues bien, me he encontrado un pequeño problema que, afortunadamente, tiene solución.

Supongamos que tenemos un proyecto con varios subproyectos. En proyecto padre suele tener packaging=pom, mientras que los subproyectos de verdad tienen packaging=jar. Supongamos ahora que algunas dependencias son comunes a todos los subproyectos y decidimos poner dicha dependencia en el proyecto padre, tal que así

<packaging>pom</packaging>

<properties>
   <unNumeroVersion>1.0</unNumeroVersion>
</properties>

<dependency>
   <groupId>un.group.id</groupId>
   <artifactId>unArtifactId</artifactId>
   <version>${unNumeroVersion}</version>
</dependency>

Pues bien, todo funcionará correctamente.

Supongamos ahora un proyecto totalmente independiente de todo esto, pero que usa uno de los jar generados en ese proyecto anterior. Este nuevo proyecto irá al repositorio que tengamos de maven y cuando intente resolver las dependencias…. viene el problema. El .pom del proyecto padre sube al repositorio SIN resolver las propiedades, es decir, tendrá, literalmente, una dependencia de un.group.id:unArtifactId-${unNumeroVersion}.jar, sin reemplazar la propiedad por su valor. Nuestro nuevo proyecto tampoco intentará resolver esa propiedad, aunque la tenga definida, y buscará un jar en el repositorio que NO existe. El que existe es con número de versión 1.0 en nuestro ejemplo.

La solución, aunque en algún momento dado puede ser incomoda, es sencilla. Basta con no poner dependencias que usen propiedades en un proyecto cuyo packaging sea pom. Sólo podemos usar este truco de propiedades con dependencias en los subproyectos con packaging jar.

Jun 10

Properties en Maven

En los ficheros pom.xml de maven podemos poner properties de esta manera

<project>
   …
   <properties>
      <nombrePropiedad1>valor1</nombrePropiedad1>
      <nombrePropiedad2>valor2</nombrePropiedad2>
      …
   </properties>
   …

Por supuesto, si tenemos un proyecto grande compuesto de varios subproyectos maven, los proyectos hijos heredan las propiedades del padre. Podemos obtener el valor de estas propiedades poniendo ${nombrePropiedad1} donde sea necesario.

¿Para qué sirve todo esto?. Pues gracias a Random thoughts by Ceki Gülcü he encontrado una posibilidad estupenda, que además me soluciona un problema que me traía de cabeza desde hace tiempo.

El tema es que tengo proyectos maven grandes, con varios subproyectos dentro y algunos de ellos incluso con otros subproyectos. En ellos, hay dependencias repetidas, digamos, por ejemplo, que los subproyectos A, B y C tiran de unaLibreria-1.2.jar. Pues bien, esa dependencia con ese número de versión está en los pom.xml de A, B y C

<dependency>
   <groupId>un.group.id</groupId>
   <artifactId>unaLibreria</artifactId>
   <version>1.2</version>
</dependency>

Muchas veces, esa librería es una librería nuestra interna y su número de versión se actualiza con cierta frecuencia. Cuando cambiamos este número de versión, hasta ahora no nos quedaba más remedio que ir rebuscando esta dependencia por todos los pom.xml de los subproyectos para cambiarla.

Pues bien, con esto de las propiedades, hay una solución mucho más sencilla. En el pom.xml de proyecto padre/raíz, ponemos una propiedad tal que así

<properties>
   <unaLibreriaVersion>1.2</unaLibreriaVersion>
   …
</properties>

y en la dependencia de los subproyectos, ponemos

<dependency>
   <groupId>un.group.id</groupId>
   <artifactId>unaLibreria</artifactId>
   <version>${unaLibreriaVersion}</version>
</dependency>

De esta forma, cuando cambia la versión de la librería, sólo tenemos que cambiar el valor de la propiedad en el pom.xml del proyecto raíz/padre.

Una pequeña maravilla de la técnica.

Jun 09

Copy – Paste desde java

En java, con Toolkit.getDefaultToolkit.getSystemClipboard() podemos acceder al portapapeles del sistema. Con los métodos ahí disponibles podemos introducir contenido o extraer el contenido que otras aplicaciones han dejado allí.

Para contenido que no sea de texto, tendremos que "currarnoslo" un poco, pero para contenido de texto es muy sencillo, simplemente porque los componentes de texto de java swing ya tienen implementados los controles de copy-cup-paste con los típicos Ctrl-C, Ctrl-X y Ctrl-V, así que no tenemos ni siquiera que acceder al portapapeles ni hacer absolutamente nada de código.

Si lo que queremos son las típicas opciones en un menú o en unos botones con la funcionalidad copy-cut-paste, también es sencillo para texto normal. La clase DefaultEditorKit ya tiene implementadas estas acciones como Action, así que bastará con pedírselas o instanciarlas y ponerlas en los JMenuItem o JButton.

Action accionCopiar = new DefaultEditorKit.CopyAction();
Action accionPegar = new DefaultEditorKit.PasteAction();
Aciont accionCortar = new DefaultEditorKit.CutAction();

como hemos dicho, estas Action se pueden poner directamente en los JButton o JMenuItem. Funcionarán sobre el componente de texto que tenga el foco en el momento de pulsarlos.

Más detalles en copy/cut/paste para componentes de texto.

Jun 06

Ubuntu + firefox + java

 

Bueno, por fin he conseguido el firefox con los Applets de java. Ni instalando, ni reinstalando, ni con apt-get ni leches similares. O sea, nada de pinchar aquí y allí con el ratón y que funcione. Lo conseguí con línea de comandos y algo de investigación.

Con apt-get, reinstalando e instalando no conseguí nada. Es cierto que lo que no hice fue desinstalar java y firefox a la vez y luego reinstalarlo en orden todo desde cero, pero no me parece de recibo que para instalar un plugin haya que desinstalar ambas aplicaciones y volver a instalarlas.

Buscando por internet encontré que la forma es poner un link simbólico dentro de ~/.mozilla/plugins a la librería .so que hace de plugin. Por supuesto, no sé cual es el motivo, pero en mi caso la librería .so de plugin no estaba donde indicaba la página, en /usr/java/jre1.5.0_01/plugin/i386/ns7/libjavaplugin_oji.so, (desde luego, a mi java me lo ha puesto en /etc/alternatives y no en /usr/java) sino en un sitio tan extraño como /usr/lib/xulrunner-addons/plugins/libjavaplugin.so, ¡¡ vaya !! que lo encontré de casualidad.

Así que simplemente con estos comandos

cd ~/.mozilla/plugins
ln -s /usr/lib/xulrunner-addons/plugins/libjavaplugin.so libjavaplugin.so

conseguí que funcionara.

Revisando, veo que si lo hubiera hecho al directorio de plugins donde está instalado firefox /usr/lib/firefox-2/plugins, posiblemente hubiera servido para todos los usuarios, pero bueno, soy el único usuario de mi ordenador y lo de "sudo" me da un poco de pereza (fíjate si es trabajoso que hasta hay que introducir la password, que por supuesto, es segura y tiene 512 caracteres con símbolos especiales, cifras y letras mayúsculas y minúsculas entremezcladas y sin sentido alguno).

Por cierto, ya que estuve instalando y desinstalando por culpa del plugin de java este, me quité la versión firefox-3 beta y me he puesto la 2. Pero por supuesto, tuve problemas, tontos esta vez, pero los tuve. Resulta que al instalar firefox-2, no me funciona el icono de firefox que me pone en el menú "aplicaciones"->"internet". ¿Motivo? Porque el ejecutable se llama firefox-2 y el menú intenta arrancar firefox a secas, sin numerito detrás. Nada que no se pueda arreglar.

¿Seré capaz ahora de instalar la barra de google?

 

Jun 04

Las cosas de Google

 

Visto en el Blog de Dr. Max Glaser, si vas a la página http://goosh.org/ verás una línea de comandos típica de una terminal de linux, pero para buscar en google. Escribiendo "help" tendrás un listado de todos los comandos que puedes ejecutar, básicamente todos ellos para búsqueda en google.

Todavía no sé muy bien para qué sirve, pero no deja de ser curioso.

Jun 03

Línea cronológica de GNU Linux

 

Visto en SIGT.net, un "poster" con la cronología de las distintas distribuciones de linux.

cronologia distribuciones linux