Narciso, Hablando de Software

17.8.05

He cambiado de dirección

Apreciado lector,
He cambiado mi blog en blogger por uno nuevo y más funcional en zoomblog, si tu navegador no te envía automáticamente a el, puedes usar este enlace.

Gracias y disculpa las molestias.

12.8.05

Fedora Core 4, SELinux vs. Java, Apache, Jboss

Recientemente he actualizado mi equipo, de Fedora Core 3 a Fedora Core 4. Ciertamente el salto ha sido mayor que en ediciones anteriores. El look and feel está más conseguido; detecta, monta y crea enlaces temporales en el escritorio para cualquier dispositivo removible (CD/DVD, USB disk, etc); tiene algo muy util pero que requiere una muy buena tarjeta gráfica: transparencia para ventanas en segundo plano. Esto último está muy bien porque elimina esa sensación de escritorio lleno. También tiene soporte para bluetooth integrado y otras cuantas cosas más que hacen ver como se acerca más a Window$.
Pero no todo iban a ser alegrías, de hecho me ha traído loco con ciertas cosas, casi todas de la mano de SELinux. La verdad es que me fijé que en versiones anteriores ya estaba SELinux, pero por defecto venía desactivado y nunca le presté mucha atención. Ahora en cambio, SELinux viene activado por defecto, lo cual implica una serie de restricciones importantes de seguridad para el sistema de ficheros y las comunicaciones. Que no es que estén mal, porque de hecho es buena la seguridad, pero hasta que no aprenda mejor como usarlo lo he desactivado.
Así que por si a alguno le pasan cosas como estas, ahí va la lista de "incidentes":
  1. Si traes una copia de seguridad de ficheros (hecha con tar, por ejemplo) desde un equipo con SELinux desactivado (como mi instalación con Fedora Core 3), al desempaquetarlo no tiene los descriptores de SELinux correctos, por lo que hay que reaplicarselos o bien hacer el "truco" (copiar a otro directorio, borrar y mover desde el directorio copiado, ya que al copiar son ficheros nuevos y se les dan los atributos correctos). Cosas que pueden ocurrir si no lo haces es que en el caso de que los ficheros sean los de una web, como era mi caso, Apache te dirá todo el rato que 403 Forbidden, por más que los permisos y grupos parezcan correctos.
  2. Si tienes un Tomcat/JBoss y quieres conectarlo con Apache usando mod_jk o mod_jk2, el mod_jk se quejará hagas lo que hagas diciendo que
    [jk_ajp_common.c (1477)]: Error connecting to tomcat. Tomcat is probably not started or is listening on the wrong port. worker=ajp13 failed errno = 13
    Para esto lo único que me ha funcionado es desactivar SELinux o ponerlo en modo permisivo, al menos de momento.
  3. Aunque lo cierto es que no uso mucho el Window$, lo tengo instalado para esas pocas ocasiones, total hay que aprovechar la licencia que venía con el portátil. Así que tengo el disco con una partición NTFS para Window$, una FAT32 para compartir datos entre ambos sistemas, y luego las particiones Linux. Pues bien, para ahorrar espacio, en lugar de tener una partición para swap en linux y el dichoso fichero de intercambio de Window$, lo que hago es poner el fichero de intercambio de en la partición FAT32 y desde linux usarlo como swap, así sólo pierdo 2Gb de disco en vez de 4Gb (tengo 1Gb de RAM). Con Fedora 3 no había problema alguno, pero con este me salta todo el rato con "permission denied" al hacer el swapon.
