On Aug 13, 2007, at 5:04 PM, David Blevins wrote:
One of the remaining issues for the 3.0 release is the JNDI name
strategy we're going to use. I had totally thought this was all
straightened out when I added the TemplatedStrategy (documented
here: http://openejb.apache.org/jndi-names.html), but it turns out
we are still using the LegacyAddedSuffixStrategy by default so the
documentation in that page also isn't right by default :)
More on the jndi name issue as it relates to proxies.
You may recall our discussions[1][2][3] on what do to about all-in-
one proxies and the fact that some spec compliant beans may have
business interfaces that conflict[4] and therefore can't be all-in-
one proxies requiring us to also support a one-proxy-per-interface
approach.
What we ended up with is for each bean we create an all-in-one proxy
and bind it into jndi, then for each of that bean's business
interfaces we create a proxy with just that interface in it (the one-
proxy-per-interface approach) and bind each proxy into jndi as well.
So a bean with four remote business interfaces, for example, gets 1
all-in-one "business remote" proxy and 4 single-interface proxies,
one for each remote business interface. The same algorithm would
apply to local business interfaces. We still do not support an all-
in-one proxy that implements both local business interfaces and
remote business interfaces.
This is the part that has changed. *Now* we no longer have two
separate approaches (all-in-one-proxy vs single-interface-proxy) we
have a sort of hybrid approach. In the new approach we still create
one proxy per each business interface, but we *also* include all the
other business interfaces implemented by the bean class provided none
of them conflict. So a bean with four business interfaces gets 4
proxies, each possibly containing all four business interfaces.
Recap: each proxy has all the business interfaces your bean
implements (provided no conflicts are found), plus the interface the
proxy is dedicated to (regardless if the bean implemented it). We
create one such proxy for each business interface you have.
So what are these conflicts? Business interfaces extending
java.rmi.Remote. If you do not have any business interfaces
extending java.rmi.Remote *and* you implemented all your business
interfaces in your bean class, you are good to go and do not need to
be concerned; all your proxies will be guaranteed to be 'all in one'
proxies you can cast it to any of the other business interfaces of
the same type (type=local vs remote) that bean implements.
What's the deal with java.rmi.Remote? The specific issue with
java.rmi.Remote interfaces is that per spec rules many runtime
exceptions (container or connection related) are thrown to clients as
java.rmi.RemoteException which is not a runtime exception and must be
throwable via the proxy.
For example it's legal for a bean to implement two conflicting
methods such as these:
InterfaceA: void doIt() throws Foo;
InterfaceB: void doIt() throws RemoteException;
by leaving out exceptions from the throws clause that aren't declared
in both interfaces methods.
Implementation: void doIt(){}
This is fine for a bean class as it isn't going to need to throw
RemoteException. However if we create a proxy from these two
interfaces it will also wind up with a 'doIt(){}' method that cannot
throw RemoteException. This is very bad as the container does need
to throw RemoteException per spec rules to any business interfaces
extending java.rmi.Remote. If the container attempts to throw a
RemoteException from the proxies 'doIt(){}' method, it will result in
an UndeclaredThrowableException thrown by the VM. The only way to
guarantee the proxy has the 'doIt() throws RemoteException {}' method
of InterfaceB is to cut out InterfaceA when we create the proxy
dedicated to InterfaceB. When we create the proxy dedicated to
InterfaceA, InterfaceB is cut out.
Hope this helps describe how we deal with proxies and the strange
edge case that may occur.
The important thing to remember is that if you implement all your
business interfaces and do not use java.rmi.Remote, your life is
super easy.
The only real issue in all of this java.rmi.Remote business is if you
decide to use an openejb.jndiname.format[5] that results in you
getting one proxy per bean (format="{deploymentId}" for example) or
one "business remote" proxy per bean (format="{deploymentId}
{interfaceType}", my preference) instead of one proxy per each
interface of a bean (format={deploymentId}/
{interfaceClass.simpleName}, the default).
Wow, that took a lot to describe.... I'm not so sure if it came out
clearly. We definitely want to make sure we nail this chunk of
documentation and that we all understand how things work.
Is it coming out clear?
-David
[1] http://marc.info/?l=openejb-development&m=117636072115360&w=2
[2] http://marc.info/?l=openejb-user&m=117636204916491&w=2
[3] http://marc.info/?l=openejb-development&m=117661592616633&w=2
[4] http://openejb.apache.org/multiple-business-interface-hazzards.html
[5] http://openejb.apache.org/jndi-names.html