Thursday, August 16, 2007

Make use of Java dynamic proxy

I didn't know about Java dynamic proxy before but finally got a chance to learn and found a good use for it. The test I was writing had the smell of repeating code:

private void testPutWithoutSynch(params...) throws Exception {

map.put("k1", "v1");


private void testPutWithSynch(params...) throws Exception {

synchronized(map) {
map.put("k1", "v1");


The test pattern repeated with other operations that you can do with Map like puttAll, remove, etc... Do_set_up() is actually some pre setup steps that I need to perform according to parameters list. As you can see, I have to repeat the test method twice for each Map operation I want to test, with and without the synchronize block.

So there is this code smell and I didn't know get rid of it. Then Tim Eck, my coworker, showed me how to use Java proxy. The idea is to wrap my map in a proxy, and use reflection to invoke methods of the map. By using a invocation handler, I can have a variable to control whether or not I want to use synchronize for that particular operation.

class Handler implements InvocationHandler {
private final Map map;
private boolean useSynch = false;

public Handler(Map map) { = map;

public void setUseSynch(boolean flag) {
this.useSynch = flag;

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

private Object invokeWithSynch(Method method, Object[] args) throws Throwable {
synchronized (map) {
return method.invoke(map, args);

Then the proxy can be created like this:

Map map = new HashMap();
Handler handler = new Handler(map);
Map mapProxy = (Map)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Map.class }, handler);

With that my test methods can be reduced to:

private void testPut(params..., boolean useSynch) throws Exception {

mapProxy.put("k1", "v1");

assertions depends on useSynch

Then I just need to call this method twice and accomplish the same thing.

testPut(params..., false);
testPut(params..., true);

Pretty neat huh? Java proxy is nice tool to know.


Taylor said...
This comment has been removed by the author.
Taylor said...

If your InvocationHandler had a static method called createProxy, you could push the Proxy creation into the Handler and then remove it from your application code.

Something like:

Map mapProxy = InvocationHandler.createProxy(map, [true | false]);

Unknown said...

Thanks for your post. DPs are powerful, allows AOPish style of development.

Don't mean to self promote, but this is a pretty cool usage sf DPs :-)


Unknown said...

Nice tip Taylor. Thanks. Thought I need to be able to flip the bit useSynch on the fly in my test (since I'm testing the same map)

Jim d said...

This is a nitpick, but aren't boolean method parms a code smell also? That aside, I've been meaning to learn about dynamic proxies, so thanks for the article.

Unknown said...

cool article on dynamic proxies... but there's a much simpler way to solve your problem:

Map map = ...

if (testUsingSync)
map = Collections.synchronizedMap(map);



NABH said...

I really appreciate your post and you explain each and every point very well.Thanks for sharing this information.And I’ll love to read your next post too.

Manish kumar said...

hmm... nice post. for an introduction on Dynamic Proxies, refer this blog also :
Java Rendezvous