I use GF4 server and in its log I have:
Portable JNDI names for EJB com.test.cms.svr.web.Service2: [java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2, java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2!com.test.fw.svr.web.bundle.ComponentService]]]
My questions:
Why are there two jndi names - with interface and without interface?
This is an EJB 3.1 feature called portable JNDI names. Here is nice explanation from this blog:
Client applications need to use global JNDI name to lookup an EJB. All along the ejb specifications had been silent about portability of such global jndi names. This allowed each vendor to assign a global jndi names to EJBs in a vendor specific way. This meant that the client code that performed a lookup using global JNDI names were inherently non portable across appserver vendor implementations.
EJB 3.1 solves the above problem by mandating that every container must assign (at least one) well defined global JNDI names to EJBs. The general syntax of a (portable) global JNDI name of an EJB is of the form:
java:global/[<application-name>]/<module-name>/<bean-name>!<fully-qualified-bean-interface-name>
In addition to the above name, if the EJB exposes just a single client view (that is it implements just one interface or the no interface view), the container is also mandated to map the bean to
java:global/[<application-name>]/<module-name>/<bean-name>
Where
<application-name>
defaults to the bundle name (.ear file name) without the bundle extension. This can be overridden in application.xml. Also, is applicable only if the bean is packaged inside a .ear file.<module-name>
defaults to bundle name (.war or .jar) without the bundle extension. Again, this can be overridden in ejb-jar.xml.<bean-name>
defaults to the unqualified class name of the bean. However, if@Stateful
or@Stateless
or@Singleton
uses the name attribute, then the value specified there will be used as the bean name.
There is some additional GlassFish-specific information in the GlassFish EJB FAQ.
Why can I get bean only using jndi-name with interface even when EJB is only local?
I guess you mean a lookup from another EJB or module in the same web application inside the same JVM. Otherwise this shouldn't be possible without a @Remote
interface. Here are two statements from the GlassFish EJB FAQ:
I have an EJB component with a Local interface. Can I access it from an Application Client or a stand-alone java client ?
If the EJB component is running within the server, no. The EJB Local view is an optimized invocation path that uses call-by-reference semantics. It is only available to web components and EJB components that are part of the same application as the target EJB component.
To access EJB components that are running in the server from an Application Client or stand-alone java client, you'll need to use either a Remote 3.x Business interface, a 2.x Home interface, or web services.One alternative, if using GlassFish v3, is to use the EJB 3.1 Embeddable API. This allows a Java SE program to directly execute EJB components within the same JVM, without using a server process.
I have an EJB component with a Local interface. Can I access it from a web component in a different application?
No. The EJB specification only requires access to an EJB component's local EJB interface from within the same application in the same JVM. One option is to package the ejb-jar in the same .ear as the .war. A second option, if using GlassFish v3, is to package the EJB component directly within the .war.
The GlassFish EJB FAQ also contains alot more detailed information about this topic.
See also: