import java.lang.reflect.Method; import java.lang.Class; import java.lang.reflect.Proxy; import java.util.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; interface I{ public void hello(); } class A implements I{ public void hello(){ System.out.println("hello"); } } interface B{ public void call_hello(I i); public void foo(); public void this_one_works(String s); } class BImpl implements B{ public void call_hello(I i){ i.hello(); } public void foo(){ System.out.println("foo"); } public void this_one_works(String s){ System.out.println(s); } } class BProxy implements InvocationHandler { private B first; private B second; Set send_to_first = new HashSet(Arrays.asList(new String[]{ "foo","bar"})); Set send_to_second = new HashSet(Arrays.asList(new String[]{ "zork","foobar"})); Set send_to_both = new HashSet(Arrays.asList(new String[]{ "something"})); public static Object newInstance(B b) { return java.lang.reflect.Proxy.newProxyInstance( B.class.getClassLoader(), new Class[] { B.class }, new BProxy(b)); } public BProxy(B b) { this.first = b; this.second = new BImpl(); } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Object result; try { String methodName = m.getName(); if (send_to_first.contains(methodName)){ return m.invoke(first, args); } else if (send_to_second.contains(methodName)){ return m.invoke(second, args); } else { if (true){ return m.invoke(this, args); } else { try{ Method method; if (args != null) { ArrayList parameterTypes = new ArrayList(); for (Object o: args){ parameterTypes.add(o.getClass()); } method = this.getClass().getMethod(methodName, parameterTypes.toArray(new Class [0])); } else { method = this.getClass().getMethod(methodName); } return method.invoke(this, args); } catch (Exception E){ E.printStackTrace(); throw E; } } } } catch (InvocationTargetException e) { throw e.getTargetException(); }// catch (Exception e) { // throw new RuntimeException("unexpected invocation exception: " + // e.getMessage()); //} } public void this_one_works(String s){ first.this_one_works(s); second.this_one_works(s); } public void call_hello(I i){ first.call_hello(i); second.call_hello(i); } } public class testCase{ public static void main(String[] args) { try{ B b = new BImpl(); A a = new A(); b.call_hello(a); B proxy = (B) BProxy.newInstance(b); proxy.foo(); proxy.this_one_works("something here"); proxy.call_hello(a); } catch (Exception e){ e.printStackTrace(); } } }