Configurando datasource de Oracle en JBoss

Autor: Javier Benek (http://blog.benek.org)
Usando:

  • JDK 1.6 u1
  • JBoss 5.0.0.Beta1
  • Oracle 10g XE

Habrá algunas veces en las que no queramos que una conexión a la base de datos esté totalmente definida en el código fuente como en el ejemplo de Marco Antonio, con todo y usuario y password por cuestiones de seguridad. Otras razones? la más importante de todas ellas es cuando manejamos más de un ambiente de desarrollo, con una base de datos para cada uno (supongamos un ambiente de desarrollo, otro de pruebas y finalmente producción). Por supuesto no son los mismos datos de conexión para una y para otra (usuario, password, sid, y en ocasiones hasta host). Hacerlo en el código fuente obviamente obligaría a cambiar esa parte del código fuente cada vez que llevemos la aplicación de un ambiente a otro.

En este caso, haré el ejemplo de configuración de datasource de Oracle con JBoss, un servidor de aplicaciones Java Enterprise.

Un DataSource es un objeto JNDI (Java Naming and Directory Interface) con el cuál obtendremos una conexión desde un Connection Pool hacia una base de datos.

Lo primero que necesitamos es obtener el jar que contiene los drivers JDBC de Oracle, ocuparemos ojdbc14.jar, el cual está optimizado para su uso con las últimas versiones del JDK: 1.4 - 1.5, mientras otros drivers como el clásico classes12.jar está optimizado para JDK 1.2 y 1.3. Lo bajaremos de aquí: http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdb...

Jboss tiene plantillas de configuraciones para diferentes DBMS, tomaremos el correspondiente a Oracle desde /docs/examples/jca/oracle-ds.xml a nuestro directorio /server/default/deploy (si utilizan el driver transaccional[XA] tomaremos oracle-xa-ds.xml).

Podemos elegir entre 4 diferentes controladores:

Oracle OCI Type 2 Driver
* Class: oracle.jdbc.driver.OracleDriver
* URL: jdbc:oracle:oci8:@

Oracle OCI Thin Type 4 Driver
* Class: oracle.jdbc.driver.OracleDriver
* URL: jdbc:oracle:thin:@::

Oracle OCI XA Type 2 Driver
* Class: oracle.jdbc.xa.client.OracleXADataSource
* URL: jdbc:oracle:thin:@::

Oracle OCI Type 2 Driver
* Class: oracle.jdbc.driver.OracleDriver
* URL: jdbc:oracle:oci8:@

La diferencia entre ellos pueden consultarla en: http://www.oracle.com/technology/tech/java/sqlj_jdbc/htdocs/jdbc_faq.htm...

Para este ejemplo, utilizaremos el driver Thin el cual nos indica que debemos configurar del modo: "jdbc:oracle:thin:@<host>:<port>:<database>", así que abriremos el archivo de configuración oracle-ds.xml antes mencionado y editamos la siguiente información:

<jndi-name>OracleDS</jndi-name>
<connection-url>jdbc:oracle:thin:@bnk:1521:XE</connection-url>

<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>usuario</user-name>
<password>password</password>

*Los datos de host, puerto y SID se encuentran en el archivo network/ADMIN/tnsnames.ora del directorio de instalación de Oracle.

Ahora editaremos el archivo standardjaws.xml propio de JBoss, que está en /server/default/conf (puede venir también como jaws.xml), ya que por default JBoss está configurado para conectar con HypersonicDB, pero este no es el caso ya que nosotros lo haremos con Oracle.

Abrimos el archivo y lo cambiamos para que quede así:

<jaws>
<datasource>java:/OracleDS</datasource>
<type-mapping>Oracle10</type-mapping>
</jaws>

También le indicamos el nombre del datasource en el archivo standardjbosscmp-jdbc.xml (puede venir como jbosscmp-jdbc.xml) y modificamos esta parte:

<datasource>java:/OracleDS</datasource>

Finalmente en el archivo login-config.xml, agregamos una <application-policy> con el nombre OracleDBRealm del siguiente modo:

<application-policy name = “OracleDbRealm”>
<authentication>
<login-module code = “org.jboss.resource.security.ConfiguredIdentityLoginModule” flag = “required”>
<module-option name = “principal”>sa</module-option>
<module-option name = “userName”>sa</module-option>
<module-option name = “password”></module-option>
<module-option name =”managedConnectionFactoryName”>
jboss.jca:service=LocalTxCM,name=OracleDS
</module-option>
</login-module>
</authentication>
</application-policy>

Ahora ya tenemos nuestro JBoss listo para poder utilizar una base de datos Oracle! :-)

Para probar rápidamente la conexión crearé una clase llamada GenericDAO, la cuál va a ser una superclase con un método que devolverá un objeto Connection utilizando la configuración que acabamos de crear.

GenericDAO.java:

package org.sintelti.dao;

import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.sql.DataSource;

/**
* Clase para crear una conexion vía JNDI a Oracle 10 XE!
*
* @author Javier Benek
* @version v0.1
*/
public class GenericDAO {
/**
* Metodo para crear y configurar una conexion!
*
* @return Se devuelve un objeto Connection con la conexion ya configurada!
*
* @throws NamingException !
*/
public Connection getConnection() throws NamingException {
Connection cnn = null;

try {
InitialContext initialContext = new InitialContext();
DataSource ds = (DataSource) initialContext.lookup(”java:OracleDS”);

try {
cnn = ds.getConnection();
} catch (SQLException sqle) {
System.out.println(
“Error obteniendo la conexión en GenericDAO: ” +
sqle.getMessage());
}
} catch (NamingException ne) {
System.out.println(
“Error en el método getConnection() de la clase GenericDAO: ” +
ne.getMessage());
}

return cnn;
}
}

Esta clase será heredada cada vez que necesitemos un objeto Connection para accesar a la BD, desde la subclase solamente llamaremos el método getConnection() para obtener la instancia de la conexión y la utilizaremos según lo que necesitemos hacer.

Aquí un ejemplo rápido.

SiiOperacionDAO:

package org.sintelti.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.NamingException;

/**
* Clase para obtener las capitales de los estados de la república.
*
* @author Javier Benek
* @version v0.1
*/
public class SiiOperacionDAO extends GenericDAO {
/**
* Metodo para generar la consulta.
*/
public void generaConsulta() {
Connection cnn = null;
Statement st = null;
ResultSet rs = null;

try {
cnn = getConnection();
} catch (NamingException ne) {
System.out.println(
“NamingException en el metodo generaConsulta() de la clase SiiOperacionDAO: ” +
ne.getMessage());
}

try {
st = cnn.createStatement();

rs = st.executeQuery(”select * from estados order by id_estado asc”);

while (rs.next()) {
System.out.println(rs.getString(”CAPITAL”));
}
} catch (SQLException sqle) {
System.out.println(
“Error SQL en el metodo generaConsulta() de la clase SiiOperacionDAO: ” +
sqle.getMessage());
}
}
}

Obviamente ahí me faltan algunas cosas como cerrar los objetos, etc, pero es un ejemplo rápido. Ya en ese punto, tenemos resuelto todo y se realizará nuestra consulta a la base de datos.

Espero que les sea de utilidad.

Saludos.