Question

I have the following code that works for creating a Proxy instance for an interface type backed by an InvocationHandler implementation, however when I use a concrete class type it doesn't work and this is well known and documented in Proxy.newProxyInstance:

    // NOTE: does not work because SomeConcreteClass is not an interface type
    final ClassLoader myClassLoader = SomeConcreteClass.getClassLoader();
    SomeConcreteClass myProxy = (SomeConcreteClass) Proxy.newProxyInstance(myClassLoader, new Class[] {
        SomeConcreteClass.class }, new InvocationHandler() { /* TODO */ });        

However, if I recall correctly I have seen this use-case work in some mock frameworks where it is possible to mock a concrete class type e.g. EasyMock. Before checking up their source code can anyone indicate what needs to be done to proxy also concrete class types and not only interfaces?

Was it helpful?

Solution

JDK dynamic proxies only work with interfaces. If you want to create a proxy with a concrete superclass you need to use something like CGLIB instead.

Enhancer e = new Enhancer();
e.setClassLoader(myClassLoader);
e.setSuperclass(SomeConcreteClass.class);
e.setCallback(new MethodInterceptor() {
  public Object intercept(Object obj, Method method, Object[] args,
        MethodProxy proxy) throws Throwable {
    return proxy.invokeSuper(obj, args);
  }
});
// create proxy using SomeConcreteClass() no-arg constructor
SomeConcreteClass myProxy = (SomeConcreteClass)e.create();
// create proxy using SomeConcreteClass(String) constructor
SomeConcreteClass myProxy2 = (SomeConcreteClass)e.create(
    new Class<?>[] {String.class},
    new Object[] { "hello" });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top