Archive

Posts Tagged ‘proxy’

The power of proxies in Java

May 10th, 2010 1 comment

In this article, I’ll show you the path that leads to true Java power, the use of proxies.

They are everywhere but only a handful of people know about them. Hibernate for lazy loading entities, Spring for AOP, LambdaJ for DSL, only to name a few: they all use their hidden magic. What are they? They are… Java’s dynamic proxies.

Everyone knows about the GOF Proxy design pattern:

Allows for object level access control by acting as a pass through entity or a placeholder object.

Likewise, in Java, a dynamic proxy is an instance that acts as a pass through to the real object. This powerful pattern let you change the real behaviour from a caller point of view since method calls can be intercepted by the proxy.

Pure Java proxies

Pure Java proxies have some interesting properties:

  • They are based on runtime implementations of interfaces
  • They are public, final and not abstract
  • They extend java.lang.reflect.Proxy

In Java, the proxy itself is not as important as the proxy’s behaviour. The latter is done in an implementation of java.lang.reflect.InvocationHandler. It has only a single method to implement:

public Object invoke(Object proxy, Method method, Object[] args)
  • proxy: the proxy instance that the method was invoked on
  • method: the Method instance corresponding to the interface method invoked on the proxy instance. The declaring class of the Method object will be the interface that the method was declared in, which may be a superinterface of the proxy interface that the proxy class inherits the method through
  • args: an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. Arguments of primitive types are wrapped in instances of the appropriate primitive wrapper class, such as java.lang.Integer or java.lang.Boolean

Let’s take a simple example: suppose we want a List that can’t be added elements to it. The first step is to create the invocation handler:

public class NoOpAddInvocationHandler implements InvocationHandler {

  private final List proxied;

  public NoOpAddInvocationHandler(List proxied) {

    this.proxied = proxied;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    if (method.getName().startsWith("add")) {

      return false;
    }

    return method.invoke(proxied, args);
  }
}


The invoke method will intercept method calls and do nothing if the method starts with “add”. Otherwise, it will the call pass to the real proxied object. This is a very crude example but is enough to let us understand the magic behind.

Notice that in case you want your method call to pass through, you need to call the method on the real object. For this, you’ll need a reference to the latter, something the invoke method does not provide. That’s why in most cases, it’s a good idea to pass it to the constructor and store it as an attribute.

Note: under no circumstances should you call the method on the proxy itself since it will be intercepted again by the invocation handler and you will be faced with a StackOverflowError.

To create the proxy itself:

List proxy = (List) Proxy.newProxyInstance(
  NoOpAddInvocationHandlerTest.class.getClassLoader(),
  new Class[] { List.class },
  new NoOpAddInvocationHandler(list));


The newProxyInstance method takes 3 arguments:

  • the class loader
  • an array of interfaces that will be implemented by the proxy
  • the power behind the throne in the form of the invocation handler

Now, if you try to add elements to the proxy by calling any add methods, it won’t have any effect.

CGLib proxies

Java proxies are runtime implementations of interfaces. Objects do not necessarily implement interfaces, and collections of objects do not necessarily share the same interfaces. Confronted with such needs, Java proxies fail to provide an answser.

Here begins the realm of CGLib. CGlib is a third-party framework, based on bytecode manipulation provided by ASM that can help with the previous limitations. A word of advice first, CGLib’s documentation is not on par with its features: there’s no tutorial nor documentation. A handful of JavaDocs is all you can count on. This said CGLib waives many limitations enforced by pure Java proxies:

  • you are not required to implement interfaces
  • you can extend a class

For example, since Hibernate entities are POJO, Java proxies cannot be used in lazy-loading; CGLib proxies can.

There are matches between pure Java proxies and CGLib proxies: where you use Proxy, you use net.sf.cglib.proxy.Enhancer class, where you use InvocationHandler, you use net.sf.cglib.proxy.Callback. The two main differences is that Enhancer has a public constructor and Callback cannot be used as such but only through one of its subinterfaces:

  • Dispatcher: Dispatching Enhancer callback
  • FixedValue: Enhancer callback that simply returns the value to return from the proxied method
  • LazyLoader: Lazy-loading Enhancer callback
  • MethodInterceptor: General-purpose Enhancer callback which provides for “around advice”
  • NoOp: Methods using this Enhancer callback will delegate directly to the default (super) implementation in the base class

As an introductory example, let’s create a proxy that returns the same value for hash code whatever the real object behind. The feature looks like a MethodInterceptor, so let’s implement it as such:

