miércoles, 14 de septiembre de 2011

Aplicacion web en medio de solo/lectura (CD) con Jetty y Derby. Parte 2: Implementación

Sin más preámbulos más que la referencia a la primera parte de este post que fue la motivación vamos directamente a la implementación.

Aquí esta lo que necesitaremos y utilizaremos:
  • Java JDK instalado (versión utilizada 1.6) con su respectiva versión de JRE (máquina virtual)
  • Jetty (versión utilizada 6.1.22).
  • Proyecto web Java construido (Puede ser el war, pero nosotros utilizaremos el proyecto con los fuentes compilados, como el que genera NetBeans en el directorio build/web del proyecto para este ejemplo)
  • Derby (versión utilizada 10.5.3.0)
Pasos a seguir:
  • Paso 1: Tener instalado y funcionando el Java JDK.
  • Paso 2: Configurar Jetty para su uso en medio de sólo lectura
  • Paso 3: Preparar proyecto web Java: configuración para uso de base de datos embebido con Derby.
  • Paso 4: Preparar Base de Datos con Derby 
  • Paso 5: Como almacenar.
  • Paso 6: Como ejecutar.


Paso 1: Tener instalado y funcionando el Java JDK.

Este paso me imagino todos los javeros ya deben tenerlo cumplido, y los que no, deben hacerlo. Hago énfasis porque es importante que estén incluidas las variables de entorno en el path del sistema para evitar cualquier conflicto de ejecución tanto en Windows como en Linux. Esto es que además de tener instalada la máquina virtual, asegurarse de tener variables como JAVA_HOME definidas en el sistema, tanto en Linux como en Windows.

Paso 2: Configurar Jetty para su uso en medio de sólo lectura

Hay que descargar el archivo con el servidor embebido Jetty desde aqui y descomprimir. En la estructura e directorios buscamos el archivo JETTY/etc/jetty.xml, donde  JETTY es el directorio raíz donde esta desempaquetada la aplicación,  y nos vamos a la parte del log y comentamos de la siguiente manera:
<!--==================================== -->
<!-- Configure the Request Log-->
<!--==================================== -->
<!--
<Set name="RequestLog">
[snip]
</Set>
-->


Así comentamos la parte que activa el log de Jetty para que no intente guardar el log en nuestro medio de solo lectura, como lo es un CD.


Paso 3: Preparar proyecto web Java: configuración para uso de base de datos embebido con Derby 


Esto puede ser cualquier proyecto web hecho en cualquier IDE, en mi caso tomé un proyecto hecho en NetBeans y compilado con ant al cual llamaremos PROYECTONETBEANS (ruta que contiene la estructura del proyecto web java en Netbeans, con directorios como build, dist, lib, src, web, etc. ). Por lo tanto aquí supondremos que esta debidamente creado el proyecto y con las librerías necesarias (Incluyendo el jar del driver jdbc para usar Derby)

Yo utilicé el framework Hibernate para utilizar mi base de datos con un manejador Derby, pero se puede hacer con o sin Hibernate y usar la clase JDBC de manera directa para poblar la base de datos con Derby en nuestro programa e incluso utilizar cualquier otro cliente para manipular la base de datos fuera de nuestro programa.

Ahora lo que hay que hacer para utilizar nuestra base de datos de manera embebida en el medio de sólo lectura es cambiar la manera en como se carga el driver del jdbc (Controlador para Java de la base de datos). Esto lo hacemos donde definimos el driver esto es:
  • Si estas usando Hibernate como en mi caso hay que modificar el archivo de configuración "hibernate.cfg.xml". Yo tenía esta configuración en mi archivo al usarlo de manera local:
<property name="hibernate.connection.driver_class" >org.apache.derby.jdbc.EmbeddedDriver</property>
<property name="hibernate.dialect" >org.hibernate.dialect.DerbyDialect </property>
<property name="hibernate.connection.url" >jdbc:derby:directory:derbytestbd;create=true;territory=es_MX;collation=TERRITORY_BASED </property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>

Cambié el valor de la propiedad "hibernate.connection.url" por: "jdbc:derby:classpath:/derbytestbd;territory=es_MX;collation=TERRITORY_BASED" . Con esto queda configurado el sistema para usar la base de datos embebida con Derby en el medio de solo lectura.
  • En caso de que estés utilizando el driver JDBC directamente desde alguna clase lo único que tienes que hacer es cambiar el texto del Driver de Derby. Esto sería cambiar la línea 1 a la línea 2: 
