You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
8.2 KiB
245 lines
8.2 KiB
/*
|
|
* 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;
|
|
}
|
|
}
|