What's My Bean's JNDI Name?
There are two a few things to keep in mind before you start reading:
- A default JNDI name is provided to your EJB.
- You can customize the JNDI name.
- If the name is taken, an error will be logged and deployment will continue.
Info |
---|
Set the openejb.jndiname.failoncollision system property to 'true' if you'd like a strict guarantee the jndi names you want are created. Hi |
Default JNDI name
The default JNDI name is in the following format:
...
Excerpt | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
The openejb.jndiname.format property allows you to supply a template for the global JNDI names of all your EJBs. With it, you have complete control over the structure of the JNDI layout can institute a design pattern just right for your client apps. See the Service Locator doc for clever ways to use the JNDI name formatting functionality in client code.
|
This can be set on a server level via a system property, for example:
Info | ||
---|---|---|
| ||
Show the recommended way to set system properties or this property (if a gbean attribute is added) |
Setting the JNDI name
It's possible to set the desired jndi name format for the whole server level, an ejb, an ejb's "local" interface (local/remote/local-home/home), and for an individual interface the ejb implements. More specific jndi name formats act as an override to any more general formats. The most specific format dictates the jndi name that will be used for any given interface of an ejb. It's possible to specify a general format for your server, override it at an ejb level and override that further for a specific interface of that ejb.
Via the <jndi> tag for a specific ejb
The following sets the name specifically for the interface org.superbiz.Foo.
Code Block | ||||
---|---|---|---|---|
| ||||
<openejb-jar>
...
<session>
...
<jndi name="foo" interface="org.superbiz.Foo"/>
</session>
</openejb-jar>
|
Or more generally...
Code Block | ||||
---|---|---|---|---|
| ||||
<openejb-jar>
...
<session>
...
<jndi name="foo" interface="Remote"/>
</session>
</openejb-jar>
|
Or more generally still...
Code Block | ||||
---|---|---|---|---|
| ||||
<openejb-jar>
...
<session>
...
<jndi name="foo"/>
</session>
</openejb-jar>
|
The 'name' attribute can still use templates if it likes, such as:
Code Block | ||||
---|---|---|---|---|
| ||||
<openejb-jar>
...
<session>
...
<jndi name="ejb/{interfaceClass.simpleName}" interface="org.superbiz.Foo"/>
</session>
</openejb-jar>
|
Multiple <jndi> tags
Multiple <jndi> tags are allowed making it possible for you to be as specific as you need about the jndi name of each interface or each logical group of iterfaces (Local, Remote, LocalHome, RemoteHome).
Given an ejb, FooBean, with the following interfaces:
- business-local: org.superbiz.LocalOne
- business-local: org.superbiz.LocalTwo
- business-remote: org.superbiz.RemoteOne
- business-remote: org.superbiz.RemoteTwo
- home: org.superbiz.FooHome
- local-home: org.superbiz.FooLocalHome
The following four examples would yield the same jndi names. The intention with these examples is to show the various ways you can isolate specific interfaces or types of interfaces to gain more specific control on how they are named.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<openejb-jar>
...
<session>
...
<jndi name="LocalOne" interface="org.superbiz.LocalOne"/>
<jndi name="LocalTwo" interface="org.superbiz.LocalTwo"/>
<jndi name="RemoteOne" interface="org.superbiz.RemoteOne"/>
<jndi name="RemoteTwo" interface="org.superbiz.RemoteTwo"/>
<jndi name="FooHome" interface="org.superbiz.FooHome"/>
<jndi name="FooLocalHome" interface="org.superbiz.FooLocalHome"/>
</session>
</openejb-jar>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<openejb-jar>
...
<session>
...
<!-- applies to LocalOne and LocalTwo -->
<jndi name="{interfaceClass.simpleName}" interface="Local"/>
<!-- applies to RemoteOne and RemoteTwo -->
<jndi name="{interfaceClass.simpleName}" interface="Remote"/>
<!-- applies to FooHome -->
<jndi name="{interfaceClass.simpleName}" interface="RemoteHome"/>
<!-- applies to FooLocalHome -->
<jndi name="{interfaceClass.simpleName}" interface="LocalHome"/>
</session>
</openejb-jar>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<openejb-jar>
...
<session>
...
<!-- applies to RemoteOne, RemoteTwo, FooHome, and FooLocalHome -->
<jndi name="{interfaceClass.simpleName}"/>
<!-- these two would count as an override on the above format -->
<jndi name="LocalOne" interface="org.superbiz.LocalOne"/>
<jndi name="LocalTwo" interface="org.superbiz.LocalTwo"/>
</session>
</openejb-jar>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<openejb-jar>
...
<session>
...
<!-- applies to LocalOne, LocalTwo, RemoteOne, RemoteTwo, FooHome, and FooLocalHome -->
<jndi name="{interfaceClass.simpleName}"/>
</session>
</openejb-jar>
|
Global Settings
You can change the JNDI setttings by specifying the GERONIMO_OPTS before lanuching the command geronimo start
. For example, to change the JNDI format into {ejbName}/{interfaceClass}, use this syntax:
No Format |
---|
set GERONIMO_OPTS="-Dopenejb.jndiname.format={ejbName}/{interfaceClass} |
You are responsible for ensuring the names don't conflict.
...
Similarly conservative settings would be:
- {deploymentId}/{interfaceClass.simpleName}
- {moduleId}/{ejbName}/{interfaceClass}
- {ejbName}/{interfaceClass}
- {moduleId}/{ejbClass}/{interfaceClass}
- {ejbClass}/{interfaceClass}
- {ejbClass}/{interfaceClass.simpleName}
- {ejbClass.simpleName}/{interfaceClass.simpleName}
- {interfaceClass}/{ejbName}
Bordeline optimistic:
- {moduleId}/{interfaceClass}
- {interfaceClass}
The above two settings would work if you the interface wasn't shared by other beans.
...
Similarly pragmatic settings would be:
- {moduleId}/{ejbClass}/{interfaceType.annotationName}
- {ejbClass}/{interfaceType.xmlName}
- {ejbClass.simpleName}/{interfaceType.xmlNameCc}
- {interfaceType}/{ejbName}
- {interfaceType}/{ejbClass}
Optimistic settings
A very optimistic setting such as "{deploymentId}" would guarantee only one proxy for the bean will be bound to JNDI. This would be fine if you knew you only had one type of interface in your beans. For example, only business remote interfaces, or only business local interfaces, or only an EJBObject interface, or only an EJBLocalObject interface.
...
Similarly optimistic settings would be:
- {ejbName}
- {ejbClass}
- {ejbClass.simpleName}
- {moduleId}/{ejbClass.simpleName}
- {moduleId}/{ejbName}
Advanced Details on EJB 3.0 Business Proxies (the simple part)
...
Info | ||||
---|---|---|---|---|
| ||||
Read this section of either of these two apply to you:
If neither of these two items describe your apps, then there is no need to read further. Go have fun. |
...
Per spec rules many runtime exceptions (container or connection related) are thrown from javax.rmi.Remote proxies as java.rmi.RemoteException which is not a runtime exception and must be throwable via the proxy as a checked exception. The issue is that conflicting throws clauses are actually removed for two interfaces sharing the same method signature. For example two methods such as these:
- InterfaceA: void doIt() throws Foo;
- InterfaceB: void doIt() throws RemoteException;
can be implemented by trimming out the conflicting throws clauses as follows:
- Implementation: void doIt(){}
This is fine for a bean class as it does not need to throw the RMI required javax.rmi.RemoteException. However if we create a proxy from these two interfaces it will also wind up with a 'doIt(){}' method that cannot throw javax.rmi.RemoteException. This is very bad as the container does need to throw RemoteException to any business interfaces extending java.rmi.Remote for any container related issues or connection issues. If the container attempts to throw a RemoteException from the proxies 'doIt(){}' method, it will result in an UndeclaredThrowableException thrown by the VM.
...