1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.io.IOException; 18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationHandler; 19*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException; 20*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method; 21*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Proxy; 22*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.UndeclaredThrowableException; 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker /* 25*795d594fSAndroid Build Coastguard Worker * Create a Proxy class that blah. 26*795d594fSAndroid Build Coastguard Worker */ 27*795d594fSAndroid Build Coastguard Worker public class WrappedThrow { main(String[] args)28*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 29*795d594fSAndroid Build Coastguard Worker WTMix mix = new WTMix(); 30*795d594fSAndroid Build Coastguard Worker InvocationHandler handler = new WTInvocationHandler(mix); 31*795d594fSAndroid Build Coastguard Worker Object proxy; 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker try { 34*795d594fSAndroid Build Coastguard Worker proxy = Proxy.newProxyInstance(WrappedThrow.class.getClassLoader(), 35*795d594fSAndroid Build Coastguard Worker new Class<?>[] { InterfaceW1.class, InterfaceW2.class }, 36*795d594fSAndroid Build Coastguard Worker handler); 37*795d594fSAndroid Build Coastguard Worker } catch (IllegalArgumentException iae) { 38*795d594fSAndroid Build Coastguard Worker System.out.println("WT init failed"); 39*795d594fSAndroid Build Coastguard Worker return; 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker InterfaceW1 if1 = (InterfaceW1) proxy; 43*795d594fSAndroid Build Coastguard Worker InterfaceW2 if2 = (InterfaceW2) proxy; 44*795d594fSAndroid Build Coastguard Worker try { 45*795d594fSAndroid Build Coastguard Worker if1.throwFunky(); 46*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 47*795d594fSAndroid Build Coastguard Worker } catch (UndeclaredThrowableException ute) { 48*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected UTE"); 49*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 50*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 51*795d594fSAndroid Build Coastguard Worker } 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker try { 54*795d594fSAndroid Build Coastguard Worker if1.throwFunky2(); 55*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 56*795d594fSAndroid Build Coastguard Worker } catch (IOException ioe) { 57*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected IOE"); 58*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 59*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 60*795d594fSAndroid Build Coastguard Worker } 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker try { 63*795d594fSAndroid Build Coastguard Worker if2.throwFunky2(); 64*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 65*795d594fSAndroid Build Coastguard Worker } catch (IOException ioe) { 66*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected IOE"); 67*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 68*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker /* 72*795d594fSAndroid Build Coastguard Worker * Throw exceptions, walking down the hierarchy. 73*795d594fSAndroid Build Coastguard Worker */ 74*795d594fSAndroid Build Coastguard Worker try { 75*795d594fSAndroid Build Coastguard Worker if1.throwException(); 76*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 77*795d594fSAndroid Build Coastguard Worker } catch (UndeclaredThrowableException ute) { 78*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected UTE"); 79*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 80*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker try { 84*795d594fSAndroid Build Coastguard Worker if1.throwBase(); 85*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 86*795d594fSAndroid Build Coastguard Worker } catch (UndeclaredThrowableException ute) { 87*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected UTE"); 88*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 89*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 90*795d594fSAndroid Build Coastguard Worker } 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker try { 93*795d594fSAndroid Build Coastguard Worker if2.throwSub(); 94*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 95*795d594fSAndroid Build Coastguard Worker } catch (SubException se) { 96*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 97*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 98*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 99*795d594fSAndroid Build Coastguard Worker } 100*795d594fSAndroid Build Coastguard Worker 101*795d594fSAndroid Build Coastguard Worker try { 102*795d594fSAndroid Build Coastguard Worker if2.throwSubSub(); 103*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 104*795d594fSAndroid Build Coastguard Worker } catch (SubException se) { 105*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 106*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 107*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 108*795d594fSAndroid Build Coastguard Worker } 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker /* 111*795d594fSAndroid Build Coastguard Worker * Make sure that, if the class explicitly allows the base 112*795d594fSAndroid Build Coastguard Worker * class of an exception, that we still allow it. 113*795d594fSAndroid Build Coastguard Worker */ 114*795d594fSAndroid Build Coastguard Worker try { 115*795d594fSAndroid Build Coastguard Worker if1.bothThrowBase(); 116*795d594fSAndroid Build Coastguard Worker System.out.println("No exception thrown"); 117*795d594fSAndroid Build Coastguard Worker } catch (BaseException se) { 118*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 119*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 120*795d594fSAndroid Build Coastguard Worker System.out.println("Got unexpected exception: " + t); 121*795d594fSAndroid Build Coastguard Worker } 122*795d594fSAndroid Build Coastguard Worker } 123*795d594fSAndroid Build Coastguard Worker } 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker class BaseException extends Exception {} 126*795d594fSAndroid Build Coastguard Worker class SubException extends BaseException {} 127*795d594fSAndroid Build Coastguard Worker class SubSubException extends SubException {} 128*795d594fSAndroid Build Coastguard Worker 129*795d594fSAndroid Build Coastguard Worker interface InterfaceW1 { throwFunky()130*795d594fSAndroid Build Coastguard Worker public void throwFunky(); 131*795d594fSAndroid Build Coastguard Worker throwFunky2()132*795d594fSAndroid Build Coastguard Worker public void throwFunky2() throws BaseException, 133*795d594fSAndroid Build Coastguard Worker NoSuchMethodException, IOException; 134*795d594fSAndroid Build Coastguard Worker throwException()135*795d594fSAndroid Build Coastguard Worker public void throwException() throws BaseException; throwBase()136*795d594fSAndroid Build Coastguard Worker public void throwBase() throws BaseException; throwSub()137*795d594fSAndroid Build Coastguard Worker public void throwSub() throws BaseException; throwSubSub()138*795d594fSAndroid Build Coastguard Worker public void throwSubSub() throws BaseException; 139*795d594fSAndroid Build Coastguard Worker bothThrowBase()140*795d594fSAndroid Build Coastguard Worker public void bothThrowBase() throws BaseException, SubException, SubSubException; 141*795d594fSAndroid Build Coastguard Worker } 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker interface InterfaceW2 { throwFunky2()144*795d594fSAndroid Build Coastguard Worker public void throwFunky2() throws InterruptedException, 145*795d594fSAndroid Build Coastguard Worker NoSuchMethodException, IOException; 146*795d594fSAndroid Build Coastguard Worker throwException()147*795d594fSAndroid Build Coastguard Worker public void throwException() throws SubException; throwBase()148*795d594fSAndroid Build Coastguard Worker public void throwBase() throws SubException; throwSub()149*795d594fSAndroid Build Coastguard Worker public void throwSub() throws SubException; throwSubSub()150*795d594fSAndroid Build Coastguard Worker public void throwSubSub() throws SubException; 151*795d594fSAndroid Build Coastguard Worker bothThrowBase()152*795d594fSAndroid Build Coastguard Worker public void bothThrowBase() throws SubException, BaseException, SubSubException; 153*795d594fSAndroid Build Coastguard Worker } 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker /** 156*795d594fSAndroid Build Coastguard Worker * Implement all of the proxied interfaces. 157*795d594fSAndroid Build Coastguard Worker */ 158*795d594fSAndroid Build Coastguard Worker class WTMix implements InterfaceW1, InterfaceW2 { dastardlyDeed()159*795d594fSAndroid Build Coastguard Worker public int dastardlyDeed() throws SubException { 160*795d594fSAndroid Build Coastguard Worker System.out.println("Throwing SubException"); 161*795d594fSAndroid Build Coastguard Worker throw new SubException(); 162*795d594fSAndroid Build Coastguard Worker } 163*795d594fSAndroid Build Coastguard Worker 164*795d594fSAndroid Build Coastguard Worker /* these don't actually get called; they just cause exceptions */ throwFunky()165*795d594fSAndroid Build Coastguard Worker public void throwFunky() {} throwFunky2()166*795d594fSAndroid Build Coastguard Worker public void throwFunky2() {} throwException()167*795d594fSAndroid Build Coastguard Worker public void throwException() throws SubException {} throwBase()168*795d594fSAndroid Build Coastguard Worker public void throwBase() throws SubException {} throwSub()169*795d594fSAndroid Build Coastguard Worker public void throwSub() throws SubException {} throwSubSub()170*795d594fSAndroid Build Coastguard Worker public void throwSubSub() throws SubException {} 171*795d594fSAndroid Build Coastguard Worker bothThrowBase()172*795d594fSAndroid Build Coastguard Worker public void bothThrowBase() throws BaseException, SubException {} 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker 175*795d594fSAndroid Build Coastguard Worker /** 176*795d594fSAndroid Build Coastguard Worker * Invocation handler for our proxy class. 177*795d594fSAndroid Build Coastguard Worker */ 178*795d594fSAndroid Build Coastguard Worker class WTInvocationHandler implements InvocationHandler { 179*795d594fSAndroid Build Coastguard Worker private Object mObj; 180*795d594fSAndroid Build Coastguard Worker WTInvocationHandler(Object obj)181*795d594fSAndroid Build Coastguard Worker public WTInvocationHandler(Object obj) { 182*795d594fSAndroid Build Coastguard Worker mObj = obj; 183*795d594fSAndroid Build Coastguard Worker } 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker /* 186*795d594fSAndroid Build Coastguard Worker * This is called when anything gets invoked in the proxy object. 187*795d594fSAndroid Build Coastguard Worker */ invoke(Object proxy, Method method, Object[] args)188*795d594fSAndroid Build Coastguard Worker public Object invoke(Object proxy, Method method, Object[] args) 189*795d594fSAndroid Build Coastguard Worker throws Throwable { 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker Object result = null; 192*795d594fSAndroid Build Coastguard Worker 193*795d594fSAndroid Build Coastguard Worker // Trap Object calls. This is important here to avoid a recursive 194*795d594fSAndroid Build Coastguard Worker // invocation of toString() in the print statements below. 195*795d594fSAndroid Build Coastguard Worker if (method.getDeclaringClass() == java.lang.Object.class) { 196*795d594fSAndroid Build Coastguard Worker //System.out.println("!!! object " + method.getName()); 197*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("toString")) 198*795d594fSAndroid Build Coastguard Worker return super.toString(); 199*795d594fSAndroid Build Coastguard Worker else if (method.getName().equals("hashCode")) 200*795d594fSAndroid Build Coastguard Worker return Integer.valueOf(super.hashCode()); 201*795d594fSAndroid Build Coastguard Worker else if (method.getName().equals("equals")) 202*795d594fSAndroid Build Coastguard Worker return Boolean.valueOf(super.equals(args[0])); 203*795d594fSAndroid Build Coastguard Worker else 204*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("huh?"); 205*795d594fSAndroid Build Coastguard Worker } 206*795d594fSAndroid Build Coastguard Worker 207*795d594fSAndroid Build Coastguard Worker System.out.println("Invoke " + method); 208*795d594fSAndroid Build Coastguard Worker if (args == null || args.length == 0) { 209*795d594fSAndroid Build Coastguard Worker System.out.println(" (no args)"); 210*795d594fSAndroid Build Coastguard Worker } else { 211*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < args.length; i++) 212*795d594fSAndroid Build Coastguard Worker System.out.println(" " + i + ": " + args[i]); 213*795d594fSAndroid Build Coastguard Worker } 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker try { 216*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("throwFunky")) 217*795d594fSAndroid Build Coastguard Worker throw new InterruptedException("fake"); 218*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("throwFunky2")) 219*795d594fSAndroid Build Coastguard Worker throw new IOException("fake2"); 220*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("throwException")) 221*795d594fSAndroid Build Coastguard Worker throw new Exception(); 222*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("throwBase")) 223*795d594fSAndroid Build Coastguard Worker throw new BaseException(); 224*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("throwSub")) 225*795d594fSAndroid Build Coastguard Worker throw new SubException(); 226*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("throwSubSub")) 227*795d594fSAndroid Build Coastguard Worker throw new SubSubException(); 228*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("bothThrowBase")) 229*795d594fSAndroid Build Coastguard Worker throw new BaseException(); 230*795d594fSAndroid Build Coastguard Worker 231*795d594fSAndroid Build Coastguard Worker if (true) 232*795d594fSAndroid Build Coastguard Worker result = method.invoke(mObj, args); 233*795d594fSAndroid Build Coastguard Worker else 234*795d594fSAndroid Build Coastguard Worker result = -1; 235*795d594fSAndroid Build Coastguard Worker System.out.println("Success: method " + method.getName() 236*795d594fSAndroid Build Coastguard Worker + " res=" + result); 237*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ite) { 238*795d594fSAndroid Build Coastguard Worker throw ite.getTargetException(); 239*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException iae) { 240*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(iae); 241*795d594fSAndroid Build Coastguard Worker } 242*795d594fSAndroid Build Coastguard Worker return result; 243*795d594fSAndroid Build Coastguard Worker } 244*795d594fSAndroid Build Coastguard Worker } 245