Página principal del curso de XML
Otros cursos y tutoriales: comercio electrónico, WAP, Webmaster
Página principal del grupo GeNeura

Entornos de transcodificación: Cocoon

J. J. Merelo

Introducción: de qué estamos hablando

Cocoon es un entorno de publicación y transformación de documentos XML basado en Java. Cocoon funciona como un servlet, o sea, que en principio, se podrá ejecutar desde cualquier servidor que pueda contener servlets, tales como el Apache, que es el mejor con diferencia, el Internet Information Server, o, incluso, si me apuráis, el Roxen, aunque no he oido a nadie que haya conseguido hacer funcionar Cocoon con Roxen.

Los servlets son hebras en Java, que se ejecutan en el mismo contexto que el servidor; por lo tanto, es más rápido de ejecutar que otros métodos tales como los CGIs; y además, son persistentes, o sea que no hace falta cargarlos. Para más información, se puede mirar la FAQ de los servlets.

El nombre de Cocoon viene de la película, y se le ocurrió al autor inicial de Cocoon, Stefano Mazocchi, porque precisamente después de ver dicha película decidió hacer un entorno de publicación basado en XML, cuando casi nadie tenía todavía claro qué era eso del XML. Por eso ha tenido tanto éxito, y hoy en día es uno de los más completos.

La versión actual, en febrero de 2001, es la 1.8.2, con ligeras modificaciones con respecto a la 1.8 y algunos bugfixes respecto a la 1.8.1. Ya hay alfas de la siguiente versión, la 2.0, que permitirá transformaciones más completas a partir de los URL, e incorporará los últimos estándares.

Cocoon incluye lo siguiente:

El procesamiento que lleva a cabo Cocoon se hace en tres fases:

Internamente, Cocoon procesa las peticiones de la forma siguiente:

La mayoría de los sitios Cocoon son sitios de producción; hay una lista bastante completa en el sitio de Cocoon ; también hay una lista de proveedores comerciales con Cocoon. Nosotros lo usamos en el sitio de enseñanza http://genmagic.ugr.es:8080 y de "producción" en http://mercurio.ugr.es:8080.

Contenido de esta sección
  • Instalando Tomcat.
  • Instalando Tomcat con Apache.

Instalando el Tomcat

El Tomcat es el contenedor de servlets que hemos elegido para insertar el cocoon; habrá que instalarlo antes. Para empezar, hay que bajárselo. Te lo puedes bajar de dos sitios, principalmente:

Hay varias versiones en danza de Tomcat (en febrero de 2001): la 3.1.1, la 3.2.1, la 3.3, que es la que está en desarrollo actual (y en el milestone 1), y la 4.0, que actualmente está en alfa. Nosotros usaremos en este tutorial la 3.2.1.

A partir de ahora, todas las instrucciones de instalación serán para una máquina con el sistema operativo Linux, en concreto, la distro RedHat 7.0. Debería funcionar en todos los Linux, e incluso en todos los Unices. Si tienes la desgracia de tener alguna versión de Windows, mira en la página de instalación original.

En realidad, instalar el Tomcat no puede ser más fácil. Simplemente se descomprime (o se instala el RPM), se cambia uno al directorio de Tomcat, por ejemplo, /usr/local/jakarta-tomcat, y simplemente hay que indicarle dónde hemos metido la máquina virtual java. Se edita el fichero tomcat.sh y se insertan dos líneas tales como las siguientes:export TOMCAT_HOME=/usr/local/jakarta-tomcat-3.2.1/ export JAVA_HOME=/usr/local/jdk1.2.2, que definen dos variables de entorno que indican dónde se puede encontrar el directorio raíz del Tomcat y el de la JVM. En Windows, se tendrá que hacer algo similar. A partir de ese momento, ya se puede ejecutar bin/startup.sh para arrancar el servidor en el puerto 8080 y bin/shutdown.sh para pararlo. Al ejecutarlo, saldrá algo así: maquina:/usr/local/jakarta-tomcat/bin# startup.sh Using classpath: /usr/local/jakarta-tomcat/[mogollón de .jar aquí]... 2001-02-02 02:48:18 - ContextManager: Adding context Ctx( /examples ) 2001-02-02 02:48:18 - ContextManager: Adding context Ctx( /admin ) 2001-02-02 02:48:18 - ContextManager: Adding context Ctx( /cocoon ) Starting tomcat. Check logs/tomcat.log for error messages 2001-02-02 02:48:18 - ContextManager: Adding context Ctx( ) 2001-02-02 02:48:18 - ContextManager: Adding context Ctx( /test ) 2001-02-02 02:48:19 - PoolTcpConnector: Starting HttpConnectionHandler on 8080 2001-02-02 02:48:19 - PoolTcpConnector: Starting Ajp12ConnectionHandler on 8007 2001-02-02 02:50:26 - Ctx( ): 404 R( + /Cocoon.xml + null) null Además, si usamos el url http://localhost:8080 debería salir la página de Tomcat.

