Welcome!

Java Authors: Liz McMillan, Walter H. Pinson, III, Maureen O'Gara, Yakov Werde, Tony Bishop

Related Topics: Java

Java: Article

Method Processing with Dynamic Proxies

Java Code Stack #12:

(April 24, 2003) - While designing Enterprise frameworks, you ought to be very cautious about exposing runtime instances of classes encompassing secure transaction or management core, outlining Intellectual Property of the enterprise. Often it is required to create a proxy wrapper around objects so method-invoke requests can be pre-processed before being associated with the original instance. Very few Java developers are accustomed to abstract their management objects by creating dynamic proxy wrappers.

java.lang.reflect.Proxy class provides methods for creating dynamic proxy classes. A Proxy object implements a list of interfaces specified at runtime, when the proxy is created. When you invoke a method on a proxy instance, an associated invoke method of the proxy class gets called with the aid of the InvocationHandler interface. Each proxy object has an associated invocation handler. When a method is invoked on a proxy object, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

That said, let's create a simple interface with a method, which prints a string. We shall also create a proxy wrapper, which will let us perform some custom action before and after invoking the method.

Note: Proxy class and InvocationHandler interface are from JDK 1.3

A simple interface having a single method.

public interface JDJ{
void hello(String str);
}


Implementation for our JDJ Interface
public class JDJImpl implements JDJ{
public void hello(String str){
System.out.println("Hello..."+str);
}
}


Let us create a proxy wrapper for our JDJ Interface so that we can perform some processing before and after the method invocation.

import java.lang.reflect.*;

public class JDJProxy implements InvocationHandler{

Object myo;

public JDJProxy (Object ob){
myo = ob;
}

/*
InvocationHandler.invoke( ) processes a method invocation
on a proxy instance and returns the result
*/

public Object invoke (Object jdjp, Method me, Object [] ars) throws Throwable{
Object obj = null;

try{
/* How about method pre-processing here? */
System.out.println("Wait...Proxy invoking method...");
obj = me.invoke (myo, ars);
}
catch(Exception e){
System.out.println("Remote Object invoke failure!");
}

finally{
/* How about method post-processing here? */
System.out.println("Wait...Proxy cleaning up...");
}

return obj;
}
}


We have created a proxy wrapper successfully! Now let us try to invoke the abstracted method.

import java.lang.reflect.*;

public class JDJAccess{
public static void main(String ar[]){

/* Let us set up a proxy wrapper for our
interface
*/
Proxy pr = null;
ClassLoader cl = JDJ.class.getClassLoader();
Class[] cls = new Class[] {JDJ.class};
InvocationHandler ih = new JDJProxy(new JDJImpl());

/* Proxy.newProxyInstance( ) returns an instance
of a proxy class for the specified interfaces
that delegates method invocations
to the invocation handler
*/
JDJ jdj = (JDJ)pr.newProxyInstance(cl, cls, ih);

/* Transparent proxy; invokes the Proxy's invoke
method first
*/
jdj.hello("JDJ");

}
}


Compile all the four files and run JDJAccess. You will get this output:

Wait...Proxy invoking method...
Hello...JDJ
Wait...Proxy cleaning up...

Similarly, you can create a single Proxy wrapper for all interfaces in your framework. These Dynamic Proxies can also be used for logging and debugging method calls, which can be very useful for testing and debugging applications.

More Stories By Frank Jennings

Frank Jennings works in the Communication Designs Group of Pramati Technologies

Comments (7) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Frank Jennings 05/01/03 05:23:00 AM EDT

Create the Proxy and bind it a JNDI instance. Let ur client lookup for the proxy using the initial context. Does that help?

d. v. holten 05/01/03 04:30:00 AM EDT

That's easy - nothing really new here. Why not telling us something from the guru's toolbox: how to use proxys on a RMI object? I have an object which is accessed via RMI from a client. Ok - works. I want to use a Proxy as a wrapper around this remote-obj. (like written in your example) Ok - works. But not as expected: the proxy is serialized and moved into the client - I would like to stay it in the server. I tried several times without success: to setup the right connection between RMI-stub, proxy, remote-support and server-object is a tough puzzle. And nothing in the literature....

David Medinets 04/30/03 10:23:00 PM EDT

It seems to me that AspectJ provides a more flexible way to achieve the same effect.

Frank Jennings 04/25/03 10:05:00 AM EDT

Right!
Proxy.newProxyInstance(..)
is a better way.
Thanks.

Howard D'Souza 04/25/03 09:31:00 AM EDT

Proxy.newProxyInstance() is static and so you won't get a NullPointerException.
Not exactly the best way to invoke a static method, though :-)

Philip Gust 04/25/03 09:23:00 AM EDT

Guenther,

He's using a peculiar idiom in Java that actually will run correctly. The newProxyInstance() method is a static method of Proxy. It's usually invoked as Proxy.newProxyInstance(). However, Java allows you to invoke static methods through an instance variable. Java only needs to know the type of the instance variable, and doesn't care about the value when the method is static.

Guenther Grau 04/25/03 05:41:00 AM EDT

Hi,

while I haven't run the code, I expect the following line to throw a NullPounterException, because pr is explicitly set to null a few lines above

JDJ jdj = (JDJ)pr.newProxyInstance(cl, cls, ih);

Apart from that, I think it is a good idea to discuss the proxy concept/API.

Guenther