【问题标题】:What does java:comp/env/ do?java:comp/env/ 做什么?
【发布时间】:2011-05-05 04:29:52
【问题描述】:

在连接一些 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 未绑定在此上下文中”

【问题讨论】:

  • 您最初使用的是哪一个?您的问题意味着您错误地使用了第二个示例(jdbc/loc,因此 java:comp/env/jdbc/loc 是正确的),而 cherouvim 的答案意味着您错误地使用了第一个示例(java:comp/env/jdbc/loc,因此 jdbc/loc 是正确的) .无论如何,真正的答案是:这取决于当前上下文。
  • 如暗示的那样,不起作用的确实缺少 java:comp/env/jdbc/loc。指向的上下文文件包含“loc”资源。 “当前”上下文的可能性是什么?
  • 我在这里回答了这个问题:stackoverflow.com/a/66325569/1051589

标签: spring jdbc jndi factory


【解决方案1】:

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

【讨论】:

  • 我以为我已经正确理解了这一点,但进一步的 cmets 让我意识到我这样做是落后的。如果默认情况下,tomcat 上下文描述符位于 java:comp/env 下,那是否意味着我可以从值中省略 java:comp/env ?就我而言,我必须添加它以使“Name jdbc is not bound in this Context”错误消失。
  • 您使用“foo”绑定并使用“java:comp/env/foo”查找。看看blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
  • 以上链接来自独立的 JNDI 教程,最初位于:docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html
  • 如果您的查找中有更多 /-es 怎么办?比如:“java:com/env/foo/bar”,你的 jndiName 值是“foo/bar”还是“foo.bar”?
  • 正确的 jndiName 值是“foo/bar”@PieterDeBrie。
【解决方案2】:

JndiObjectFactoryBean 中还有一个属性resourceRef,即当设置为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 成功设置 - 一个更全面的示例可能会帮助我了解我的错误。
    猜你喜欢
    • 2012-07-22
    • 2011-11-19
    • 2020-08-29
    • 2012-09-23
    • 1970-01-01
    • 2010-10-12
    • 2019-05-21
    • 2018-03-08
    • 1970-01-01
    相关资源
    最近更新 更多