Algo que sí puede convenir tocar en server.xml, sobre todo si no hay mucha memoria disponible, es el número de hebras disponibles para conexión. Por defecto, se lanzan hasta 50, lo cual puede chupar del orden de 600 megas de memoria (aunque usa memoria virtual). Para cambiarlo, hay que cambiar la configuración de todos los Connector, cambiando el número de hebras que pueden usar:<Parameter name="max_threads" value="5"/>. Hay tres conectores; se puede cambiar el número de hebras de cualquiera de ellos, aunque yo no he conseguido bajar de 180 megas el consumo de memoria.

La configuración de Tomcat está en los ficheros que cuelgan del directorio $TOMCAT_HOME/conf; el principal es el server.xml, que, casualmente, está escrito en XML. Este fichero contiene toda la configuración del servidor, y define los conectores,contextos, y, en general, toco lo que necesita un servidor. En principio, no hay que tocarla para nada, pero sí más adelante cuando decidamos instalar el Cocoon.

Tal cual lo hemos instalado, ya podemos servir directamente páginas JSP, servlets, y, por supuesto, páginas HTML; el problema es que si queremos hacer algo fuera de eso, por ejemplo CGIs, o incluso si queremos tener un servidor "serio", gestionando varios dominios virtuales, con PHP, CGI y lo que se nos ocurra, necesitamos usar eso precisamente, un servidor serio, tal como el Apache, dentro del cual Tomcat se usará como contenedor de servlets. En ese caso, tenemos que instalar el módulo mod_jk de Apache, para manejar la interacción entre Apache y Tomcat.

Se pueden cambiar también los puertos que se van a usar, sobre todo si hay problemas de colisión con otros usuarios, o simplemente se quiere usar el puerto por defecto, que es el 80. Habrá que modificar las líneas siguientes del fichero server.xml: <Connector className="org.apache.tomcat.service.PoolTcpConnector"> <Parameter name="handler" value="org.apache.tomcat.service.http.HttpConnectionHandler"/> <Parameter name="port" value="8080"/> </Connector> y cambiar el valor por defecto, que es 8080, por el valor que se desee, tal como 18335 (máximo 65535). Igualmente se pueden cambiar los valores de los puertos de los otros tres conectores: el 8043, que es el que se usa en las conexiones SSL, y el del conector AJP12, que además se usa para cerrar Tomcat.

Teóricamente, la instalación de mod_jk es simple. Consiste en bajarse el mod_jk.so desde el sitio web, copiarlo a /directorio/de/apache/libexec/mod_jk.so, y hacer lo siguiente:

Como se suele decir, hay otros contenedores de servlets, pero no son Tomcat. Se puede encontrar un listado completo en servlets.com. Entre ellos, destaca Enhydra, otro servidor Open Source, y Jetty. Los demás suelen ser de pago, y además, bastante caros. Por su popularidad, destacan Bea Weblogic y el IBM Trancoding Publisher. Con todos ellos se puede instalar Cocoon, siguiendo las instrucciones de la página web, o bien instalándolo como cualquier otro servlet.

Ejercicios
1. Instalar Tomcat, usando el paquete especial para el curso en ~jmerelo/cursoxml-tomcat-cocoon.tgz. Descomprimirlo en el directorio propio, y lanzar el servidor de servlets, usando los puertos indicados por el profesor. El número máximo de hebras permitidas por conector serán 2.

Contenido de esta sección
  • Instalando Cocoon con Tomcat
  • .
  • Instalando Cocoon con Tomcat y Apache.

Instalación de Cocoon

