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