Путь JNDI Tomcat против Jboss

У меня есть DataSource, который настроен на Tomcat 6 в context.xml как MyDataSource. И я получаю его следующим образом:

      DataSource dataSource;
            try {
                dataSource = (DataSource) new InitialContext().lookup("java:comp/env/MyDataSource");
            } catch (NamingException e) {
                throw new DaoConfigurationException(
                    "DataSource '" + url + "' is missing in JNDI.", e);
            }

Все работает отлично. Теперь я экспортирую этот код в Jboss AP 6. И я настроил свой dataSource и его пул соединений как локальный-tx dataSource под тем же именем.

Когда я выполняю код выше, я получаю исключение NamingException. после некоторого расследования я обнаружил, что правильный способ вызвать мой DataSource под Jboss -

 dataSource = (DataSource) new InitialContext().lookup("java:/MyDataSource");

Может кто-нибудь объяснить мне, почему я должен пропустить "comp/env" в моем пути JNDI в Jboss?

Ответы

Ответ 1

Переносной подход для определения источников данных - использовать ссылку на ресурс. Ссылки на ресурсы позволяют определить имя JNDI для вашего источника данных относительно контекста именования приложений (java:comp/env), а затем сопоставить эту логическую ссылку на физический ресурс, определенный на сервере приложений, чье имя JNDI является собственностью приложения сервер. Этот подход позволяет переносить ваш код и сборку на любой совместимый сервер приложений.

Шаг 1: Объявление ресурса декларации и поиска

Вариант 1

Это можно сделать, объявив a resource-ref в дескрипторе веб-развертывания (WEB-INF/web.xml):

<resource-ref>
    <description>My Data Source.</description>
    <res-ref-name>jdbc/MyDataSource</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

Внутри вашего кода вы можете найти этот ресурс, используя имя JNDI java:comp/env/jdbc/MyDataSource:

dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");

Это имя JNDI не изменится независимо от сервера, на котором развертывается приложение.

Вариант 2

В качестве альтернативы, начиная с Java EE 5 (Servlet 2.5), это можно сделать еще проще в вашем коде, используя аннотацию @Resource. Это устраняет необходимость настройки ref-ref в дескрипторе веб-развертывания (web.xml) и предотвращает необходимость явного поиска JNDI:

public class MyServlet extends HttpServlet {

    @Resource(name = "jdbc/MyDataSource")
    private DataSource dataSource;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // dataSource may be accessed directly here since the container will automatically
        // inject an instance of the data source when the servlet is initialized

}

Этот подход имеет те же результаты, что и предыдущий вариант, но сокращает код и конфигурацию шаблона в вашей сборке.

Шаг 2: Ссылка на ресурсы ресурсов к источнику данных

Затем вам нужно будет использовать собственный подход к серверу приложений для сопоставления ссылки ресурсов на физический источник данных, созданный на сервере, например, используя дескрипторы пользовательского развертывания JBoss (WEB-INF/jboss-web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <resource-ref>
        <res-ref-name>jdbc/MyDataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <jndi-name>java:/MyDataSource</jndi-name>
    </resource-ref>
</jboss-web>

Или, например, используя Tomcat context.xml:

<Resource name="jdbc/MyDataSource" . . . />

Ответ 2

Вы можете добавить к определению источника данных тег 'jndi-name':

jndi-name - имя JNDI, под которым должен привязываться DataSource.

Документацию по источнику данных можно найти на вики JBoss: ConfigDataSources