El siguiente paso es instalar Cocoon junto con Tomcat; en realidad, no hace falta Apache, porque Cocoon es simplemente un servlet con su propio contexto dentro de Tomcat. Después de bajarnos el cocoon , en su distribución binaria, lo descomprimimos en un directorio, por ejemplo, el /usr/local. Para que funcione con Tomcat, hay que añadir los .jar a los que coge Tomcat cuando arranca. Se hace lo siguiente ($TOMCAT_HOME es el directorio donde está Tomcat, y $COCOON_HOME donde está Cocoon): mkdir $TOMCAT_HOME/webapps/cocoon mkdir $TOMCAT_HOME/webapps/cocoon/WEB-INF cp $COCOON_HOME/bin/cocoon.jar $TOMCAT_HOME/lib cp $COCOON_HOME/lib/*.jar $TOMCAT_HOME/lib cp $COCOON_HOME/src/WEB-INF/web.xml $TOMCAT_HOME/webapps/cocoon/WEB-INF cp $COCOON_HOME/conf/cocoon.properties $TOMCAT_HOME/webapps/cocoon/WEB-INF cp -R $COCOON_HOME/samples $TOMCAT_HOME/webapps/cocoon/samples .

A continuación, hay que cambiar unos cuantos ficheros:

Lo más probable es que a la primera no funcione. La fuente más probable de conflictos es el parser XML que lleva el propio Tomcat, que entra en conflictos con el parser XML que incluye cocoon. Para evitarlo, cambiar de nombre parser.jar a zzz.jar.

Si Tomcat está arrancado, se para, y si no lo está, se vuelve a arrancar otra vez. El URL http://localhost:8080/cocoon/Cocoon.xml debería devolver una página de estado del Cocoon. Si no es así, dice fichero no encontrado, o alguna gaita de esas, es que la has fastidiado en algún sitio. Vuelve a empezar.

Por supuesto, ya que tienes instalado el Apache con Tomcat, igual también te da porque funcione el Cocoon+Apache+Tomcat. En ese caso, tendrás que agarrar el fichero mod_jk.conf-auto y copiarlo, por ejemplo, a mod_jk.mio.conf, porque ese fichero se genera cada vez que se ejecuta el Tomcat, y modificarlo de la forma siguiente:
Si no te gusta el protocolo ajp12, puedes usar el ajp13, que se supone que es más rápido, y usa SSL, y más guay y todo. Pero hay que cambiar más cosas en la configuración, asín que mejor nos estamos quietecitos.
JkMount /cocoon/*.xml ajp12 AddType text/xml .xml #JkMount /cocoon/servlet/* ajp12 #JkMount /cocoon/*.jsp ajp12 , es decir, comentar las dos líneas que se indican, y añadir las otras dos. Con esas dos líneas se indica que todos los ficheros que tengan xml como extensión serán manejados por el "trabajador" ajp12, y que además, Apache tendrá que servir los ficheros XML como XML, para que se enteren los navegadores que manejen XML. Al final de todo esto, podremos llamar al URL de cocoon en htp://localhost:9000/cocoon/Cocoon.xml.

Usando Cocoon

Una muestra de cómo se puede usar Cocoon se puede ver directamente tras la instalación en http://localhost:8080/cocoon/samples/index.xml; Cocoon puede servir directamente páginas web, o aplicarles simples hojas de estilo. Si queremos servir la siguiente página XML ( hola.xml): <?xml version="1.0" encoding='ISO-8859-1'?> <?xml-stylesheet href="hola.xsl" type="text/xsl"?> <?cocoon-process type="xslt"?> <page> <title>Hola</title> <contenido> <para>Mi primera página Cocoon</para> </contenido> </page> Este código referencia la <a href='hola.xsl'>hoja de estilo hola.xsl, que indica como se tiene que transformar para que se presente en una página XML. Para indicar a Cocoon cómo tiene que procesar una página, tienen que incluirse las líneas siguientes:<?xml-stylesheet href="hola.xsl" type="text/xsl"?>, que indica dónde encontrar la hoja de estilo que procesa la página XML; y la siguiente <?cocoon-process type="xslt"?>, que le indica a cocoon que tiene que llamar al procesador XSLT para que procese esa página.

Otros procesos posibles, que por tanto se pueden y deben usar como opción en cocoon-process en Cocoon son los siguientes:

Esos ficheros, tal como hemos configurado anteriormente el tomcat, tendrán que ir en $TOMCAT_HOME/webapps/cocoon, o cualquier otro directorio que cuelgue de él, o que tenga un link simbólico desde ese directorio. Simplemente colocándolos en un directorio así, obtendremos una salida similar a esta o a través de Cocoon.

Contenido de esta sección
  • Tags específicos de Cocoon
  • .

Procesadores en Cocoon

Cocoon incluye una serie de etiquetas, con sus espacios de nombres correspondientes, que están en realidad implementados como programas en Java. Estas etiquetas se pueden usar tanto en los ficheros XML como en los XSL; en estos ejemplos los usaremos simplemente dentro de los ficheros XML. Las etiquetas están divididas en espacios de nombres, cada una con un fin específico.

La etiquetas request permiten acceder al contexto de la petición del fichero XML, es decir, a lo que en un CGI correspondería a las variables de entorno y a lo que se introduce en la línea de comandos. Por ejemplo, el fichero siguiente request.xml <?xml version="1.0" encoding='ISO-8859-1' ?> <?cocoon-process type="xsp"?> <xsp:page xmlns:xsp="http://www.apache.org/1999/XSP/Core" xmlns:request="http://www.apache.org/1999/XSP/Request" > <html> <head><title>Prueba del tag request</title></head> <body> <p>La petición se ha hecho con los siguientes parámetros:<ul> <li>Nombre de los parámetros: <request:get-parameter-names /></li> <li>La petición se ha hecho desde: <request:get-remote-addr /> con nombre <request:get-remote-addr /> </li> <li>La petición completa es: <request:get-query-string /></li> </ul></p> </body> </html> </xsp:page> Este fichero se trata de XML estándar, salvo que usa espacios de nombres. Primero, en la segunda línea, hay que indicarle a Cocoon que se van a usar los XSP; aunque en este caso no estemos incluyendo código java, en realidad los tags de request se procesan como XSPs. Por eso hay que incluir la etiqueta xsp:page rodeando a todo el código. En esa etiqueta se declaran también los espacios de nombres que se usan, y los prefijos correspondientes: xsp, y request.

Los tags se usan propiamente dentro de la página XML, que en realidad es simplemente una página HTML "bien formada" (para no tener que usar hojas de estilo). Las etiquetas acceden al contexto del servlet, lo cual corresponde, grosso modo, a la clase request del mismo; todos los métodos de la clase están disponibles como diferentes etiquetas. Si todo va bien, el resultado debería ser tal como en esta página, o algo así: La petición se ha hecho con los siguientes parámetros: Nombre de los parámetros: param2param1 La petición se ha hecho desde: 10.10.103.98 con nombre 10.10.103.98 La petición completa es: param1=pepe¶m2=juan

De la misma forma se pueden usar los tags util, que como el anterior, no está documentado, sino que hay que mirar cómo se usa en los ejemplos y en los fuentes para ver qué es lo que hace. Por ejemplo, el fichero siguiente: util.xml 4 <xsp:page 5 xmlns:xsp="http://www.apache.org/1999/XSP/Core" 6 xmlns:util="http://www.apache.org/1999/XSP/Util" 7 > 9 <html> 10 <head><title>Prueba del tag util</title></head> 11 <body> 12 <h1>Petición hecha a la hora <util:time format="dd/MM/yyyy hh:mm:ss" /></h1> 13 <p>Este es un fichero externo <util:include-file name='inc.xml' /> </p> 14 <p>Ya has pedido esta página <util:counter /> veces, ¡so pesao!</p> 15 </body> 16 </html> 17 18 </xsp:page> . La estructura es bastante similar a la anterior, salvo que se declara el namespace util en vez del request; en cuanto a las peticiones, dan, por este orden, la hora con un formato determinado (y no se puede omitir la cadena de formato), incluyen un fichero externo, que debe ser XML, y además te cuenta las veces que ha pedido la página. Esto último es posible porque en realidad cada página XML se convierte en un servlet (lo cual puede dar lugar a múltiples problemas cuando se trata de recargar una página que uno ha modificado), y en realidad se contará mientras esté ejecutándose el servidor. La salida que dará está en el servidor, pero en todo caso será algo similar a esto.

Ejercicios
1. Hacer una página XML que incluya las etiquetas anteriores; por ejemplo, que muestre la hora, los parámetros que se le pasan, y demás. Una mezcla de los dos ejemplos anteriores.

Agradecimientos

Agradezco a los participantes del grupo de correo JUGAnd, de usuarios de Java en Andalucía, su ayuda a la hora de instalar Tomcat y Cocoon, y sus críticas de este tutorial.

Bibliografía y enlaces relacionados con Cocoon

Una de las pocas cosas que se encuentran en castellano son Usando PHP y XML con Apache Cocoon, que explica como usar todas esas cosas juntas.

El libro Java y XML, de Brett MacLaughlin, es bastante interesante en todo lo que se reviere a XML y Java, e incluye un capítulo dedicado al cocoon.