Bueno, la verdad es que tuve otro incidente más, este mucho más suerrealista y difícil de encontrar, gracias a Internet al final pude solucionarlo. Es una conjunción curiosa que ocurre con Fedora Core 4 y JDK 1.4. Fedora 4 usa IPv6 junto a IPv4, y resulta que JDK 1.4 por defecto usa IPv6 si está disponible, lo cual resulta en una imposibilidad casi total de conseguir conectar desde java a cualquier servicio de red. Para solucionarlo, pues si puedes usar JDK 1.5 mejor, pero si no, tienes que ejecutar el comando java pasando una constante que hace que use IPv4: -Djava.net.preferIPv4Stack=true.
Bueno, espero que si alguien topa con estos problemas esto le sirva de ayuda. Cuando aprenda a usar SELinux ya contaré la solución ¿o se anima alguien a iluminarnos?
Como última pincelada, os diré como deshabilitar SELinux: para hacerlo temporalmente podemos usar el comando setenforce permissive, siempre como usuario root; para hacerlo permanentemente debemos editar el fichero /etc/selinux/config y donde pone SELINUX=enforce ponemos SELINUX=permissive.
Gracias a Technorati he encontrado algo que puede servir, habrá que probarlo un poco más adelante.


Technorati: Fedora, SELinux, Java, JDK, JBoss, Tomcat, mod_jk

9.8.05

Java sobre ruedas

Hace ya unos años que vi en un programa de televisión sobre coches que cierto fabricante estaba ya haciendo pruebas para poner sistemas basados en MS Windows CE (ahora PocketPC) dentro de sus coches. Y con dentro quiero decir controlando la electrónica del coche, desde temas como puede ser la inyección electrónica o la alarma hasta cosas más de entretenimiento como el GPS o DVD. Este "prodigio" sería capaz de hacer cosas como por ejemplo detectar componentes que pudieran estar a punto de fallar, de controlar cuando debemos llevar el coche a revisión, y lo que es mejor, concertar automáticamente una cita con el taller para ello. Aún hay más, también sería capaz de autoactualizarse sobre la marcha, con algo similar al Windows Update pero específico para esto. Para ello utilizaría el teléfono móvil integrado.
Aquello no llegó a salir (usaba Windows CE).
Pero ahora hay algo similar que va a salir ya a la calle, de momento sobre los BMW serie 5, 6 y 7, y que funciona con Java. Aunque no controla nada de electrónica del propio coche (mejor) y se dedica exclusivamente al tema de entretenimiento y comunicación. En los coches con navegador y pantalla a color vendrá este sistema, que permite controlar el navegador, la radio, el teléfono móvil, la climatización, la televisión, el dvd, el GPS, etc.
De momento funciona con Personal Java, que está siendo abandonado en favor de J2ME, pero ya están realizando la adaptación para que funcione con J2ME CDC (CDC es una versión de J2ME para dispositivos con más capacidad que los teléfonos móviles, que funcionan sobre CLDC).
Esto abre un mundo de posibilidades muy grande de cara a los desarrolladores de aplicaciones móviles, un campo en auge y con gran futuro y con el que tengo mucho que ver en estos últimos tiempos.
El sistema está pensado para montarlo en cualquier vehículo, no solo en BMW, y cuando empiecen a extenderse (cada vez son más los coches con navegador gps) serán muchas las posibilidades, no solo de aplicaciones de entretenimiento, sino tabmién de negocio.
Más información:

5.8.05

¿Por qué no sois bloggers?

