Как мне подключиться к источнику данных Websphere с заданным именем JNDI?
Я использую Websphere Portal 7.0 и создаю портлет с RAD 8.0. Мой портлет пытается установить соединение db2 с удаленным сервером. Я написал Java-программу локально, чтобы установить базовое JDBC-соединение с сервером и получить записи из таблицы. Код работает нормально; однако, когда я добавляю код в свой портлет, а также db2jcc4.jar, соединение не работает. Я использую основные:
Connection connection = DriverManager.getConnection("jdbc:db2://server:port/db:user=user;password=pw;");
Я полагаю, что использование источника данных Websphere - правильный путь. Я знаю имя JNDI для источника данных, но я не нахожу четких примеров того, как установить соединение. В нескольких примерах используется класс DataSource (я набрал его, и это не похоже на то, что он исходит из нативного Java-пакета, поэтому какой импорт я здесь использую?) В сочетании с Context. Я сталкивался с кодом, как:
Context ctx = new InitialContext();
ctx.lookup("jdbc/xxxx");
... Может кто-нибудь сломать это для меня?
РЕДАКТИРОВАТЬ 1
Я обновил свой код в соответствии с перечисленными ответами. Я действительно думаю, что становлюсь ближе. Вот мой метод 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;
}
Весь мой файл web.xml выглядит так:
<?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>
Я вижу ошибку, которая описывает то, что вы, ребята, говорите мне, Websphere должен побудить меня сделать, но это не так:
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.
Да, я знаю, что я неправильно использовал производительность в качестве приложения во всем приложении.
РЕШЕНИЕ
Я был очень близко Вот недостающие биты, которые сделали все это на свои места:
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>
Похоже, что файл ibm-web-bnd.xml обрабатывает связывание между именем ресурса проекта и источником данных в веб-сфере. Как только я добавил строку:
<resource-ref name="jdbc/db" binding-name="jdbc/mydatasource" />
Портал Websphere казался успокоенным. Мой код работает и подключается к базе данных.
6 ответов
Вам необходимо определить ссылку на ресурс в вашем приложении, а затем сопоставить эту ссылку логического ресурса с физическим ресурсом (источником данных) во время развертывания.
В вашем web.xml
добавьте следующую конфигурацию (изменив имена и свойства соответствующим образом):
<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>
Затем во время развертывания приложения WAS предложит вам сопоставить эту ссылку на ресурс (jdbc/MyDB
) к источнику данных, который вы создали в WAS.
В своем коде вы можете получить источник данных, аналогичный тому, который вы показали в своем примере; однако имя JNDI, которое вы будете использовать для поиска, на самом деле должно быть именем ссылки на ресурс, которое вы определили (res-ref-name
), а не имя JNDI физического источника данных. Кроме того, вам нужно добавить префикс ref-name к контексту именования приложений (java:comp/env/
).
Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/MyDB");
Чтобы получить соединение из источника данных, должен работать следующий код:
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();
В то время как вы можете искать источник данных, как определено в конфигурации Websphere Data Sources (то есть через консоль websphere), поиск в java:comp/env/jdbc/xxxx означает, что в файле 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>
Это означает, что источники данных могут быть сопоставлены для отдельных приложений, и вам не нужно менять имя источника данных, если вы хотите, чтобы ваше приложение указывало на другой источник данных. Это полезно при развертывании приложения на разных серверах (например, test, preprod, prod), которые должны указывать на разные базы данных.
DNS для сервисов
К JNDI нужно подходить с пониманием того, что это сервисный локатор. Когда требуемый сервис размещен на том же сервере / узле, что и приложение, использование InitialContext может работать.
Что делает его более сложным, так это то, что определение источника данных в веб-сфере (по крайней мере, в 4.0) позволило вам определять видимость в различной степени. В основном это добавляет пространства имен к среде, и клиенты должны знать, где размещен ресурс.
javax.naming.InitialContext ctx = new javax.naming.InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/DataSourceAlias");
Вот справочная страница IBM.
Если вы пытаетесь сослаться на источник данных из приложения, которое НЕ находится в контейнере J2EE, вам понадобится немного другой подход, начиная с использования некоторых jar-файлов J2EE-клиентов в вашем пути к классам. http://www.coderanch.com/t/75386/Websphere/lookup-datasources-JNDI-outside-EE
Ниже приведен код для подключения к базе данных с сервера веб-приложений. Просто создайте источник данных на сервере приложений и используйте следующий код для получения соединения:
// 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();
Импорт именования и sql классов. Нет необходимости добавлять какие-либо XML-файлы или редактировать что-либо в проекте.
Это оно..
Джейсон,
Вот как это работает.
Localnamespace - java: comp / env - это локальное пространство имен, используемое приложением. Имя, которое вы используете в нем, jdbc/db - это просто псевдоним. Это не относится к физическому ресурсу.
Во время развертывания этот псевдоним должен быть сопоставлен с физическим ресурсом (в вашем случае источником данных), который определяется во время выполнения WAS/WPS.
Это на самом деле хранится в файлах ejb-bnd.xmi. В последних версиях XMI заменены файлами XML. Эти файлы называются файлами привязки.
HTH Манглу
Для таких, как я, нужна только информация о том, как подключиться к источнику данных WAS (DB2) из Java с использованием поиска JNDI (Использовался IBM Websphere 8.5.5 и поставщик универсальных драйверов DB2 JDBC с классом реализации: 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;
}