Hi. I have some difficulties understanding the idea of java:comp/env. I will put here down what I know (or I think I know), and maybe someone could straighten things up if I am wrong.
1. There is a global JNDI namespace, and it uses names that are vendor dependent, possibly not portable. Every EJB, JDBC pool, JMS Topic or Queue, I create for the server, has its name in the global JNDI.
2. java:comp/env is a utility context (which may not even be a real context, can be "virtual"). Every resource (for example, EJB) has its own java:comp/env context, populated with resources ejbs, and env-entries, but only those that are specified for the given resource.
3. In web containers, the resource-ref, resource-env-ref, env-entry, ejb-ref and ejb-local-ref are used in web.xml to bring the resources into the java:comp/env context. The resources are specified for all web resources when used in web.xml (as these are immediate children of the web-app element), so are present in java:comp/env for every resource.
4. In web containers, the @Resource and @EJB annotations can be specified on class level, which is a counterpart of resource-ref / resource-env-ref, env-entry, and ejb-ref / ejb-local-ref in web.xml (so it places the referenced resource into java:comp/env), the difference being that this time the resource is present only in java:comp/env of the web resource that has the annotation (in contrast to these put in web.xml).
5. In EJB container, in ejb-jar.xml, resource-ref, resource-env-ref, env-entry, ejb-ref and ejb-local-ref are specified for each bean separately, so the resources are present only in java:comp/env for that specific EJB. This is the same with @Resource and @EJB annotations - they put the resources into the context, and these are local to the bean.
6. When @Resource or @EJB is used on setter or field level, this is equivalent to two things: a. bringing the resource into java:comp/env of the class (which is the same as using the @Resource / @EJB annotations on class level) so that I can use a JNDI lookup in the java:comp/env context (can I really do the lookup?) b. the container does the lookup for me (injection)
I would be very grateful if someone could take time, read, and correct any of these statements.
What you have is absolutely accurate. Congratulations on putting this together. There is rarely any material on this, so it would be a great resource for anyone who needs it. I would urge you to write an article on it or put it on your blog or make it more generally accessible via some other means.
That being said, a little bit of personal opinion: the component context is a terrible over-engineered concept that only a hopeless academic can love :-). I wish it could be deprecated :-). That being said, I am glad EJB 3 handles most of this behind the scenes quite elegantly 90+% of the time. In the cases it cannot, I don't see using global JNDI names as being that bad. Also, we are standardizing global JNDI names in EJB 3.1.
That all being said, if you want to know a little more about the component context, do let me know.
Independent Consultant — Author, EJB 3 in Action — Expert Group Member, Java EE 6 and EJB 3.1
Joined: Aug 21, 2008
Hi. I would like to know one more thing (for now :-)) - is java:comp/env inherited? I mean, if I have a servlet, which has the @Resource annotation on a field, which is of DataSource type. I can look it up with the code:
Works fine. Then, I instantiate a helper class, and do the same lookup:
code for the helper class
and the code in the servlet:
This also works fine. I am using Glassfish - is it a feature specigic to this server, or is it standard, expected behaviour?
Thanks for you good words. As for making it public, I am shy and introvert ;-) Really, I have no blog or any way I could write an article. But if anyone reading this would like to use this, please do so.
Joined: Feb 01, 2005
It is expected behavior, as long as the look-up happens within the span of the invocation that defines the component context/environment.