Can you statically derive an EJB3 bean's portable JNDI name?
Evening all,
I don't use EJB3, and am trying to learn more about it and play with it a
bit. Things have definitely improved since i last did EJB to pay the
bills.
Now, the normal way to get hold of a reference to an enterprise bean (FSVO
'reference') is to use injection. Excellent. But sometimes (eg when coming
from a non-bean object), we have to resort to JNDI. One of the things EJB3
added was a portable JNDI syntax, so that beans will be bound to the same
name in different app servers. Lovely. There is an informative but
slightly incorrect description of this here:
http://download.oracle.com/javaee/6/tutorial/doc/gipjf.html#girgn
The incorrectnesses that i've noticed are its claims that (a) the module
name is optional in a java:app name, and (b) the bean name and interface
name are separated with a '/' (the spec says it's a '!').
Anyway, there's something i'd like to do (over the details of which i will
draw a discreet veil) which i think requires me to write a function like:
public static <T> resolveBean(Class<T> beanClass)
I am prepared to assume that the bean being looked up was defined with
annotations rather than through XML, and that it is in the same module (or
rather, i am prepared to accept more complexity when it is not). I can
write that function as:
public static <T> resolveBean(Class<T> beanClass) throws various exceptions {
String path = determineBeanPath(beanClass);
InitialContext ic = new InitialContext();
return beanClass.cast(ic.lookup(path));
}
Where i still need to write this:
public static String determineBeanPath(Class<T> beanClass)
I think i can do this. Am i right? Is there already a utility to do this
somewhere?
To be specific, i think i can generate a URL that looks like this:
"java:module/" + beanName + "!" + interfaceName
beanName will be the 'name' attribute of the @Stateless, @Stateful, or
@Singleton annotation, if there is one, or else the unqualified name of
the class. interfaceName will be the fully-qualified name of a business
interface, if there is one, or of the class if not (or the class is
annotated @LocalBean). I can find the interfaces by looking for a @Remote
or @Local annotation on the class and picking one of its values, or else
searching its implemented (and inherited?) interfaces to find one itself
annotated with @Remote or @Local.
All of this assumes that there is no mappedName in play. If bean class's
@S* annotation declares one, i can either use it, try it and fail over to
the portable name, ignore it, or abort the mission.
Have i gone bonkers? Does this sound plausible?
tom
--
Sorry. Went a bit Atari Teenage Riot there. -- Andrew