Resolución de Cannot create JDBC driver of class » for connect URL ‘null’ en Tomcat

19 de junio de 2008

Durante el arranque de Tomcat, cuando la aplicación web lleva asociada una conexión a una base de datos, uno se puede encontrar un error con el siguiente mensaje

Cannot create JDBC driver of class » for connect URL ‘null’

Si aparece este mensaje, no se ha iniciado la conexión a la base de datos y, por lo tanto la aplicación no funciona.

Este error se puede dar cuando se realiza un cambio de versión, de un Tomcat 4.1.27/5.0.x a un Tomcat 5.5.x/6.0.x y no se tiene cuidado en adecuar las aplicaciones web a la nueva versión.

El problema viene del cambio de estructura del xml de configuración de los contextos, context.xml. Concretamente, el elemento Resource pasa de definirse en 2 elementos, Resource y ResourceParams, a uno solo, Resource, dónde los parámetros son atributos de este único elemento. A continuación se puede ver la diferencia entre las dos configuraciones para una conexión a una base de datos en postgres

Tomcat 4.1.27/5.0.x

	<Resource
        name="jdbc/BaseDeDatosPool"
        auth="Container"
        type="javax.sql.DataSource"
    />
    <ResourceParams name="jdbc/BaseDeDatosPool">
        <parameter>
            <name>driverClassName</name>
            <value>org.postgresql.Driver</value>
        </parameter>
        <parameter>
            <name>url</name>
            <value>jdbc:postgresql://127.0.0.1/mibasededatos</value>
        </parameter>
        <parameter>
            <name>username</name>
            <value>postgres</value>
        </parameter>
        <parameter>
            <name>password</name>
            <value></value>
        </parameter>
        <parameter>
            <name>maxActive</name>
            <value>20</value>
        </parameter>
    </ResourceParams>

Tomcat 5.5.X/6.0.x

<Resource name="jdbc/BaseDeDatosPool" auth="Container"
	type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
	url="jdbc:postgresql://127.0.0.1/mibasededatos"
	username="postgres" password="" maxActive="20"/>

Tomcat, al parsear el xml para inicializar el recurso, encuentra un error en el context.xml y la cadena de error que proporciona es Cannot create JDBC driver of class » for connect URL ‘null’, que en un principio puede despistar porque no resulta claro. Basta con adecuar el xml de configuración a la versión de Tomcat que se está utilizando para que deje de producirse.

El error se produce cuando el context.xml está malformado en la definición de recursos, por lo que se puede producir por otras causas diferentes de una cambio de versión, pero he centrado esta entrada en esta causa porque suele ser la más común

Configuración del juego de caracteres (charset) en una aplicación web en Tomcat

1 de abril de 2008

En este artículo se describen los pasos necesarios para la correcta configuración en UTF-8 de los juegos de caracteres una aplicación y los distintos componentes que intervienen en una arquitectura cliente/servidor de un servidor web. El procedimiento sería similar en el caso de que el juego de caracteres elegido fuera el ISO8859-1. Para la configuración de este artículo se ha utilizado el servidor web Tomcat versión 6.0.16 y Postgresql como motor de base de datos.

A continuación se muestra la figura con un esquema de todos los componentes. En esta figura se marcan los distintos componentes con números (en rojo) para poder referenciarlos en las descripciones que siguen.

Codificacion de Caracteres

Configuración del Servidor Web (Tomcat)

Se puede modificar el charset de la máquina virtual donde se ejecute el servidor, añadiendo como opción de ejecución en JAVA_OPTS el parámetro -Djava.file.encoding=UTF-8 (0). Si se trata del Tomcat, se debe añadir al fichero catalina.sh o catalina.bat según el sistema operativo.

Este valor no se tiene en cuenta en la máquina virtual de Sun 1.4.x, porque al parecer se trata de una propiedad de solo lectura en numerosas máquinas virtuales (leido en los foros del Tomcat). Sí parece activarse en la máquina virtual de Sun 1.5.x.

En principio no parece necesario modificar el charset de la máquina virtual, porque ninguna prueba realizada demuestra que se tenga en cuenta para las operaciones de codificación de caracteres en un intercambio cliente/servidor. En cambio, sí que afecta a otros aspectos de las aplicaciones, como la codificación de caracteres utilizada para escribir en el log por la librería log4j.

Si por alguna razón se produjera algún problema en la codificación de caracteres, se puede intentar modificar este parámetro para encontrar la solución. Si se hace, puede que sea necesario modificar la codificación de caracteres del elemento appender del log4j.

Para fijar este parámetro:

  • En Windows: Edita el fichero %CATALINA_HOME%\bin\catalina.bat y añade la siguiente línea:
rem ----- Execute The Requested Command -----
echo...
echo...
set...
set JAVA_OPTS=%JAVA_OPTS% -Djava.file.encoding=UTF-8
  • En Linux: Edita el fichero $CATALINA_HOME/bin/catalina.sh y añade al principio la siguiente línea.