Mientras leía el blog de mi amigo y ex-compañero Esteban, pensaba en todos los ex-compañeros que han ido quedando en el camino tras todos estos años.
Son muchos y muy buenos, pero el caso es que poco a poco la vida nos lleva a cada uno por un sendero diferente y se va perdiendo el contacto.
Sin embargo, si todos escribieran un blog, aunque fuera poniendo un post cada varios meses, sería más sencillo mantener el contacto y saber que es de ellos.
Y lo cierto es que ese contacto no es sólo personal, sino también profesional. Sin ir más lejos buscaba una empresa de diseño web y me acordé de Maite Cajaraville y su estudio de diseño, pero la web está fuera de juego y he tenido que buscar a otros.
Por eso me pregunto, ¿por qué no sois bloggers? No cuesta tanto, un blog es gratis y hay donde elegir, y poner un post cada cierto tiempo solo requiere unos minutos.
De hecho he recurrido al "googling" (he tenido que crear la entrada en la Wikipedia :) ) para buscar información sobre algunos, pero lo cierto es que parece que se esconden, ni tan siquiera un post en algún grupo de dudas sobre cualquier tema de consultoría informática.
También me he registrado en e-conozco y en linked in, pero ahí sólo he encontrado un par de ellos que buscan un trabajo más apetecible.
Bueno, acabo con estas reflexiones tardías esperando que alguno de mis excompañeros haga googling sobre mi, vea la entrada a uno de mis blogs y me haga caso (dejad un comentario aquí para que sepa que lo habéis visto :) ).

19.7.05

De vuelta

Vaya, hace casi un año que no escribía en este diario. Ha sido un año con una cantidad de trabajo realmente terrible. Si creeis que trabajais mucho, montad vuestra propia empresa y vereis lo que es trabajar :)
Mi gran proyecto, Elondra, se ha llevado casi todo mi tiempo libre, y el poco que quedaba ha sido para mi familia y la universidad.
No es que ahora tenga realemnte más tiempo, al contrario, la actividad sigue siendo tremenda, pero he decidido retomar este hilo. Probablemente no haga más de una aportación al mes, pero bueno.
Estoy preparando un texto sobre J2ME, que espero que os resulte muy interesante.
Por cierto, hace algún tiempo creé también otro blog corporativo: Elondra Blog.

13.8.04

Hibernate y JBoss

Lo prometido es deuda, así que hoy voy a explicar cómo he integrado Hibernate y JBoss.
Lo primero que hay que tener en cuenta son las versiones, esto aplica a JBoss 3.2.x (en concreto estoy trabajando actualmente con la 3.2.5) y a Hibernate 2.1.6. La versión 2.1.4 de Hibernate tenía un fallo que impedía su uso con JBoss así que es imporante utilizar la 2.1.6 que ahora es la última disponible.
Al grano.
Con Hibernate creamos los denominados POJO (Plain Old Java Objects) o Java Beans, e Hibernate se encarga de manejar la persistencia de dichos objetos. Hibernate nos permite una flexibilidad increiblemente mayor que los Entity Beans a la hora de diseñar la estructura de clases, y eso significa que podemos hacer diseños de una granularidad muy fina, usar la herencia adecuadamente y crear componentes (otros POJOs) que actúen como campos de nuestras entidades.
Para hacer que Hibernate funcione con JBoss hemos de crear un archivo de servicio dentro de nuestra aplicación, es decir un archivo .SAR, pero como queremos poder llamar a nuestras clases desde el resto de la aplicación, en dicho .SAR sólo irá el archivo de servicio y los archivos descriptores de nuestras entidades (los .hbm.xml). Y algo más... también hemos de incluir el archivo de servicio que creará la fuente de datos (DataSource) uitilizado por Hibernate.
Yo utilizo XDoclet y Ant para la automatización de todo este proceso, aunque XDoclet introduce algunas limitaciones sigue siendo lo suficientemente interesante.
Por otro lado, en nuestro archivo de aplicación (.EAR) tenemos que hacer referencia a los diferentes servicios en el orden adecuado, así como incluir todas las librerías necesarias: las que necesita Hibernate, una con las clases que representan nuestras entidades y el resto que necesite nuestra aplicación.
En definitiva, nuestra aplicación debe tener la siguiente estructura:
aplicacion.EAR
|
|- hibernate.SAR
| |
| |- descriptores
| |- META-INF/
| |
| |- datasource.xml
| |- jboss-service.xml
|- lib/
| |- dependencias de Hibernate
| |- model.jar
| |- demás librerías que necesite la aplicación
|
|- META-INF/
| |
| |- application.xml
| |- jboss-app.xml

