Posts Tagged ‘dynamic proxies

05
Aug
08

Business Delegate for EJB 2.1 using Dynamic Proxies

Those who still use EJB 2.1 and had already the oportunity of tasting EJB 3 might miss the liberty of not having to declare the throwing of RemoteException in every remote method. Back to old school and EJB 2.1 we had the Business Delegate pattern that freed us from polluting UI code with RemoteExceptions but still writing a Business Delegate class by hand was tedious and error prone.

J2SE 1.3 brought a powerful feature: Dynamic Proxies but still we have one thing to follow, the DRY (or Don’t Repeat Yourself) principle.

Enough theory… let’s get to the sample. Imagine you had to develop a Foo EJB. You would start by declaring its Local and Remote interfaces. First tip for EJB 2.1 users (like myself) to avoid deploy time surprises: use a POJO interface and make your EJB implement it and also your Local and Remote interfaces extend it. It saves you a lot of time cause chances that you skip a method on your EJB are incredibly high.

So thats the class diagram we have now:

Class Diagram FooEJB

Class Diagram FooEJB

First thing to pay attention, FooLocal and FooRemote interfaces only extend IFoo, unfortunately FooLocal will end up throwing RemoteExceptions. On the other hand IFooDelegate overwrites the method hiding the RemoteException that was thrown in the base interface. You could argue that your Local Interface could override the methods as well removing the RemoteException but then you’d end up writing three interfaces.

FooBean as expected implements the IFoo interface to avoid missing some method. So, enough interfaces and EJB now we have to tie the things together with the Dynamic Proxy.

package foo;
import foo.util.EJBFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class FooDelegateFactory {
    public static IFooDelegate getInstance() {
        return FooProxy.newInstance(EJBFactory.getFoo());
    }
}

class FooProxy implements InvocationHandler {
    private IFoo foo;

    public static IFooDelegate newInstance(IFoo realFoo) {
        return (IFooDelegate) Proxy.newProxyInstance(FooProxy.class.getClassLoader(), new
            Class[]{IFooDelegate.class}, new FooProxy(realFoo));
    }

    private FooProxy(IFoo realFoo) {
        this.foo = realFoo;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
        try {
            return method.invoke(foo, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
}

One of the tricky parts about the Dynamic Proxies is the exception handling. Since the method is reflective called you need to fetch the original Exception through the InvocationTargetException and rethrow it. Pay attention that the invoke method declares that it may throw anything.
So, with this you have a Business Delegate that only takes you to construct the proxy and replicate the method on that interface.

Advertisements



ClustrMaps

Blog Stats

  • 361,304 hits since aug'08

%d bloggers like this: