What does java:comp/env/ do?

I just spent too much time of my day trying to figure out some errors when hooking up some JNDI factory bean. The problem turned out to be that instead of this...

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

I had actually written this...

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

I infer that the java:comp/env/ perhaps references some environment variable and makes it so that, ultimately, my context file is looked at. The only difference is java:comp/env/. From an expert's mouth, what does that do?

Without the java:comp/env prefix in the value, I would get an error that said "Name jdbc is not bound in this Context".


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

At the root context of the namespace is a binding with the name "comp", which is bound to a subtree reserved for component-related bindings. The name "comp" is short for component. There are no other bindings at the root context. However, the root context is reserved for the future expansion of the policy, specifically for naming resources that are tied not to the component itself but to other types of entities such as users or departments. For example, future policies might allow you to name users and organizations/departments by using names such as "java:user/alice" and "java:org/engineering".

In the "comp" context, there are two bindings: "env" and "UserTransaction". The name "env" is bound to a subtree that is reserved for the component's environment-related bindings, as defined by its deployment descriptor. "env" is short for environment. The J2EE recommends (but does not require) the following structure for the "env" namespace.

So the binding you did from spring or, for example, from a tomcat context descriptor go by default under java:comp/env/

For example, if your configuration is:

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

Then you can access it directly using:

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

or you could make an intermediate step so you don't have to specify "java:comp/env" for every resource you retrieve:

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

还有一个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>

After several attempts and going deep in Tomcat's source code I found out that the simple property useNaming="false" did the trick!! Now Tomcat resolves names java:/liferay instead of java:comp/env/liferay

链接地址: http://www.djcxy.com/p/65344.html

上一篇: 在春天读取属性文件时发生错误404

下一篇: java:comp / env /做什么?