...
- java:comp/env is the spec defined namespace for lookup of any Container-Managed Resource
- java:comp/env is empty by default
- java:comp/env is read-only at runtime
- java:comp/env is populated by Declaring References to Container-Managed Resource via xml or annotation
- only Container-Managed Components, not their libraries, can Declare References via xml or annotation
- only Container-Managed Components, not their libraries, can get dependency injection of Container-Managed Resources
- only Container-Managed Components, and their libraries, may lookup from java:comp/env
- you must use the no-arg 'new InitialContext()' constructor to lookup something from java:comp/env
- the annotations and xml for Declaring References are identical in functionality, both always configure lookup with optional dependency injection
Common mistakes
...
, misunderstandings
...
, and myths
- "I tried it via annotation and it didn't work, so I used xml and then it did work"
...
See rule 9 and the above. You can use the annotation at the class level and it will cause no dependency injection and only the entry creation in java:comp/env.
InitialContext Lookups
- Server side beans should access other beans on the server via the default no args constructor (EJB 3 spec 15.3.1 Bean Provider's Responsibilities).
- Container side lookup names must be preceded with java:comp/env, as in java:comp/env/myBean. e.g.
Code Block initialContext.lookup("java:comp/env/beanName")
- note that java:comp/env/ is empty by default, and you need to declare your references, whether via xml or annotations
- Declared via annotations
Code Block @EJB(name="myBean", beanInterface = IMyBean.class) public class DependentBean ....
- Declared via xml INCOMPLETE
- Declared via annotations
- Clients is a good reference for more complex lookups, including authentication (only for non-standard clients not running in an EJB container).
Injection
Some important things to realize about dependency injections.
...
Code Block |
---|
initialContext = new InitialContext();
initialContext.lookup("java:comp/env/beanName") |
- "I tried to list java:comp/env but it's empty?!"
See rule 2 and rule 4. There will be nothing in java:comp/env unless you Declare a Reference to it. It does not matter if is a DataSource configured a the server level, etc. Nothing is bound into java:comp/env unless you explicitly declare a reference to it. The Java EE 5 TCK (Technology Compatibility Kit) tests for this extensively and is a rule we cannot break. Java EE 6 does finally offer some new namesaces (java:global, java:app, and java:module) which will offer some great new options for more global-style lookups.
- "I deployed the EJB but can't look it up, it's name is Foo"
See rule 2 and the above. Just creating an EJB doesn't cause it to be added to java:comp/env. If a Container-Managed Component wants to lookup the EJB they must Declare a Reference to it via the @EJB annotionation or <ejb-local-ref> or <ejb-ref> in xml. In Java EE 6, however, EJBs will be automatically bound to "java:global/<app-name>/<module-name>/<bean-name>!<fully-qualified-interface-name>" and can be looked up without declaring a reference first.
- "Which InitialContextFactory do for java:comp/env?"
See rule 8. You are not allowed to use an InitialContextFactory for java:comp/env lookups. Setting an InitialContextFactory via 'java.naming.factory.initial' in either System properties, InitialContext properties, or a jndi.properties file is illegal and will cause java:comp/env lookups to fail.
- "My Client can't lookup the EJB from java:comp/env"
See rule 7. A plain, standalone, Java application cannot use java:comp/env. There is the official concept of a Java EE Application Client which can be packaged in an ear and deployed into the Container. In practice, most people find them restrictive, cumbersome, and hard to use and are therefore rarely employed in "real world" projects. Most people opt to use the non-standard, vendor-specific, approach to looking up EJBs from their plain java clients. In OpenEJB this can be done via either the RemoteInitialContextFactory (for remote clients) or the LocalInitialContextFactory (for local clients of an embedded container). The JNDI names can be configured as shown here.
- "I declared the reference, but still can't look it up"
See all of the above and reread the rules a few times. Always check the log output as well.
...