java:comp / env /做什么?


116

我一天中花了太多时间试图找出一些连接JNDI工厂bean的错误。问题原来是,而不是这个...

<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,2010年

1
正如所暗示的,确实不起作用的那个确实缺少java:comp / env / jdbc / loc。指向的上下文文件包含“ loc”资源。“当前”上下文有哪些可能性?
Danny

Answers:


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");

我以为我已经正确理解了这一点,但是进一步的评论使我意识到我做得如此落后。如果tomcat上下文描述符默认情况下位于java:comp / env下,这是否意味着我可以从值中省略java:comp / env?就我而言,我必须添加它以使“名称jdbc在此上下文中未绑定”错误消失。
Danny

4
您可以使用“ foo”进行绑定,并使用“ java:comp / env / foo”进行查找。看看blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim 2010年

3
上面的链接来自独立的JNDI教程,该教程最初在docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html上提供
2013年

如果您的查询中有更多/-怎么办?像:“ java:com / env / foo / bar”,您的jndiName值是“ foo / bar”还是“ foo.bar”?
Pieter De Bie 2015年

正确的jndiName值将为“ foo / bar” @PieterDeBrie。
tftdias 2015年

37

还有一个属性resourceRefJndiObjectFactoryBean是,当设置为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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.