Java ee | ejb3 | runtime dispatch
I would like to call ejb3 at runtime. The ejb name and method name will only be available at runtime, so at compile time I cannot include any remote interfaces.
String bean = 'some/Bean';
String meth = 'doStuff';
//lookup the bean
Object remoteInterface = (Object) new InitialContext().lookup(bean);
//search the method ..
// foreach (methods)
// if method == meth, method.invoke(bean);
beans must be distributed across multiple application servers and all beans must be called remotely.
Any hints? in particular, I want not :
- dependency injection
- enabling application specific ejb interfaces in the dispatcher (above)
- webservices, kind of wasting computing power for nothing, all xml crap
Is it possible to download the ejb3 remote interface over the network (if so, how?), So I could cache the interface in some hash file or something.
I have a solution with a remote dispatcher bean that I can include in the above main dispatcher, which is essentially the same, but just relays the call to the local ejb (which I can find as name lookup fail). Given the remote dispatcher bean, I can use dependency injection.
thanks for any help
(netbeans and glassfish btw)
ejb3 is used by RMI. RMI supports loading remote classes, so I would suggest looking into that.
also, JMX mbeans supports completely untyped, remote invocations. so if you can use mbeans instead of session beans it might work. (JBoss, for example, supports ejb3-like mbeans with some custom annotations).
Finally, many application servers support CORBA calls, and CORBA supports untyped method calls.
source to share
It's impossible. You will always get a "class not found" exception. This is, in my opinion, the biggest flaw in EJB / Java. You will lose some of the speakers because the metalanguage functions are limited.
EJB3 supports RMI / IIOP, but not RMI / JRMP (standard RMI), so dynamic class loading is not supported. You lose some general Java generality, but you gain other capabilities, such as the ability to link transactions and security.
source to share
To do this, you need to use reflection, and it's very easy to do. Assuming you are looking for a void method called meth:
Object ejb = ctx.lookup(bean);
for (Method m : ejb.getClass().getMethods()) {
if (m.getName().equals(meth) && m.getParameterTypes().length == 0) {
m.invoke(service);
}
}
If you are looking for a specific method signature, just change the m.getParameterTypes () test accordingly, eg. for a method with one parameter String you can try:
Arrays.equals(m.getParameterTypes(), new Class[]{String.class})
And then pass the Object [] array with the actual arguments to the m.invoke () call:
m.invoke(service, new Object[]{"arg0"})
source to share