Linea 1:
Connection conn = DriverManager.getConnection("jdbc:derby:directory:derbytestbd;create=true;territory=es_MX;collation=TERRITORY_BASED","root","");


Linea 2:
Connection conn = DriverManager.getConnection("jdbc:derby:classpath:/derbytestbd;territory=es_MX;collation=TERRITORY_BASED","root","");



Se puede observar como en ambos casos utilicé un usuario "root"  sin contraseña (vacío).

Una  vez hecho esto simplemente copiamos el directorio donde esta nuestro proyecto al directorio de Jetty. Esto sería copiar el directorio con los archivos compilados del proyecto web, en mi caso copiar el contenido de PROJECTONETBEANS/build/web a un JETTY_HOME/webapp/miproyecto , estamos pasando todos los jsp's y directorios WEB-INF y META-INF que son necesarios para que nuestra aplicación web funcionara en un contenedor tomcat por ejemplo.

Paso 4: Preparar Base de Datos con Derby

Debemos preparar la base de datos para que funcione en el medio de solo lectura.

Para empezar a manipular la base de datos es importante que  hayamos finalizado cualquier cliente que pudiera estar conectado y haciendo uso de nuestra base de datos.

Nuestra base de datos se llama "derbytestbd" entonces este es el nombre del directorio que contiene nuestra base de datos derby en la ubicación que lo hayamos creado. Dentro de este directorio antes de copiarlo debemos borrar el archivo directorio derbytestbd/tmp (sólo el tmp), el cual puede o puede no existir, así que no se preocupen si no existe.

Una vez hecho esto nos disponemos a crear el jar con los archivos de la base de datos. La mejor manera es utilizando el comando jar de la siguiente manera:

$ jar cMf derbytestbd.jar derbytestbd

Para más información de como crear un jar con tu base de datos Derby checar el Tema de la documentación de Derby "Transferring read-only databases to archive (jar or zip) files"

Donde derbytestbd es el directorio donde esta nuestra base de datos Derby y derbytestbd.jar es el nombre del nuevo archivo jar que se creará con nuestra base de datos para el medio de solo lectura.

Continuamos copiando nuestro nuevo archivo jar "derbytestbd.jar" en donde tenemos nuestro proyecto preparado para el medio de sólo lectura, es decir donde esta nuestra aplicación Jetty. Entonces copiamos derbytestbd.jar a JETTY_HOME/webbapp/miproyecto/WEB-INF/lib y así el jar de nuestra base de datos quede ligado al classpath de nuestra aplicación.

Paso 5: Como almacenar.

¡Listo! ya tenemos nuestro proyecto preparado para utilizarlo en un medio de sólo lectura. Para almacenarlo solo es necesario copiar el directorio completo JETTY_HOME al medio de almacenaje que deseemos. En este tutorial se indica que sea en un CD, pero se puede copiar a una memoria USB, disco portátil, etc. Así que tal cual se oye, técnica "copy&paste" y ¡ya!.


Paso 6: Como ejecutar.

Para ejecutar unicamente es necesario correr el servidor Jetty utilizando el archivo jar JETTY_HOME/start.jar ejecutandolo de la siguiente manera:

$ java -jar start.jar

Para más información de como ejecutar o utilizar el servidor Jetty acceder a la página oficial del proyecto aquí.

De esta manera iniciamos el servidor Jetty en la computadora donde estemos. Ahora es necesario acceder a nuestro proyecto, lo cual lo haremos a través de un navegador web ingresando a la siguiente url (Con las opciones por default de Jetty): "localhost:8443/miproyecto"

Si todo sale bien estarás viendo tu proyecto corriendo desde un medio de sólo lectura de manera embebida en un servidor Jetty :D


Notas finales

Algunas consideraciones que pueden ayudar en caso de algún error:
  •  El tutorial del que tomé la mayoría de las cosas les puede ser útil también y lo encuentran aquí.
  • Es importante que los jar's necesarios para la aplicación estén incluidos en el directorio miproyecto/WEB-INF/lib , si algún problema con alguna dependencia esta fallando, revisar eso o el CLASSPATH para corregir problemas con dependencias.
  • Cualquier comentario extra o duda pueden externarla, espero con gusto poder ayudar.