Что делает java: comp / env /?

116

Я просто потратил слишком много времени на попытки выяснить некоторые ошибки при подключении некоторого фабричного компонента JNDI. Проблема оказалась в том, что вместо этого ...

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/loc"/>
</bean>

Я действительно написал это ...

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
</bean>

Я предполагаю, что, java:comp/env/возможно, ссылается на некоторую переменную среды и делает так, чтобы в конечном итоге просматривался мой файл контекста. Единственная разница java:comp/env/. Что это из уст эксперта?

Без java:comp/env/префикса в значении я бы получил сообщение об ошибке «Имя jdbc не привязано в этом контексте» .

Дэнни
источник
3
Какой из них вы изначально использовали? Ваш вопрос подразумевает, что вы неправильно использовали второй пример ( jdbc/locи, следовательно java:comp/env/jdbc/loc, правильный), в то время как ответ cherouvim подразумевает, что вы неправильно использовали первый пример ( java:comp/env/jdbc/locи, следовательно jdbc/loc, правильный). Тем не менее, настоящий ответ таков: это зависит от текущего контекста.
BalusC
1
В том, что не сработало, действительно отсутствовал java: comp / env / jdbc / loc, как подразумевается. Файл контекста, на который был указан, включал ресурс "loc". Каковы возможности «текущих» контекстов?
Дэнни

Ответы:

100

Цитата https://web.archive.org/web/20140227201242/http://v1.dione.zcu.cz/java/docs/jndi-1.2/tutorial/beyond/misc/policy.html

В корневом контексте пространства имен находится привязка с именем «comp», которая привязана к поддереву, зарезервированному для привязок, связанных с компонентами. Название «comp» - это сокращение от «компонент». В корневом контексте нет других привязок. Однако корневой контекст зарезервирован для будущего расширения политики, в частности для именования ресурсов, которые привязаны не к самому компоненту, а к другим типам объектов, таким как пользователи или отделы. Например, будущие политики могут позволить вам называть пользователей и организации / отделы, используя такие имена, как «java: user / alice» и «java: org / engineering».

В контексте «comp» есть две привязки: «env» и «UserTransaction». Имя «env» привязано к поддереву, которое зарезервировано для привязок компонента, связанных со средой, как определено его дескриптором развертывания. «env» - это сокращение от «окружающая среда». J2EE рекомендует (но не требует) следующую структуру для пространства имен "env".

Таким образом, привязка, которую вы сделали из spring или, например, из дескриптора контекста tomcat, по умолчанию идет в java: comp / env /

Например, если ваша конфигурация:

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="foo"/>
</bean>

Затем вы можете получить к нему доступ напрямую, используя:

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/foo");

или вы можете сделать промежуточный шаг, чтобы вам не нужно было указывать «java: comp / env» для каждого извлекаемого ресурса:

Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("foo");
cherouvim
источник
Я думал, что понял это правильно, но дальнейшие комментарии заставили меня понять, что я сделал это задом наперед. Если дескриптор контекста tomcat по умолчанию находится в java: comp / env, не означает ли это, что я могу опустить java: comp / env из значения? В моем случае мне пришлось добавить его, чтобы убрать ошибку «Имя jdbc не привязано в этом контексте».
Дэнни
4
Вы связываете с помощью «foo» и выполняете поиск с помощью «java: comp / env / foo». Посмотрите blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim
3
Вышеупомянутая ссылка взята из отдельного руководства по JNDI, изначально доступного по адресу : docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Данило Пьяццалунга
что, если в вашем поиске есть больше / -ов? Например: «java: com / env / foo / bar», ваше значение jndiName «foo / bar» или «foo.bar»?
Питер Де Би
Правильным значением jndiName будет "foo / bar" @PieterDeBrie.
tftdias
37

Существует также свойство resourceRefв JndiObjectFactoryBeanтом , что есть, когда установлено true, используется для автоматического предварять строку , java:comp/env/если она уже не присутствует.

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
  <property name="resourceRef" value="true"/>
</bean>
Филип Спиридонов
источник
3

После нескольких попыток и глубокого изучения исходного кода Tomcat я обнаружил, что простое свойство useNaming = "false" помогло !! Теперь Tomcat разрешает имена java: / liferay вместо java: comp / env / liferay

Тьяго Леау Морейра
источник
Не могли бы вы привести полный пример, включая определение ресурса? Мне не удалось успешно настроить это с помощью Tomcat 8.5 - возможно, более подробный пример поможет мне увидеть мою ошибку.
RobertG