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. Я настроил свой источник данных и его пул соединений как источник данных local-tx под тем же именем.

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

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

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

2 ответа

Решение

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

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

Опция 1

Это можно сделать, объявив 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 в вашем дескрипторе веб-развертывания (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's context.xml:

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

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

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

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

Другие вопросы по тегам