Title: Multiple Business Interface Hazzards
<a name="MultipleBusinessInterfaceHazzards-UndeclaredThrowableException"></a>
#  UndeclaredThrowableException

When two java interfaces are implemented by a proxy and those two
interfaces declare the *same method* but with *different throws clauses*
some very nasty side effects happen, namely you loose the ability to throw
any checked exceptions that are not in the throws clause of both methods.


    import junit.framework.TestCase;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.UndeclaredThrowableException;
    
    /**
     * @version $Rev$ $Date$
     */
    public class ExceptionTest extends TestCase {
    
        public void test() throws Exception {
    	ClassLoader classLoader = this.getClass().getClassLoader();
            Class[]
 interfaces = new Class[]{One.class, Two.class};
    
    	InvocationHandler h = new TestInvocationHandler();
    
    	Object proxy =
java.lang.reflect.Proxy.newProxyInstance(classLoader, interfaces, h);
    
    	One one = (One) proxy;
    
    	try {
    	    one.run(new CommonException());
    	} catch (CommonException e) {
    	    // this will work
    	} catch(UndeclaredThrowableException u) {
    	    Throwable t = u.getCause();
    	    fail("Undeclared: "+t);
    	} catch(Throwable t){
    	    fail("Caught: "+t);
    	}
    
    	try {
    	    one.run(new OneException());
    	} catch (OneException e) {
    	} catch(UndeclaredThrowableException u) {
    	    Throwable t = u.getCause();
    	    fail("Undeclared: "+t); // This will always be the code that
executes
    	} catch(Throwable t){
    	    fail("Caught: "+t);
    	}
    
    	Two two = (Two) proxy;
    	try {
    	    two.run(new CommonException());
    	} catch (TwoException e) {
    	} catch(UndeclaredThrowableException u) {
    	    Throwable t = u.getCause();
    	    fail("Undeclared: "+t); // This will always be the code that
executes
    	} catch(Throwable t){
    	    fail("Caught: "+t);
    	}
    
        }
    
        public static class CommonException extends Exception {
    	public CommonException() {
    	}
        }
    
        public static interface One {
    	void run(Object o) throws OneException, CommonException;
        }
    
        public static class OneException extends Exception {
    	public OneException() {
    	}
        }
    
        public static interface Two {
    	void run(Object o) throws TwoException, CommonException;
        }
    
        public static class TwoException extends Exception {
    	public TwoException() {
    	}
        }
    
        private static class TestInvocationHandler implements InvocationHandler
{
            public Object invoke(Object proxy, Method method, Object[]
 args) throws Throwable {
                throw (Throwable)args[0]
;
    	}
        }
    }



<a name="MultipleBusinessInterfaceHazzards-IllegalArgumentException"></a>
# IllegalArgumentException

This one is less of a runtime problem as doing this will cause things to
fail up front.	When two java interfaces are implemented by a proxy and
those two interfaces declare the *same method* but with *different return
types* the VM proxy code will refuse to create a proxy at all.	Take this
code example:


    
    import junit.framework.TestCase;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    /**
     * @version $Rev$ $Date$
     */
    public class ReturnTest extends TestCase {
    
        public void test() throws Exception {
    	ClassLoader classLoader = this.getClass().getClassLoader();
            Class[]
 interfaces = new Class[]{ReturnTest.One.class, ReturnTest.Two.class};
    
    	InvocationHandler h = new ReturnTest.TestInvocationHandler();
    
    	Object proxy =
java.lang.reflect.Proxy.newProxyInstance(classLoader, interfaces, h);
    
    	One one = (One) proxy;
    	try {
    	    Object object = one.run(new ThingOne());
    	} catch (Throwable t) {
    	    fail("Caught: " + t);
    	}
    
    	Two two = (Two) proxy;
    	try {
    	    Object object = two.run(new ThingTwo());
    	} catch (Throwable t) {
    	    fail("Caught: " + t);
    	}
    
        }
    
        public static interface One {
    	ThingOne run(Object o);
        }
    
        public static class ThingOne {
        }
    
        public static interface Two {
    	ThingTwo run(Object o);
        }
    
        public static class ThingTwo {
        }
    
        private static class TestInvocationHandler implements InvocationHandler
{
            public Object invoke(Object proxy, Method method, Object[]
 args) throws Throwable {
                return args[0]
;
    	}
        }
    }


Running this code will result in the following exception:


    java.lang.IllegalArgumentException: methods with same signature
run(java.lang.Object) but incompatible return types: [class ReturnTest$ThingOne, class ReturnTest$ThingTwo]
    	at
sun.misc.ProxyGenerator.checkReturnTypes(ProxyGenerator.java:669)
    	at
sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:420)
    	at
sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:306)
    	at java.lang.reflect.Proxy.getProxyClass(Proxy.java:501)
    	at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
    	at ReturnTest.test(ReturnTest.java:36)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at
com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:32)
    

