¿Qué hace java: comp / env /?

116

Pasé demasiado tiempo de mi día tratando de descubrir algunos errores al conectar un bean de fábrica JNDI. El problema resultó ser que en lugar de esto ...

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

De hecho, había escrito esto ...

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

Infiero que java:comp/env/quizás hace referencia a alguna variable de entorno y lo hace de modo que, en última instancia, se examine mi archivo de contexto. La única diferencia es java:comp/env/. De la boca de un experto, ¿qué hace eso?

Sin el java:comp/env/prefijo en el valor, obtendría un error que decía "El nombre jdbc no está vinculado en este contexto" .

Danny
fuente
3
¿Cuál usaste inicialmente? Su pregunta implica que estaba usando incorrectamente el segundo ejemplo ( jdbc/locy por lo tanto java:comp/env/jdbc/loces correcto), mientras que la respuesta de cherouvim implica que estaba usando incorrectamente el primer ejemplo ( java:comp/env/jdbc/locy por lo tanto jdbc/loces correcto). Independientemente, la respuesta real es: depende del contexto actual .
BalusC
1
El que no funcionó realmente faltaba java: comp / env / jdbc / loc, como se implica. El archivo de contexto al que se señaló incluía el recurso "loc". ¿Cuáles son las posibilidades para los contextos "actuales"?
Danny

Respuestas:

100

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

En el contexto raíz del espacio de nombres hay un enlace con el nombre "comp", que está enlazado a un subárbol reservado para enlaces relacionados con componentes. El nombre "comp" es la abreviatura de componente. No hay otras vinculaciones en el contexto raíz. Sin embargo, el contexto raíz está reservado para la futura expansión de la política, específicamente para nombrar recursos que no están vinculados al componente en sí, sino a otros tipos de entidades como usuarios o departamentos. Por ejemplo, las políticas futuras podrían permitirle nombrar usuarios y organizaciones / departamentos usando nombres como "java: user / alice" y "java: org / engineering".

En el contexto "comp", hay dos enlaces: "env" y "UserTransaction". El nombre "env" está vinculado a un subárbol que está reservado para los enlaces relacionados con el entorno del componente, según lo definido por su descriptor de implementación. "env" es la abreviatura de medio ambiente. J2EE recomienda (pero no requiere) la siguiente estructura para el espacio de nombres "env".

Entonces, el enlace que hizo desde Spring o, por ejemplo, desde un descriptor de contexto de Tomcat, va por defecto en java: comp / env /

Por ejemplo, si su configuración es:

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

Entonces puedes acceder a él directamente usando:

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

o puede realizar un paso intermedio para no tener que especificar "java: comp / env" para cada recurso que recupere:

Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("foo");
Cherouvim
fuente
Pensé que había entendido esto correctamente, pero más comentarios me hicieron darme cuenta de que lo había hecho al revés. Si el descriptor de contexto de tomcat fuera, por defecto, bajo java: comp / env, ¿no significaría eso que puedo omitir el java: comp / env del valor? En mi caso, tuve que agregarlo para que desapareciera el error "El nombre jdbc no está vinculado en este contexto".
Danny
4
Se enlaza usando "foo" y busca usando "java: comp / env / foo". Eche un vistazo a blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim
3
El enlace anterior es del tutorial independiente de JNDI, originalmente disponible en: docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Danilo Piazzalunga
¿Qué pasa si hay más / -es en su búsqueda? Como: "java: com / env / foo / bar", ¿su valor de jndiName es "foo / bar" o "foo.bar"?
Pieter De Bie
El valor correcto de jndiName sería "foo / bar" @PieterDeBrie.
tftdias
37

También hay una propiedad resourceRefde JndiObjectFactoryBeanque, cuando se establece en true, se usa para anteponer automáticamente la cadena java:comp/env/si aún no está presente.

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
  <property name="resourceRef" value="true"/>
</bean>
Filip Spiridonov
fuente
3

Después de varios intentos y profundizando en el código fuente de Tomcat, descubrí que la propiedad simple useNaming = "false" funcionó. Ahora Tomcat resuelve los nombres java: / liferay en lugar de java: comp / env / liferay

Thiago Leão Moreira
fuente
¿Podría proporcionar un ejemplo completo, incluida la definición de recurso? No logré configurar esto correctamente con Tomcat 8.5; un ejemplo más completo me ayudaría a ver mi error, tal vez.
RobertG