/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; /* * Create a Proxy class that blah. */ public class WrappedThrow { public static void main(String[] args) { WTMix mix = new WTMix(); InvocationHandler handler = new WTInvocationHandler(mix); Object proxy; try { proxy = Proxy.newProxyInstance(WrappedThrow.class.getClassLoader(), new Class<?>[] { InterfaceW1.class, InterfaceW2.class }, handler); } catch (IllegalArgumentException iae) { System.out.println("WT init failed"); return; } InterfaceW1 if1 = (InterfaceW1) proxy; InterfaceW2 if2 = (InterfaceW2) proxy; try { if1.throwFunky(); System.out.println("No exception thrown"); } catch (UndeclaredThrowableException ute) { System.out.println("Got expected UTE"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } try { if1.throwFunky2(); System.out.println("No exception thrown"); } catch (IOException ioe) { System.out.println("Got expected IOE"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } try { if2.throwFunky2(); System.out.println("No exception thrown"); } catch (IOException ioe) { System.out.println("Got expected IOE"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } /* * Throw exceptions, walking down the hierarchy. */ try { if1.throwException(); System.out.println("No exception thrown"); } catch (UndeclaredThrowableException ute) { System.out.println("Got expected UTE"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } try { if1.throwBase(); System.out.println("No exception thrown"); } catch (UndeclaredThrowableException ute) { System.out.println("Got expected UTE"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } try { if2.throwSub(); System.out.println("No exception thrown"); } catch (SubException se) { System.out.println("Got expected exception"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } try { if2.throwSubSub(); System.out.println("No exception thrown"); } catch (SubException se) { System.out.println("Got expected exception"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } /* * Make sure that, if the class explicitly allows the base * class of an exception, that we still allow it. */ try { if1.bothThrowBase(); System.out.println("No exception thrown"); } catch (BaseException se) { System.out.println("Got expected exception"); } catch (Throwable t) { System.out.println("Got unexpected exception: " + t); } } } class BaseException extends Exception {} class SubException extends BaseException {} class SubSubException extends SubException {} interface InterfaceW1 { public void throwFunky(); public void throwFunky2() throws BaseException, NoSuchMethodException, IOException; public void throwException() throws BaseException; public void throwBase() throws BaseException; public void throwSub() throws BaseException; public void throwSubSub() throws BaseException; public void bothThrowBase() throws BaseException, SubException, SubSubException; } interface InterfaceW2 { public void throwFunky2() throws InterruptedException, NoSuchMethodException, IOException; public void throwException() throws SubException; public void throwBase() throws SubException; public void throwSub() throws SubException; public void throwSubSub() throws SubException; public void bothThrowBase() throws SubException, BaseException, SubSubException; } /** * Implement all of the proxied interfaces. */ class WTMix implements InterfaceW1, InterfaceW2 { public int dastardlyDeed() throws SubException { System.out.println("Throwing SubException"); throw new SubException(); } /* these don't actually get called; they just cause exceptions */ public void throwFunky() {} public void throwFunky2() {} public void throwException() throws SubException {} public void throwBase() throws SubException {} public void throwSub() throws SubException {} public void throwSubSub() throws SubException {} public void bothThrowBase() throws BaseException, SubException {} } /** * Invocation handler for our proxy class. */ class WTInvocationHandler implements InvocationHandler { private Object mObj; public WTInvocationHandler(Object obj) { mObj = obj; } /* * This is called when anything gets invoked in the proxy object. */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; // Trap Object calls. This is important here to avoid a recursive // invocation of toString() in the print statements below. if (method.getDeclaringClass() == java.lang.Object.class) { //System.out.println("!!! object " + method.getName()); if (method.getName().equals("toString")) return super.toString(); else if (method.getName().equals("hashCode")) return Integer.valueOf(super.hashCode()); else if (method.getName().equals("equals")) return Boolean.valueOf(super.equals(args[0])); else throw new RuntimeException("huh?"); } System.out.println("Invoke " + method); if (args == null || args.length == 0) { System.out.println(" (no args)"); } else { for (int i = 0; i < args.length; i++) System.out.println(" " + i + ": " + args[i]); } try { if (method.getName().equals("throwFunky")) throw new InterruptedException("fake"); if (method.getName().equals("throwFunky2")) throw new IOException("fake2"); if (method.getName().equals("throwException")) throw new Exception(); if (method.getName().equals("throwBase")) throw new BaseException(); if (method.getName().equals("throwSub")) throw new SubException(); if (method.getName().equals("throwSubSub")) throw new SubSubException(); if (method.getName().equals("bothThrowBase")) throw new BaseException(); if (true) result = method.invoke(mObj, args); else result = -1; System.out.println("Success: method " + method.getName() + " res=" + result); } catch (InvocationTargetException ite) { throw ite.getTargetException(); } catch (IllegalAccessException iae) { throw new RuntimeException(iae); } return result; } }