public class HashCodeAlwaysZeroMethodInterceptor implements MethodInterceptor {

  public Object intercept(Object object, Method method, Object[] args,
    MethodProxy methodProxy) throws Throwable {

    if ("hashCode".equals(method.getName())) {

      return 0;
    }

    return methodProxy.invokeSuper(object, args);
  }
}


Looks awfully similar to a Java invocation handler, doesn’t it? Now, in order to create the proxy itself:

Object proxy = Enhancer.create(
  Object.class,
  new HashCodeAlwaysZeroMethodInterceptor());


Likewise, the proxy creation isn’t suprising. The real differences are:

  • there’s no interface involved in the process
  • the proxy creation process also creates the proxied object. There’s no clear cut between proxy and proxied from the caller point of view
  • thus, the callback method can provide the proxied object and there’s no need to create and store it in your own code

Conclusion

This article only brushed the surface of what can be done with proxies. Anyway, I hope it let you see that Java has some interesting features and points of extension, whether out-of-the-box or coming from some third-party framework

You can find the sources for this article in Eclipse/Maven format here.

To go further:

Send to Kindle
Categories: Java Tags:

Hibernate hard facts – Part 4

February 17th, 2010 2 comments

In the fourth article of this serie, I will show the subtle differences between get() and load() methods.

Hibernate, like life, can be full of suprises. Today, I will share one with you: have you ever noticed that Hibernate provides you with 2 methods to load a persistent entity from the database tier? These two methods are get(Class, Serializable) and load(Class, Serializable) of the Session class and their respective variations.

Strangely enough, they both have the same signature. Strangely enough, both of their API description starts the same:

Return the persistent instance of the given entity class with the given identifier.

Most developers use them indifferently. It is a mistake since, if the entity is not found, get() will return null when load() will throw an Hibernate exception. This is well described in the API:

Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists. You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.

Truth be told, the real difference lies elsewhere: the get() method returns an instance, whereas the load() method returns a proxy. Not convinced? Try the following code snippet:

Session session = factory.getCurrentSession();

Owner owner = (Owner) session.get(Owner.class, 1);

// Test the class of the object
assertSame(owner.getClass(), Owner.class);

The test pass, asserting that the owner’s class is in fact Owner. Now, in another session, try the following:

Session session = factory.getCurrentSession();

Owner owner = (Owner) session.load(Owner.class, 1);

// Test the class of the object
assertNotSame(owner.getClass(), Owner.class);

The test will pass too, asserting that the owner’s class is not Owner. If you spy the object in the debugger, you’ll see a Javassist proxyed instance and that fields are not initialized! Notice that in both cases, you are able to safely cast the instance to Owner. Calling getters will also return expected results.

Why call the load() method then? Because since it is a proxy, it won’t hit the DB until a getter method is called.

Moreover, these features are also available in JPA from the EntityManager, respectively with the find() and getReference() methods.

Yet, both behaviours are modified by Hibernate’s caching mechanism. Try the following code snippet:

// Loads the reference
session.load(Owner.class, 1);

Owner owner = (Owner) session.get(Owner.class, 1);

According to what was said before, owner’s real class should be the real McCoy. Dead wrong! Since Hibernate previously called load(), the get() looks in the Session cache (the 1st level one) and returns a proxy!

The behaviour is symmetrical with the following test, which will pass although it’s counter-intuitive:

// Gets the object
session.get(Owner.class, 1);

// Loads the reference, but looks for it in the cache and loads
// the real entity instead
Owner owner = (Owner) session.load(Owner.class, 1);

// Test the class of the object
assertSame(owner.getClass(), Owner.class);

Conclusion: Hibernate does a wonderful job at making ORM easier. Yet, it’s not an easy framework: be very wary for subtle behaviour differences.

The sources for the entire hard facts serie is available here in Eclipse/Maven format.

Send to Kindle
Categories: Java Tags: , , , ,

Mockito’ spy() method and Spring

May 21st, 2009 4 comments

Mockito is a mocking framework (see Two different mocking approaches) that is an offshoot of EasyMock. Whatever the mocking framework one uses, a common feature is the ability to mock interfaces, through the JDK Proxy class. This is well and nice, but one has to explicitly mock every method that one wants to use in the course of the test.

What if I want to mock an already existing implementation, with some methods providing behaviours that suit me ? Today, I ran across this case: Read more…

Send to Kindle