JAVA_OPTS="$JAVA_OPTS -Djava.file.encoding=UTF-8

Para modificar la configuración del log4j: Añadir el atributo encoding del elemento appender utilizado, asignándole el valor ISO8859-1, en el fichero de configuración:

  • En xml, añadir dentro del elemento appender:
 
  • En properties:
log4j.appender.file.encoding=ISO8859-1

El navegador efectúa un GET sobre el servidor.

En un petición de tipo GET, los parámetros se encuentran en la URL (query string). Para que se ejecute correctamente, los parámetros hay que codificarlos correctamente al construir la url del GET y luego que el servidor los decodifique correctamente antes de pasárselos al correspondiente Servlet.

  • (1) La codificación de los parámetros en la url se debe realizar al construir el html de cada página. Para ello se pueden utilizar el método encode de la clase java.net.URLEncoder al que se le suministra como parámetro el juego de caracteres (UTF-8)
  • (2) La decodificación de los parámetros de la URL se realiza en el conector de Tomcat, tanto el 8080 como el de ssh 443, configurado en el archivo server.xml mediante
 

El navegador efectúa un POST sobre el servidor.

La codificación de los parámetros se realiza en el navegador. Para que el navegador sepa en qué juego de caracteres tiene que codificar los parámetros del POST que envía, el html tiene que tener la siguiente cabecera (3), que se tiene que incluir en el jsp de incluya las cabeceras (4)

 

Al recibir los parámetros de un POST, el servlet que se encarga de recibir la petición tiene que fijar el juego de caracteres en el que llega la petición. En el caso de una aplicación que usa Struts o cualquier aplicación web que utilice el modelo MVC en el que todas las peticiones pasan por el elemento Controller, esta operación se debe realizar en dicho elemento, en el caso de Struts el servlet que extienda al ActionServlet (5).

request.setCharacterEncoding("UTF-8");

Precompilación de los JSP

Los Jsp se pueden precompilar opcionalmente para convertirlos en servlets. En este caso, es necesario precompilarlos utilizando el juego de caracteres que se utiliza en la máquina donde se están editando, que no suele ser UTF-8, sino ISO8859-1. Esto se hace para que los archivos precompilados mantengan el juego de caracteres en el que fueron escritos a la hora de convertirse en servlets. Este juego de caracteres no es que utiliza por defecto la precompilación (UTF-8). Por lo tanto es necesario especificarlo (9):

  • En el caso de que los compile el servidor web, Tomcat, según vaya necesitando estos jsp, se utiliza el parámetro javaEncoding que se le debe suministrar al servlet encargado de la precompilación, JspC o Jikes en archivo web.xml general de Tomcat, servlet org.apache.jasper.servlet.JspServlet.
javaEncoding
ISO-8859-1
  • En el caso de que los jsp se precompilen mediante la tarea de ant jasper2, es necesario suministrarle a esta tarea el parámetro javaEncoding:
 

Acceso a los datos

Los datos deben estar guardados en una base de datos acorde con el juego de caracteres que se pretenda usar (6). UNICODE en el caso de UTF-8 para Postgresql. Este juego de caracteres se especifica al crear la base de datos.

Además, para el acceso a la base de datos, se debe configurar el driver para que utilice el juego de caracteres correctos en el intercambio de datos (7). Esta configuración se realiza en el archivo context.xml. Para el caso de PostgreSQL parece que no es necesario especificar el juego de caracteres para una base de datos UNICODE.

Visión correcta en el navegador de la respuesta

Para que el navegador muestre correctamente el contenido del html generado (8.1), necesita saber el juego de caracteres del html. Este proceso se realiza al decodificar la respuesta del servidor de acuerdo a la cabeceras HTTP de respuesta de tipo de contenido, Content-Type (8.2) según se puede ver en el siguiente ejemplo de cabecera HTTP de respuesta:

HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 2540
Date: Wed, 30 Mar 2008 19:53:00 GMT

Para que esta cabecera HTTP se incluya en la respuesta, se debe incluir en el código lo siguiente, dependiendo de si se trata de un servlet o un jsp:

  • (8.3) JSP. En un jsp que se incluya en todos los html de respuesta, hay que incluir
&lt;%@ contentType="text/html"; charset="UTF-8" %&gt;
  • (8.4) Servlet. Al enviar la respuesta:
response.setContentType("text/plain; charset=UTF-8");
java.io.PrintWriter out = response.getWriter();
out.print(responseStr);
response.flushBuffer();
out.close();

Nueva versión de Tomcat

28 de febrero de 2008

El pasado 8 de febrero el equipo de desarrolladores de Tomcat anunciaron el lanzamiento de la versión 6.0.16 de su servidor web