0

I am attempting to wrap a service in a proxy to simulate lag during tests. The following class is meant to wrap an object and sleep the thread for 100ms for any invoked method.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SleepyProxy<T> implements InvocationHandler {

  private T wrapped;

  private SleepyProxy(T toWrap) {
    this.wrapped = toWrap;
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  public static <T> T createProxy(T toWrap) {

    Object proxy = Proxy.newProxyInstance(
         toWrap.getClass().getClassLoader(), 
         toWrap.getClass().getInterfaces(), 
         new SleepyProxy(toWrap));

    return (T) proxy;
  }

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

    Object result = method.invoke(wrapped, args);

    nap();

    return result;
  }

  private void nap() {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  }
}

From my test class:

private MyService service = SleepyProxy.createProxy(ServiceProvider.getMyService());

Produces the following error:

java.lang.ClassCastException: com.sun.proxy.$Proxy33 cannot be cast to com.example.service.MyService;

Please Note:

  • I am using Spring Framework and JUnit4
  • Test class annotated with @RunWith(SpringJUnit4ClassRunner.class)
  • I'm learning Spring; I'm unsure if I need to be using a Spring InvocationHandler / Proxy service

Why am I having issues casting to MyService? All object values seem to line up when debugging. Is there a better way I can go about simulating lag on my services? (Aside from making a 'test service' for each).

Thanks for your help!

Chris
  • 387
  • 5
  • 16

1 Answers1

0

Problem is that MyService is a class, and Proxy.newProxyInstance creates object that implements interface you provide in second argument. To have it working MyService needs to implement interface so:

class MyService implements ServiceInterface

And later use your proxy like this:

 ServiceInterface service = SleepyProxy.createProxy(ServiceProvider.getMyService());

Proxy.newProxyInstance has nothing to do with MyService class, it will only create object that will run InvocationHandler.invoke when you will call method on it.

reynev
  • 326
  • 2
  • 5