Как мне подключиться к источнику данных 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 обрабатывает привязку между именем ресурса проекта и источником данных в websphere. Как только я добавил строку:

<resource-ref name="jdbc/db" binding-name="jdbc/mydatasource" />

Websphere Portal казался умиротворенным. Мой код работает и сейчас подключается к базе данных.


person jason    schedule 23.08.2011    source источник
comment
Было бы неплохо, если бы вы извлекли свое решение из вопроса в отдельный ответ. Это облегчило бы чтение темы.   -  person Danubian Sailor    schedule 01.10.2013


Ответы (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.

В вашем коде вы можете получить DataSource аналогично тому, как вы показали его в своем примере; однако имя JNDI, которое вы будете использовать для его поиска, должно фактически быть именем ссылки на ресурс, которое вы определили (res-ref-name), а не именем JNDI физического источника данных. Кроме того, перед именем res-ref-name необходимо указать контекст именования приложения (java:comp/env/).

Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/MyDB");
person shelley    schedule 23.08.2011
comment
@ Джейсон, какую версию спецификации сервлета использует ваше приложение? Подход, который я описал выше, должен работать для любой версии, но если вы используете Servlet 2.5 (который поддерживается в WAS 7), есть еще более простой подход, который вы можете использовать с аннотацией @Resource. - person shelley; 24.08.2011
comment
Я сделал это, но мне не было предложено связать ссылку на ресурс с источником данных в WAS. Теперь оглядываюсь вокруг WAS, чтобы увидеть, есть ли где-нибудь, чтобы сделать это вручную с настройками портлета. - person jason; 24.08.2011
comment
WAS должен запросить эту информацию, и развертывание, как правило, завершится ошибкой, если вы не сопоставите ссылки ресурсов с физическими источниками данных. Может быть, вы указали вариант включения привязок по умолчанию? У вас должна быть возможность отобразить их в ISC в разделе Приложения ›Типы приложений› Корпоративные приложения WebSphere ›[ваше_приложение]› Ссылки на ресурсы. Если вы не видите эту опцию или не видите ссылку на свой ресурс в списке, возможно, что-то неправильно настроено в вашем приложении. - person shelley; 24.08.2011
comment
RAD создаст специфичные для WAS файлы развертывания, файлы .xmi, которые автоматически сделают выбор, не позволяющий при развертывании запрашивать их у вас. Вы можете редактировать эти файлы из RAD или можете попробовать исключить их из артефактов, созданных RAD. Или, как говорит Шелли, вы можете повторно сопоставить их после развертывания. - person dbreaux; 24.08.2011
comment
Ладно, я все время говорю БЫЛО. На самом деле я загружаю файл .WAR через Admin - ›Управление портлетами из Websphere Portal. Мы говорим здесь об одном и том же? - person jason; 24.08.2011
comment
Я не знаком с WebSphere Portal, хотя думаю, что он может быть построен на архитектуре WAS. Тем не менее, вы все равно должны указать ссылку на ресурс и выполнить поиск на основе имени res-ref, как я описал. Что касается инструмента, используемого для правильного сопоставления ссылки ресурса с вашим источником данных, я не уверен, чем WebSphere Portal отличается от WAS. Я также предлагаю пояснить ваш вопрос, чтобы указать, что вы используете WebSphere Portal. - person shelley; 24.08.2011
comment
Я наткнулся на это technote, который, кажется, указывает на то, что ISC WAS доступен для WebSphere Portal. Если у вас есть доступ к нему, вы можете увидеть возможность сопоставить ссылку на ресурс, как я описал в моем комментарий выше. - person shelley; 24.08.2011
comment
Я изменил вопрос, включив в него решение, но отмечу ваш ответ как решение, Шелли. Большое спасибо за ваш постоянный отзыв по этому поводу. Это заняло бы намного больше времени без всяких комментариев, так что еще раз спасибо всем. - person jason; 24.08.2011
comment
@shelley Привет, у меня аналогичная проблема с проектом пользовательского интерфейса Maven Built, который я хочу запустить на WAS. Я пытаюсь отобразить JNDI в меню «Приложения» ›Типы приложений› Корпоративные приложения WebSphere ›[ваше_приложение]› Ссылки на ресурсы, но после того, как я нажму «Обзор», выберите jndi и нажмите «Применить», кнопки «ОК» или «Сохранить» не появятся. Можно как-нибудь об этом поговорить? У меня есть вопрос по этому поводу, если вы видите мой профиль. - person Michael Miner; 20.08.2015

Чтобы получить соединение с источником данных, должен работать следующий код:

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 (т. Е. Через консоль 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), которые должны указывать на разные базы данных.

person beny23    schedule 23.08.2011

DNS для служб

К JNDI нужно подходить с пониманием того, что это локатор сервисов. Если желаемая служба размещена на том же сервере / узле, что и приложение, то использование InitialContext может работать.

Более сложным является то, что определение источника данных в Web Sphere (по крайней мере, в версии 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

person Kelly S. French    schedule 23.08.2011
comment
Вот и все ... Я думал, что имя JNDI было своего рода ключом, который можно использовать для поиска фактической информации о соединении, но чем больше я это исследую, тем больше кажется JNDI. Я ценю объяснение на высоком уровне, но я пытаюсь найти больше конкретики. Было бы чересчур просить у ibm пример «вот как вы подключаетесь к источнику данных websphere с помощью jndi изнутри портлета» ... ‹/sarcasm› - person jason; 24.08.2011
comment
Я сочувствую тебе. Если бы у меня была под рукой моя старая кодовая база, я бы попытался опубликовать несколько реальных примеров. Как бы то ни было, знайте, что есть много движущихся частей, которые все должны выстроиться в линию, чтобы он работал. - person Kelly S. French; 24.08.2011

Джейсон,

Вот как это работает.

Localnamespace - java: comp / env - это локальное пространство имен, используемое приложением. Имя, которое вы используете в нем jdbc / db, является просто псевдонимом. Это не относится к физическому ресурсу.

Во время развертывания этот псевдоним должен быть сопоставлен с физическим ресурсом (в вашем случае источником данных), который определен во время выполнения WAS / WPS.

Фактически он хранится в файлах ejb-bnd.xmi. В последних версиях XMI заменены файлами XML. Эти файлы называются файлами привязки.

HTH Manglu

person Manglu    schedule 25.08.2011

Для таких, как я, нужна только информация о том, как подключиться к источнику данных (DB2) WAS из Java с помощью поиска JNDI (Используется IBM Websphere 8.5.5 и DB2 Universal JDBC Driver Provider с классом реализации: 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;
}
person straville    schedule 12.05.2015

Найдите ниже код, чтобы получить соединение с базой данных с сервера вашего веб-приложения. Просто создайте источник данных на сервере приложений и используйте следующий код для подключения:

// 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-файлы или редактировать что-либо в проекте.
Вот и все ..

person blackberry dev    schedule 27.05.2014