EJB FAQ
https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.htmlHere are answers to some frequently asked questions about how touseEnterprise Java Beans within GlassFish. Additional resources can be found here. Please send any follow-up questions/comments to ejb@glassfish.dev.java.netor the GlassFishforum.
EJB Clients
[*]How do I access a Remote EJBcomponent froma stand-alone java client?
[*]Is a stand-alone Java client portable? What's the difference between a stand-alone Java client and anApplication Client component?
[*]How do I access aRemote EJB (3.0 or 2.x) component from a non-Java EE web container likeTomcat orResin?
[*]What if I have multipleinstances of the Appserver running and I want to access a Remote EJBcomponent between them?
[*]Do I need RMI stubs to access EJBcomponents from my java client?
[*]What if I have an existing stand-alonejavaclient that accesses EJB components through the CosNaming JNDIprovider? Howdo I get static RMI-IIOPstubs for it?
[*]What is the relationshipbetween @EJBand <ejb-ref>/<ejb-local-ref>?
[*]I have a Remote EJBdependency (@EJBor <ejb-ref>)in my Java EE component. How do Icontrol whichactual target EJB component it refers to?
Local EJB Access
[*]How do I access a Local EJB componentfroma POJO or utility class?
[*]I have an EJB component with aLocalinterface. Can I access it from an Application Client or a stand-alonejava client ?
[*]I have an EJB component with aLocalinterface. Can I access it from a web component in a differentapplication?
JNDI names
[*]Are Global JNDInames portable? How do I know if my EJB component has aportable JNDIname?
[*]What is thesyntax for portable global JNDI names?
[*]The defaultportable JNDInames are great, but how do I define my own portableglobal JNDIname?
[*]How areGlassFish-specific(non-portable) Global JNDI namesassigned to Session / Entity beans?
[*]How do I specify the Queue or Topic thataMessage Driven Bean should consume from?
Testing / Embeddable API
[*]How do I "unittest" EJB components?
How do I access a Remote EJBcomponent froma stand-alone java client?
Step 1. Use the no-arg InitialContext() constructorin yourcode.
The most common problem developers run into is passing specificJNDIbootstrapping properties to InitialContext(args). Some othervendors require this step but GlassFish does not. Instead, use theno-arg InitialContext()constructor.
Step 2. Pass the global JNDI name of the Remote EJB toInitialContext.lookup()
Stand-alone java clients do not have access to a component namingenvironment (java:comp/env)or to the @EJBannotation, so they mustexplicitly use the global JNDI nameto lookup the Remote EJB. (See here formore information on how global JNDI namesare assigned to EJB components)Assuming the global JNDI nameof the Remote EJB is "FooEJB":
For Beans with a 3.x Remote Business interface :
Foo foo =(Foo) new InitialContext().lookup("FooEJB");
Note that in the EJB 3.x case the result of thelookup can be directlycast to the remote business interface type without usingPortableRemoteObject.narrow().
For EJB 2.1 and earlier session/entity beans :
Object homeObj = newInitialContext().lookup("FooEJB");
FooHome fooHome = (FooHome)
PortableRemoteObject.narrow(homeObj,FooHome.class);
Foo foo = fooHome.create(...)
Step3. Include the appropriate GlassFish .jars in the java client'sclasspath.
For GlassFish v3
Include $GLASSFISH_HOME/modules/gf-client.jarin the client'sclasspath.
E.g., assuming the application classes are in /home/user1/myclasses andthe main client class is acme.MyClient:
java-classpath$GLASSFISH_HOME/modules/gf-client.jar:/home/user1/myclassesacme.MyClient
Note that the Java EE 6 API classes are automatically included bygf-client.jarso there is no need to explicitly add javaee.jar to theclasspath. gf-client.jarrefers to many other .jars from theGlassFish installation directory so it is best to refer to it fromwithin the installation directory itself rather than copying it(and allthe other .jars) to another location.
For GlassFish v2 and earlier
Include both $GLASSFISH_HOME/lib/appserv-rt.jarand$APS_HOME/lib/javaee.jarin the client's classpath.
E.g., assuming the application classes are in /home/user1/myclasses andthe main client class is acme.MyClient :
java-classpath$GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:/home/user1/myclassesacme.MyClient
Note : appserv-rt.jaruses the JAR MANIFEST-CLASSPATH attribute toinclude other dependent .jars within the lib directory. Whensetting yourclient classpath, it is best to directly refer to the appserv-rt.jarwithinthe app server lib directory rather than copying it to anotherlocation. If you do copy appserv-rt.jar,you'll need to copy additional.jarssuch as appserv-deployment-client.jarand appserv-ext.jar. Thefull set of .jars that might be needed by appserv-rt.jar is located initsMETA-INF/MANIFEST.MF file.
If your stand-alone client makes use of JMS, you'll also need to add$GLASSFISH_HOME/lib/install/applications/jmsra/imqjmsra.jar,$GLASSFISH_HOME/lib/appserv-admin.jarand $GLASSFISH_HOME/lib/appserv-ws.jar.
If your stand-alone client makes use of the Java Persistence API (e.g.it calls a Remote EJB component that returns a Java Persistence APIentity), you'll also need to add $APS_HOME/lib/toplink-essentials.jar.
Step 4. Set the server host property, if necessary.
If the stand-alone java client is running on a different host than theserver, set the -Dorg.omg.CORBA.ORBInitialHostproperty when startingthe client JVM. E.g.
java-Dorg.omg.CORBA.ORBInitialHost=com.acme.Host1. Thispropertydefaults to localhost,so it is not necessary to set it if the javaclient is running on the same machine as the server.
Step 5. Set the naming service port property, if necessary.
The default naming service port in the app server is 3700. Ifthe naming service is running on a different port, you'll need toset it via the -Dorg.omg.CORBA.ORBInitialPortproperty when startingtheclient JVM. You can double-check the actual naming service portfor a given server instance by looking in the server instace'sdomain.xmlfor "orb-listener-1".Alternatively, check theApplications..Configuration..ORB..IIOP Listeners section of the adminGUI for orb-listener-1.
Is a stand-alone Java client portable? What's the difference between a stand-alone Java client and anApplication Client component?
The Java EE platform defines a component that is specially designed toportably access Java EE services from a JVM running outside of theApplication Server. It is called a Java EE Application Clientand has beenpart of the platform since the first release (J2EE 1.2). LikeallJava EE components it runs within a container provided by the vendor'simplementation. The main advantages of the Application Client arethat it's portable and that it allows the developer to use the sameprogrammingmodel for defining and accessing resources as is used within webcomponentsand EJB components. It follows the overall philosophy of the JavaEEplatformthat as much of the "plumbing" or system-level work as possible shouldbe performed by a container instead of being part of the Applicationcode. That means a guarantee that the no-arg InitialContextconstructorwill work, that a private component naming context (java:comp/env)isavailable,and in Java EE 5 that platform annotations and injection are available.
One of the most common issues faced by developers is how to initializethe naming context within a client that accesses EJB components. When sucha client is *not* written as an Application Client it is referred to asa "stand-alone" java client. By definition, such stand-alone javaclients are not portable, so each vendor defines its own way tobootstrapthe naming service. This not only makes it more difficult to code theclientbut causes problems when moving between Java EE implementations.
Like all Java EE components, there are some additional steps requiredto achieve the portability offerered by the Application Client. E.g., definining a deployment descriptor, packaging theapplication client .jar and learning how to run the Application Clientcontainer.
See the following for more details on using Application Clients :
Chapter 22(Getting Started with EJBs) of the Java EE 5 tutorial
SimpleEJB 3.0 session / message-driven bean code examples
Clientchapter of our Developer's Guide
How do I access aRemote EJB (3.0 or 2.x) component from a non-Java EE web container likeTomcat orResin?
Accessing a Remote EJB component from a non-Java EE web container issimilar tothe stand-alone java client case. However, the complication is that most Java web serversset the defaultJNDIname provider for the JVM, which prevents our appserver namingproviderfrom being instantiated when the application uses the no-argInitialContext()constructor. The solution is to explicitly instantiate anInitialContext(Hashtable)with the properties for our naming provider,as contained in GlassFish's jndi.properties file.
Step 1. Instantiate the InitialContext
Properties props = newProperties();
props.setProperty("java.naming.factory.initial",
"com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.factory.url.pkgs",
"com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state",
"com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
// optional. Defaults to localhost. Onlyneeded if web server is running
// on a different host than the appserver
props.setProperty("org.omg.CORBA.ORBInitialHost","localhost");
// optional. Defaults to 3700. Only needed iftarget orb port is not 3700.
props.setProperty("org.omg.CORBA.ORBInitialPort","3700");
InitialContext ic = new InitialContext(props);
Step 2. Use the global JNDI name of the target Remote EJB inthe lookup.
EJB 3.x, assuming a global JNDI nameof "com.acme.FooRemoteBusiness":
FooRemoteBusiness foo =(FooRemoteBusiness)ic.lookup("com.acme.FooRemoteBusiness");
EJB 2.x, assuming a global JNDI nameof "com.acme.FooHome":
Object obj = ic.lookup("com.acme.FooHome");
FooHome fooHome = (FooHome)PortableRemoteObject.narrow(obj, FooHome.class);
Step 3. Add the necessary appserver code to the web server'sclasspath.
See step 3 ofstand-alone client access for the list of required .jars.
Step 4. For EJB 3.0 Remote access, use at least Glassfish V2or Java EE 5 SDK(SJS AS 9) Update 1.
Builds from this point on will contain a required bug fix.
Seehttps://glassfish.dev.java.net/issues/show_bug.cgi?id=920 formore details.
What if I have multipleinstances of the Appserver running and I want to access a Remote EJBcomponentbetween them?
If the two server instances are part of the same cluster, there is nospecial mapping needed. By definition, a cluster is homogeneous,meaningthe exact same set of applications is deployed to all instances. Each server instance has the same entries in its global JNDInamespace,sothe target Remote EJB component can always be resolved intra-server. Therefore,it would never be a good idea to explicitly refer to a Remote EJBcomponent inoneserver instance in the cluster from a different server instance in thesamecluster.
However, if the server instances are either both stand-alone instancesor this a cross-cluster access, the only difference is the syntax oftheglobal JNDIname used to resolve the ejb-ref or @EJB. Since thecallingcode is running within a Java EE component (web or ejb), it should usethestandard Java EE programming model for accessing remote EJB components-- @EJBorejb-ref +java:comp/env lookup. The application code and anyejb-ref.xml should remain location transparent so that the mapping to physicalEJB component can be changed without affecting any portable code ordescriptors.
Follow the steps outlined here, but instead of using an unqualified global JNDI name,use the CORBAinteroperable naming syntax :
corbaname:iiop:<host>:<port>#<global_jndi_name>
E.g., assume we have a web application running in a non-clustered appserver instance on host1 thatwants to access a Remote StatelessSession bean in an app server instance on host2. The targetRemote EJB component has a global JNDI nameof "Foo".
Within the servlet :
@EJB(name="fooejbref")
private FooRemote fooRemote;
Within sun-web.xml:
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<jndi-name>corbaname:iiop:host2:3700#Foo</jndi-name>
</ejb-ref>
Do I need RMI stubs to access EJBsfrom myjava client?
No. Our implementationuses a feature called "Dynamic RMI-IIOP" that creates any necessaryRMI-IIOPstubs at runtime in a way that is completely hidden from theapplication. This makes deployment much faster and avoidsmany of the configuration problems that result from having to addstatic stubs to your client. However, Dynamic RMI-IIOP is onlyenabled when the client is using the naming providerfrom our server implementation. If theclient is a stand-alone java client, that means following theinstructionshere or here , or using anApplication Client component. Any explicit use of the CosNamingprovider in theclient will not be able to use the dynamic RMI-IIOP feature,which iswhywe don't recommend that approach. If you must use CosNaming,see here.
What if I have an existing stand-alone javaclient that accesses EJB components through the CosNaming JNDIprovider ? How do I get static RMI-IIOPstubs for it?
First, read about Portable Java EE clientsand "How To Write a Stand-alone Client". The best option would be to change the client to an ApplicationClient or to follow our stand-alone java client recommendations. Ifthat's not possible, you can request that static RMI-IIOPstubs begeneratedduring deployment by using the --generatermistubsoption on theasadmindeploy command. In this case, the static RMI-IIOPstubswillbe placed within the client.jar file. E.g.
asadmin deploy --generatermistubs --retrieve/home/user1/clientstubdir fooapp.ear
After the command executes, the client.jar containing the staticRMI-IIOPstubs will be in /home/user1/clientstubdir/fooappClient.jar.
The reason static RMI-IIOPstubs are still needed in this case is thatif the CosNamingprovider is instantiated, it is not using the clientnaming provider from our appserver implementation. It insteaduses an ORB from Java SE which does not support dynamic RMI-IIOP.
What is the relationshipbetween @EJBand ejb-ref/ejb-local-ref?
The @EJBannotation and the ejb-ref/ejb-local-ref.xml elements areused to specify the same semantic information. Specifically, thata Java EE component has a dependency on a local or remote EJBcomponent. Every @EJBcan be translated into an equivalentejb-ref/ejb-local-ref. @EJBis easier to use but it serves thesame purpose as ejb-ref/ejb-local-ref. Here's a table with moredetails :
@EJB attribute
Description
Default value
ejb-refequivalent
ejb-local-refequivalent
name
Unique location within the private componentnamespace(java:comp/env).
field-level : <fully-qualifiedname ofdeclaring class>/<field-name>
method-level : <fully-qualifiedname of declaringclass>/<property name>
class level : nameis required.
ejb-ref-name
ejb-ref-name
beanInterface
For EJB 3.x business interfaces, the Local orRemote business interface of the session bean.
For EJB 2.x, the Home/LocalHome interface of the session/entity bean.
field-level : the type of the declared field.
method-level : the type of the single setter parameter
class level : beanInterfaceis required.
For EJB 3.x : <remote>
For EJB 2.x :
<home>
For EJB 3.x :
<local>
For EJB 2.x :
<local-home>
beanName
ejb-name (not global JNDI name)of the targetejb component within the application. This can be used wheneverthe targetejbcomponent is defined within the same application as the referencingcomponent,regardless of local vs. remote. The only time it can't be usedis if the @EJBrefers to a Remote interface (3.x or 2.x) that isdefined outside the application.
Automatically resolved if there is only one EJBcomponent within the application that exposes the value of beanInterface
ejb-link
ejb-link
lookup
*(Added in EJB 3.1)
Specifies the portable JNDI nameof the target EJB component to which this @EJBdependency refers. This should be used instead of mappedNamein cases where an @EJBdependency needs to be resolved to a Remote EJB component defined in adifferent application. It can also be used to chain one @EJBdependency to another @EJBdependency.
n/a
lookup-name
lookup-namemappedName
Specifies the product-specific name of thetarget Remote EJB component. For GlassFish, this refers to theglobal JNDIname of the target Remote EJB component.
Not applicable for localinterfaces because beanNamecan always beused instead.
*(Should not be used in EJB 3.1. See lookupinstead)
If the target EJB component is defined withinthe sameapplication and the beanNamedefault applies, no additional mappingis required.
Otherwise, the target global JNDI namewill be set to the value of beanInterface
mapped-name
n/a
I have a Remote EJBdependency (@EJB or <ejb-ref>) in my Java EE component. Howdo Icontrol whichactual target EJB component it refers to?
If the target EJB component is defined within the same application asyourreferencing component andthere is only one target EJB component within theapplication that exposes the remote interface associated with your EJBdependency, then the mapping will happen automatically. In thiscase, there is no need to specify any additional mapping information.
Otherwise, there are 3 ways to map the remote EJB dependency to thetarget Remote EJB component. From highest to lowest precedence,they are :
1. Use the sun-specific deployment descriptor
Map the remote EJB dependency to the global JNDI nameof the target EJB componentwithin the sun-*.xml{sun-web.xml,sun-application-client.xml,sun-ejb-jar.xml}file corresponding to the module in which the EJBdependency is defined.
E.g. given a remote EJB dependency defined within a servlet(com.acme.MyServlet):
@EJB(name="fooejbref")
private FooRemote fooRemote;
To map this remote EJB dependency to an EJB comopnent with global JNDI name "Foo":
Within sun-web.xml:
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<jndi-name>Foo</jndi-name>
</ejb-ref>
If the @EJBdid not use the nameattribute, you would need to referto the default name of the EJB dependency when specifying thesun-*.xmlmapping. E.g. :
@EJB
private FooRemote fooRemote;
To map this remote EJB dependency to an EJB component with global JNDI name "Foo":
Within sun-web.xml:
<ejb-ref>
<ejb-ref-name>com.acme.MyServlet/fooRemote</ejb-ref-name>
<jndi-name>Foo</jndi-name>
</ejb-ref>
2. Use @EJBmappedNameor the <ejb-ref>..<mapped-name>element.
For @EJB,specify the global JNDI nameof the target EJB component using themappedNameattribute. E.g.
@EJB(name="fooejbref", mappedName="Foo")
private FooRemote fooRemote;
Note that mappedNameis completely different than name. namerefers to a location within the private componentenvironment namespace (java:comp/env)that represents this EJBdependency. mappedNamerefers toa location within a product-specific globalnamespace that holds the EJB reference object.
For <ejb-ref>,specify the global JNDI nameof the target EJB component using the<mapped-name>element. E.g.
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<remote>com.acme.FooRemote</remote>
<mapped-name>Foo</mapped-name>
</ejb-ref>
If an @EJB andan <ejb-ref> aredefined for the same EJBdependency(meaning @EJB.nameequals <ejb-ref>..<ejb-ref-name>)in the same componentenvironment, the values in <ejb-ref>take precedence.
3. Use @EJBbeanNameor <ejb-ref>..<ejb-link>element.
beanNameand <ejb-link>only apply if the target remote EJB component is definedwithin the same application as the referencing component. In this case, the value is the ejb-nameof the targetbean, not the global JNDI name. If the target EJB component is definedusing ejb-jar.xml,the ejb-nameis the value of the <session>or <entity>ejb-nameelement. If the target EJB component is defined usingannotations, theejb-nameis either the value the @Stateless/@Stateful/@Singletonnameattribute or ifnamewas not specified, the unqualifiedbean class name.
E.g. , assuming our target EJB component com.acme.FooBeanis defined as follows:
@Stateless
public class FooBean implements FooRemote { ... }
To map the servlet's EJB dependency using beanName :
@EJB(name="fooejbref", beanName="FooBean")
private FooRemote fooRemote;
To map the servlet's EJB dependency using ejb-link :
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<remote>com.acme.FooRemote</remote>
<ejb-link>FooBean</ejb-link>
</ejb-ref>
Note that ejb-nameis only guaranteed to be unique within an ejb-jaror .warmodule. If there are multiple modules within the .ear thatdefinean EJB component with the same ejb-name,the following beanName/<ejb-link>syntaxcanbe used to explicitly refer to the target EJB component :
<relativeejb-jarmodule uri>#<ejb-name>
E.g., given an application containing ejb1.jar, ejb2.jar,and web1.war,where ejb1.jarand ejb2.jarboth define an EJB component with ejb-name FooBean :
To map the servlet's EJB dependency to the EJB component in ejb1.jarusingbeanName:
@EJB(name="fooejbref", beanName="ejb1.jar#FooBean")
private FooRemote fooRemote;
To map the servlet's EJB dependency to the EJB component in ejb1.jarusing ejb-link:
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<remote>com.acme.FooRemote</remote>
<ejb-link>ejb1.jar#FooBean</ejb-link>
</ejb-ref>
If an @EJB andan <ejb-ref> aredefined for the same EJBdependency(meaning @EJB.nameequals <ejb-ref>..<ejb-ref-name>)in the same componentenvironment, the values in <ejb-ref>take precedence.
I have an EJB component with aLocalinterface. Can I access it from an Application Client or a stand-alonejava client ?
If the EJB component is running within the server, no. The EJBLocal view is an optimized invocation path that usescall-by-reference semantics. It is only available to webcomponents and EJB components that are part of the same applicationas the target EJB component. To access EJB components thatare running in the server from an Application Client orstand-alone java client, you'll need to use either a Remote 3.xBusiness 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 withinthe same JVM, without using a server process.
I have an EJB component with aLocal interface. Can I access it from a web component in adifferent application?
No. The EJB specification only requires access to an EJBcomponent's local EJB interface fromwithin the same application in the same JVM. One option isto package the ejb-jar inthe same .earas the .war. Asecond option, if using GlassFish v3, is to package the EJB componentdirectly within the .war.
How do I access a Local EJB componentfrom a POJO?
Local EJB component access is only portable from within the sameapplication, sothePOJO class must be called from a component running within the sameapplicationas the target Local EJB component. Injection is not supported forPOJO classes,so the POJO needs to look up the local reference.
If the application is running within GlassFish v3, it can use the portable global JNDInames defined by the EJB 3.1 specification. In addition toportable java:globalnames, there are default portable JNDI namesfortwo other scopes : java:module,and java:app. An EJB component's java:moduleJNDIname is visible to any code running within thesame module. An EJB component's java:app JNDI nameisvisible to any code running within the same application.
The syntax for each is :
java:module/<bean-name>
java:app/<module-name>/<bean-name>
<module-name>defaults to the unqualified name of the ejb-jarfile or .warfile in which the EJB component is defined, minus the fileextension. The <module-name>can be explicitlyspecified usingthe <module-name>element of the ejb-jar.xml(for ejb-jars) orweb.xml(forEJB components defined in .wars).
<bean-name>corresponds to the session bean's ejb-name. Itdefaults to the unqualifiedname of the session bean class. Itcan beexplicitly specified using the nameattribute of the@Stateless/@Stateful/@Singletonannotation. Alternatively, if theejb-jar.xmlis being used to define the component, <bean-name>corresponds to the <ejb-name>element of ejb-jar.xml.
So, given :
@Stateless
public class FooBean { ... }
A POJO running within the same module as FooBean canlookup an EJBreference to FooBeanusing :
FooBean foo = (FooBean) newInitialContext().lookup("java:module/FooBean");
An advantage of the java:module syntaxvs. java:globalis that the codedoing the lookup does not have to know the <app-name>or<module-name>in which it is executing.
If the application is running in GlassFish v2 or earlier, there are noportable JNDInames for the local EJB view. In that case the onlyway for the POJO to acquire an EJB reference is to define a local EJBdependency using @EJB or ejb-local-ref,and then look up thatdependency within the private namespace(java:comp/env)of the component within whose scope it is executing. That can be done using the following steps :
Step 1. Define the local EJB dependency for the componentwithinwhose scope the POJO will execute.
Assume the POJO wants to access a local EJB 3.0 business interfaceFooLocalfrom the following EJB component defined within the same application :
@Stateless
public class FooBean implements FooLocal { ... }
If the POJO is called from a web application, the java:comp/envnamespaceis shared by the entire .war. So, the local EJB dependency can bedefinedby using an @EJBannotation on any managed class within the .war :
@EJB(name="fooejbref", beanInterface=FooLocal.class)
public class MyServlet extends HttpServlet { ... }
Likewise, if the POJO is itself called from an EJB component, the localEJBdependencymust be defined within that EJB component. Unlike the .war case,thecomponent environment (java:comp/env)is private for each EJB component.
@EJB(name="fooejbref", beanInterface=FooLocal.class)
@Stateless
public class BarBean implements BarLocal { ... }
Alternatively, the local EJB dependency can be declared within thestandarddeployment descriptor corresponding to the component within whose scopethePOJO is executing (web.xml / ejb-jar.xml)
<ejb>
<ejb-name>BarBean</ejb-name>
<ejb-class>com.acme.BarBean</ejb-class>
...
<ejb-local-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<local>com.acme.FooLocal</local>
<ejb-link>FooBean</ejb-link>
</ejb-local-ref>
</ejb>
Step 2. In the POJO code, lookup the local EJB dependencywithinjava:comp/env
InitialContext ic = new InitialContext();
FooLocal foo = (FooLocal)ic.lookup("java:comp/env/fooejbref");
Note that if the POJO is called from multiple components, e.g. fromboththe web application and BarBean,you'll need to define the same localEJBdependency for both calling components so that it is always defined inthecurrently active component environment when the POJO does its lookup.
Are Global JNDInames portable? How do I know if my EJB component has a portableJNDIname?
If the EJB component is a kind of session bean and it is deployed toany implementation supporting EJB 3.1(E.g. GlassFish v3), it willautomatically have one or more portable JNDI namesdefined based on thesyntax in the EJB 3.1 specification. Note that this is true ofexisting EJB 3.0 and 2.x applications that are deployed to animplementation supporting EJB 3.1. No code changes are required on thebean class itself in order to have the portable global JNDI nameautomatically assigned when deployed to an EJB 3.1 container. Seehere for EJB 3.1portableglobal JNDIname syntax.
Prior to EJB 3.1 (GlassFish v2 and earlier), there were no portableglobal JNDInames defined by the specification. See GlassFish-specificglobal JNDIname syntax.
What is thesyntax for portable global JNDI namesin EJB 3.1?
Per the EJB 3.1 Specification, each session bean is assigned a uniqueJNDIname within the java:globalnamespace. Note that prior toEJB 3.1 / GlassFish v3, there were no portable JNDInames defined for session beans, so each vendor defined its ownsyntax. Seehere for GlassFish vendor-specific global JNDI namesyntax .
The syntax for portable global session bean JNDI namesin EJB 3.1 is :
java:global[/<app-name>]/<module-name>/<bean-name>
The <app-name>portion is only present ifthe application isdeployed as an .earfile. In that case, <app-name>defaults to the unqualifiedname of the .earfile, minus the fileextension. The <app-name>can be explicitly specifiedusing the <app-name>element in application.xml.
<module-name>defaults to the unqualifiedname of the ejb-jarfile or .warfile in which the EJB component is defined, minus the fileextension. The <module-name>can be explicitlyspecified using the <module-name>element of the ejb-jar.xml(forejb-jars) or web.xml(forEJB components defined in .wars).
<bean-name>corresponds to the session bean's EJB name. Itdefaults to the unqualifiedname of the session bean class. Itcan be explicitly specified using the nameattribute of the@Stateless/@Stateful/@Singletonannotation. Alternatively, if theejb-jar.xmlis being used to define the component, <bean-name>corresponds to the <ejb-name>element of ejb-jar.xml.
Given the session bean :
@Stateless
public class FooBean implements Foo { ... }
If FooBeanis packaged in fooejb.jarand deployed as a stand-alonemodule, its resulting JNDI nameentry is :
java:global/fooejb/FooBean
If FooBeanis packaged in fooejb.jarwithin fooapp.ear,its resultingglobal JNDIname entry is :
java:global/fooapp/fooejb/FooBean
If FooBeanis packaged in a stand-alone web module fooweb.war,its resultingglobal JNDIname is :
java:global/fooweb/FooBean
If <span style="font-family: Courier New,Courier,monospace;">FooBean</
页:
[1]