Dónde:

  • descriptores es la jerarquía de directorios paralela a nuestra jerearquía de clases persistentes con los ficheros .hbm.xml correspondientes

  • datasource.xml es el descriptor de nuestro origen de datos (más información en la documentación de JBoss)

  • jboss-service.xml es el descriptor del servicio Hibernate. Yo lo genero automáticamente con Ant y XDoclet, es lo más cómodo y seguro para no equivocarse. En cualquier caso os doy un ejemplo

  • model.jar es nuestro modelo, las clases persistentes que manejará Hibernate empaquetadas en un jar.

  • application.xml es el descriptor de aplicación J2EE (más información en la documentación de Java J2EE). Aquí lo importante es hacer referencia a todas las librerías y servicios de nuestra aplicación, así que también os pongo un ejemplo.

  • jboss-app.xml es el descriptor de aplicación específico de JBoss, en el se hace referencia al servicio de Hibernate y a otros que podamos tener en nuestra aplicación (más información en la documentación de JBoss). También os doy otro ejemplo


Ejemplos:
1. Archivo de servicio para hibernate.SAR

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<!-- Generated file - Do not edit! -->

<server>
<mbean
code="net.sf.hibernate.jmx.HibernateService"
name="jboss.jca:service=Model"
>
<depends>jboss.jca:service=RARDeployer</depends>
<attribute name="MapResources">
com/sample/app/model/Role.hbm.xml,
com/sample/app/model/common/Telephone.hbm.xml,
(other descriptors)
</attribute>
<attribute
name="JndiName"
>java:/hibernate/DefaultSessionFactory
</attribute>
<attribute
name="Datasource">java:/myDS</attribute>
<attribute
name="Dialect">net.sf.hibernate.dialect.MyDialect
</attribute>
<attribute
name="ShowSql">false</attribute>
<attribute
name="UserTransactionName">UserTransaction
</attribute>
<attribute
name="TransactionStrategy"
>net.sf.hibernate.transaction.JTATransactionFactory
</attribute>
<attribute
name="TransactionManagerLookupStrategy"
>
net.sf.hibernate.transaction.JBossTransactionManagerLookup
</attribute>
</mbean>
</server>


2. Archivo de aplicación

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE application
PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN'
'http://java.sun.com/dtd/application_1_3.dtd'>
<application>
<display-name>Mi Aplicación</display-name>

<!-- ===================================
jdbc driver
======================================= -->
<module>
<java>lib/my-jdbc-driver.jar</java>
</module>

<!-- ===================================
Model classes
======================================= -->
<module>
<java>lib/model.jar</java>
</module>

<!-- ===================================
Hibernate classes
======================================= -->
<module>
<java>lib/c3p0-0.8.4.5.jar</java>
</module>
<module>
<java>lib/cglib-full-2.0.2.jar</java>
</module>
<module>
<java>lib/commons-collections-2.1.1.jar</java>
</module>
<module>
<java>lib/commons-lang-1.0.1.jar</java>
</module>
<module>
<java>lib/concurrent-1.3.3.jar</java>
</module>
<module>
<java>lib/dom4j-1.4.jar</java>
</module>
<module>
<java>lib/ehcache-0.9.jar</java>
</module>
<module>
<java>lib/hibernate2.jar</java>
</module>
<module>
<java>lib/jaas.jar</java>
</module>
<module>
<java>lib/jcs-1.0-dev.jar</java>
</module>
<module>
<java>lib/odmg-3.0.jar</java>
</module>
<module>
<java>lib/oscache-2.0.jar</java>
</module>
<module>
<java>lib/swarmcache-1.0rc2.jar</java>
</module>

<!-- ================================
EJBs
===================================== -->
<module>
<ejb>ejbs/01-model.jar</ejb>
</module>

<!-- ================================
Web Application
===================================== -->
<module>
<web>
<web-uri>my.war</web-uri>
<context-root>/my</context-root>
</web>
</module>
</application>

3. Archivo de aplicación de JBoss

<jboss-app>

<module>
<service>model.sar</service>
</module>

</jboss-app>


Y con esto terminamos por hoy. Con estas instrucciones no deberías tener problemas para empezar rápidamente con Hibernate y JBoss, sobretodo si utilizais Ant y XDoclet, lo cual os aconsejo.

29.7.04

Consideraciones de diseño con JUnit

Hace tiempo que no escribo en el blog, pero es que mi actual proyecto consume todo mi tiempo. No obstante, merece la pena, porque es el más importante que he emprendido profesionalmente hablando.
Pero vamos al grano...
Aunque todavía no he terminado de entrar en la dinámica del desarrollo guiado por pruebas, al estilo de XP, hace ya tiempo que estoy "infectado por los tests". No hay duda de que el tiempo que "pierdes" escribiendo los test con JUnit es un tiempo bien empleado, puesto que luego puedes tener la tranquilidad de que si los test funcionan es más que probable que todo funcione. De hecho es la única manera de poder hacer test de regresión sin apenas esfuerzo y estar totalmente seguro de que no has introducido un bug, ni siquiera uno inducido en un módulo que no has tocado.
Sin embargo, hay algunos tipos de componente sobre los que es más complicado hacer pruebas con JUnit, sin ir más lejos los EJB (sean del tipo que sean). En general todo lo que se ejecuta sobre un contenedor es complicado de probar puesto que no es sencillo emular en nuestros juegos de pruebas las situaciones reales a las que se enfrenta el código en el contenedor.
Actualmente estoy desarrollando una aplicacion J2EE, preparando el camino para que todo pueda funcionar con WebServices, que sea muy rápida, estable y segura (como todos ;-) ).
Como servidor de aplicaciones estoy utilizando JBoss, aunque cuando el tiempo me deje y esté más maduro probaré Geronimo.
En el dilema que me planteé incialmente sobre que utilizar de J2EE estaban los Entity Beans CMP e Hibernate. Al final ha ganado Hibernate por ser más fácil de probar con JUnit, más fácil de generar y distribuir, y mucho más cercano al verdadero desarrollo orientado a objetos. Podría utilizar Entity Beans BMP que a su vez utilizaran Hibernate, pero me parece rizar el rizo e introducir complejidad innecesaria.
Sin embargo, si he decidido utilizar Stateless Session Beans, pues permiten distribuir la carga entre varios servidores de aplicaciones facilmente, pero sobre todo porque me permiten dejar el trabajo transaccional al contenedor y estar seguro de que se hace bien.
En este punto es donde de nuevo entra JUnit. Probar EJB, incluso Session Beans, es complicado. Así que al final, usar JUnit ha inducido una decisión de diseño importante, que puede implicar un pequeño coste adicional en tiempo de ejecución, pero cuyas ventajas creo que son superiores. Lo que estoy haciendo es que los Session Beans sean meros proxies de POJOs (que llamaré Business Objects) que son los que realmente tienen la lógica de negocio. Los BOs utilizan sessiones de Hibernate para realizar su trabajo, pero no realizan ningún tipo de asunción con respecto a las transacciones. De esta forma es sencillo realizar pruebas sobre los BOs fuera del contenedor, dejando que sean las clases de prueba las que manejen las transacciones de forma simple, y estar razonablemente seguros de que todo funcionará correctamente sobre el contenedor.
¿Te parece una buena solución? ¿Crees que hay una mejor?

En el próximo post detallaré el proceso de trabajo con Hibernate sobre JBoss, ya que a pesar del artículo al respecto que hay en la web de Hibernate, la realidad es algo diferente y además creo que sería muy conveniente detallar la integración del proceso con Ant, cosa que está explicada en varios sitios pero parcialmente en todos ellos.