texto - instalar fuentes en java
¿Cómo me conecto a una fuente de datos de Websphere con un nombre JNDI dado? (6)
Estoy usando Websphere Portal 7.0 y creando un portlet con RAD 8.0. Mi portlet está intentando establecer una conexión db2 con un servidor remoto. Escribí un programa Java localmente para hacer una conexión JDBC básica al servidor y obtener registros de una tabla. El código funciona bien; sin embargo, cuando agrego el código a mi portlet así como a db2jcc4.jar, la conexión no funciona. Estoy usando el básico:
Connection connection = DriverManager.getConnection("jdbc:db2://server:port/db:user=user;password=pw;");
Me imagino que usar la fuente de datos de Websphere es el camino correcto. Sé el nombre JNDI para la fuente de datos, pero no encuentro ejemplos claros sobre cómo establecer una conexión. Varios ejemplos utilizan una clase DataSource (escribí esto y esto no parece que venga de un paquete java nativo, así que, ¿qué importación uso aquí?) Junto con un Contexto. He encontrado código como:
Context ctx = new InitialContext();
ctx.lookup("jdbc/xxxx");
... ¿Puede alguien descomponer esto por mí?
EDITAR 1
He actualizado mi código por las respuestas enumeradas. Realmente creo que me estoy acercando. Aquí está mi método getConnection ():
private Connection getConnection() throws SQLException {
javax.naming.InitialContext ctx = null;
javax.sql.DataSource ds = null;
System.out.println("Attempting connection..." + DateUtil.now() );
try {
ctx = new javax.naming.InitialContext();
ds = (javax.sql.DataSource) ctx.lookup("java:comp/env/jdbc/db");
connection = ds.getConnection();
} catch (NamingException e) {
System.out.println("peformanceappraisalstatus: COULDN''T CREATE CONNECTION!");
e.printStackTrace();
}
System.out.println("connection: " + connection.getClass().getName() + " at " + DateUtil.now());
return connection;
}
Todo mi archivo web.xml se parece a:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>PeformanceAppraisalStatus</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<resource-ref>
<description>
Datasource connection to Db</description>
<res-ref-name>jdbc/db</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
Estoy viendo un error que describe exactamente lo que ustedes me están diciendo que Websphere debería pedirme que haga, pero no lo hace:
SRVE0169I: Loading Web Module: PeformanceAppraisalStatus.
[8/23/11 18:08:02:166 CDT] 00000009 InjectionProc E CWNEN0044E: A resource reference binding could not be found for the jdbc/db resource reference, defined for the PeformanceAppraisalStatus component.
[8/23/11 18:08:02:169 CDT] 00000009 InjectionEngi E CWNEN0011E: The injection engine failed to process bindings for the metadata.
Sí, sé que he malinterpretado el rendimiento como rendimiento en toda la aplicación.
SOLUCIÓN
Estaba muy cerca. Aquí están los bits faltantes que hicieron que todo cayera en su lugar:
web.xml:
<resource-ref>
<description>
Datasource connection to db</description>
<res-ref-name>jdbc/db</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<mapped-name>jdbc/db</mapped-name>
</resource-ref>
ibm-web-bnd.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0">
<virtual-host name="default_host" />
<resource-ref name="jdbc/db" binding-name="jdbc/mydatasource" />
</web-bnd>
Parece que el archivo ibm-web-bnd.xml maneja el enlace entre el nombre del recurso del proyecto y la fuente de datos en websphere. Una vez que agregué la línea:
<resource-ref name="jdbc/db" binding-name="jdbc/mydatasource" />
El portal de Websphere parecía apaciguado. Mi código está funcionando y se está conectando a la base de datos ahora.
DNS para servicios
JNDI debe abordarse con el entendimiento de que es un localizador de servicios. Cuando el servicio deseado está alojado en el mismo servidor / nodo que la aplicación, entonces su uso de InitialContext puede funcionar.
Lo que lo hace más complicado es que la definición de una fuente de datos en Web Sphere (al menos en 4.0) le permitió definir la visibilidad en varios grados. Básicamente, agrega espacios de nombres al entorno y los clientes deben saber dónde se aloja el recurso.
javax.naming.InitialContext ctx = new javax.naming.InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/DataSourceAlias");
Aquí está la página de referencia de IBM.
Si está intentando hacer referencia a una fuente de datos desde una aplicación que NO está en el contenedor J2EE, necesitará un enfoque ligeramente diferente, comenzando con la necesidad de algunos jars de clientes J2EE en su classpath. http://www.coderanch.com/t/75386/Websphere/lookup-datasources-JNDI-outside-EE
Debe definir una referencia de recurso en su aplicación y luego asignar esa referencia de recurso lógico al recurso físico (fuente de datos) durante la implementación.
En su web.xml
, agregue la siguiente configuración (modificando los nombres y las propiedades según corresponda):
<resource-ref>
<description>Resource reference to my database</description>
<res-ref-name>jdbc/MyDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Luego, durante la implementación de la aplicación, WAS le pedirá que jdbc/MyDB
esta referencia de recurso ( jdbc/MyDB
) al origen de datos que creó en WAS.
En su código, puede obtener el DataSource similar a cómo lo ha mostrado en su ejemplo; sin embargo, el nombre JNDI que usará para buscarlo debería ser el nombre de referencia del recurso que definió ( res-ref-name
), en lugar del nombre JNDI del origen de datos físicos. Además, deberá prefijar el res-ref-name con el contexto de denominación de la aplicación ( java:comp/env/
).
Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/MyDB");
Encuentre el código a continuación para obtener conexión de base de datos desde su servidor de aplicaciones web Simplemente cree una fuente de datos en el servidor de aplicaciones y use el siguiente código para obtener la conexión:
// To Get DataSource
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/abcd");
// Get Connection and Statement
Connection c = ds.getConnection();
stmt = c.createStatement();
Importar nombres y clases de sql. No es necesario agregar ningún archivo xml o editar nada en el proyecto.
Eso es..
Jason
Así es como funciona.
Localnamespace - java: comp / env es un espacio de nombre local utilizado por la aplicación. El nombre que usa en él jdbc / db es solo un alias. No se refiere a un recurso físico.
Durante la implementación, este alias debe asignarse a un recurso físico (en su caso, un origen de datos) que se define en el tiempo de ejecución de WAS / WPS.
Esto se almacena realmente en archivos ejb-bnd.xmi. En las últimas versiones, los XMI se reemplazan con archivos XML. Estos archivos se conocen como los archivos de enlace.
HTH Manglu
Para aquellos como yo, solo necesito información sobre cómo conectarse a una fuente de datos WAS (DB2) desde Java utilizando la búsqueda JNDI (IBM Websphere 8.5.5 usado y DB2 Universal JDBC Driver Provider con clase de implementación: com.ibm.db2.jcc. DB2ConnectionPoolDataSource):
public DataSource getJndiDataSource() throws NamingException {
DataSource datasource = null;
InitialContext context = new InitialContext();
// Tomcat/Possibly others: java:comp/env/jdbc/myDatasourceJndiName
datasource = (DataSource) context.lookup("jdbc/myDatasourceJndiName");
return datasource;
}
Para obtener una conexión de una fuente de datos, el siguiente código debería funcionar:
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
Context ctx = new InitialContext();
DataSource dataSource = ctx.lookup("java:comp/env/jdbc/xxxx");
Connection conn = dataSource.getConnection();
// use the connection
conn.close();
Si bien puede buscar un origen de datos como se define en la configuración de Orígenes de datos de Websphere (es decir, a través de la consola de websphere) directamente, la búsqueda desde java: comp / env / jdbc / xxxx significa que debe haber una entrada en web.xml:
<resource-ref>
<res-ref-name>jdbc/xxxx</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Esto significa que las fuentes de datos se pueden asignar en una base por aplicación y no es necesario cambiar el nombre de la fuente de datos si desea apuntar su aplicación a una fuente de datos diferente. Esto es útil cuando se implementa la aplicación en diferentes servidores (por ejemplo, test, preprod, prod) que necesitan apuntar a diferentes bases de datos.