Adding old unit tests to test suite.
These tests are copied straight over. They'll still run, but they're
using the old system.
Change-Id: If494519e52ddf858a9febfc55bdae830468cb3c8
diff --git a/test/044-proxy/expected.txt b/test/044-proxy/expected.txt
new file mode 100644
index 0000000..4be26cf
--- /dev/null
+++ b/test/044-proxy/expected.txt
@@ -0,0 +1,80 @@
+Invoke public abstract void Shapes.circle(int)
+ 0: 3
+--- circle 3
+Success: method circle res=null
+Invoke public abstract int Quads.rectangle(int,int)
+ 0: 10
+ 1: 20
+--- rectangle 10,20
+Success: method rectangle res=4
+Invoke public abstract java.lang.String Shapes.blob()
+ (no args)
+--- blob
+Success: method blob res=mix
+Invoke public abstract int Quads.rectangle(int,int)
+ 0: 15
+ 1: 25
+--- rectangle 15,25
+Success: method rectangle res=4
+Invoke public abstract int Quads.trapezoid(int,double,int)
+ 0: 6
+ 1: 81.18
+ 2: 4
+--- trap 6,4,81.18
+Success: method trapezoid res=8
+Invoke public abstract int Colors.red(float)
+ 0: 1.0
+--- red 1.0
+Success: method red res=0
+Invoke public abstract double Colors.blue(int)
+ 0: 777
+--- blue 777
+Success: method blue res=2.54
+Invoke public abstract int Colors.mauve(java.lang.String)
+ 0: sorry
+--- mauve sorry
+Success: method mauve res=3
+Invoke public abstract java.lang.String Shapes.blob()
+ (no args)
+--- blob
+Success: method blob res=mix
+Invoke public abstract void Shapes.upChuck()
+ (no args)
+Got expected ioobe
+Invoke public abstract void Shapes.upCheck() throws java.lang.InterruptedException
+ (no args)
+Got expected ie
+
+Proxy methods: [public native boolean $Proxy0.equals(java.lang.Object), public native int $Proxy0.hashCode(), public native java.lang.String $Proxy0.toString(), public native int $Proxy0.rectangle(int,int), public native int $Proxy0.square(int,int), public native int $Proxy0.trapezoid(int,double,int), public native java.lang.String $Proxy0.blob(), public native void $Proxy0.circle(int), public native void $Proxy0.upCheck(), public native void $Proxy0.upChuck(), public native double $Proxy0.blue(int), public native R0aa $Proxy0.checkMe(), public native int $Proxy0.green(double), public native int $Proxy0.mauve(java.lang.String), public native int $Proxy0.red(float)]
+Decl annos: []
+Param annos (1) : [[]]
+Proxy fields: [private static java.lang.Throwable[][] $Proxy0.throws]
+Dupe threw expected exception
+Clash threw expected exception
+Clash2 threw expected exception
+Clash3 threw expected exception
+Clash4 threw expected exception
+Invoke public abstract void InterfaceW1.throwFunky()
+ (no args)
+Got expected UTE
+Invoke public abstract void InterfaceW1.throwFunky2() throws BaseException,java.lang.NoSuchMethodException,java.io.IOException
+ (no args)
+Got expected IOE
+Invoke public abstract void InterfaceW1.throwFunky2() throws BaseException,java.lang.NoSuchMethodException,java.io.IOException
+ (no args)
+Got expected IOE
+Invoke public abstract void InterfaceW1.throwException() throws BaseException
+ (no args)
+Got expected UTE
+Invoke public abstract void InterfaceW1.throwBase() throws BaseException
+ (no args)
+Got expected UTE
+Invoke public abstract void InterfaceW1.throwSub() throws BaseException
+ (no args)
+Got expected exception
+Invoke public abstract void InterfaceW1.throwSubSub() throws BaseException
+ (no args)
+Got expected exception
+Invoke public abstract void InterfaceW1.bothThrowBase() throws BaseException,SubException,SubSubException
+ (no args)
+Got expected exception
diff --git a/test/044-proxy/info.txt b/test/044-proxy/info.txt
new file mode 100644
index 0000000..08127da
--- /dev/null
+++ b/test/044-proxy/info.txt
@@ -0,0 +1,6 @@
+This is a miscellaneous test that was imported into the new-at-the-time
+runtime test framework. The test is intended to exercise basic features,
+and as such cannot be build on top of junit, since failure of such basic
+features might disrupt junit.
+
+TODO: Real description goes here.
diff --git a/test/044-proxy/src/BasicTest.java b/test/044-proxy/src/BasicTest.java
new file mode 100644
index 0000000..2a453c4
--- /dev/null
+++ b/test/044-proxy/src/BasicTest.java
@@ -0,0 +1,263 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+
+/**
+ * Do some basic tests.
+ */
+public class BasicTest {
+
+ public static void main(String[] args) {
+ Mix proxyMe = new Mix();
+ Object proxy = createProxy(proxyMe);
+
+ if (!Proxy.isProxyClass(proxy.getClass()))
+ System.err.println("not a proxy class?");
+ if (Proxy.getInvocationHandler(proxy) == null)
+ System.err.println("ERROR: Proxy.getInvocationHandler is null");
+
+ /* take it for a spin; verifies instanceof constraint */
+ Shapes shapes = (Shapes) proxy;
+ shapes.circle(3);
+ shapes.rectangle(10, 20);
+ shapes.blob();
+ Quads quads = (Quads) proxy;
+ quads.rectangle(15, 25);
+ quads.trapezoid(6, 81.18, 4);
+ Colors colors = (Colors) proxy;
+ colors.red(1.0f);
+ colors.blue(777);
+ colors.mauve("sorry");
+ colors.blob();
+
+ try {
+ shapes.upChuck();
+ System.out.println("Didn't get expected exception");
+ } catch (IndexOutOfBoundsException ioobe) {
+ System.out.println("Got expected ioobe");
+ }
+ try {
+ shapes.upCheck();
+ System.out.println("Didn't get expected exception");
+ } catch (InterruptedException ie) {
+ System.out.println("Got expected ie");
+ }
+
+ /*
+ * Exercise annotations on Proxy classes. This is mostly to ensure
+ * that annotation calls work correctly on generated classes.
+ */
+ System.out.println("");
+ Method[] methods = proxy.getClass().getDeclaredMethods();
+ System.out.println("Proxy methods: " + Arrays.deepToString(methods));
+ Method meth = methods[methods.length -1];
+ System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations()));
+ Annotation[][] paramAnnos = meth.getParameterAnnotations();
+ System.out.println("Param annos (" + paramAnnos.length + ") : "
+ + Arrays.deepToString(paramAnnos));
+ Field[] fields = proxy.getClass().getDeclaredFields();
+ System.out.println("Proxy fields: " + Arrays.deepToString(fields));
+ }
+
+ static Object createProxy(Object proxyMe) {
+ /* declare an object that will handle the method calls */
+ InvocationHandler handler = new MyInvocationHandler(proxyMe);
+
+ /* create the proxy class */
+ Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(),
+ new Class[] { Quads.class, Colors.class });
+
+ /* create a proxy object, passing the handler object in */
+ Object proxy = null;
+ try {
+ Constructor<Class> cons;
+ cons = proxyClass.getConstructor(
+ new Class[] { InvocationHandler.class });
+ //System.out.println("Constructor is " + cons);
+ proxy = cons.newInstance(new Object[] { handler });
+ } catch (NoSuchMethodException nsme) {
+ System.err.println("failed: " + nsme);
+ } catch (InstantiationException ie) {
+ System.err.println("failed: " + ie);
+ } catch (IllegalAccessException ie) {
+ System.err.println("failed: " + ie);
+ } catch (InvocationTargetException ite) {
+ System.err.println("failed: " + ite);
+ }
+
+ return proxy;
+ }
+}
+
+/*
+ * Some interfaces.
+ */
+interface Shapes {
+ public void circle(int r);
+ public int rectangle(int x, int y);
+
+ public String blob();
+
+ public R0base checkMe();
+ public void upChuck();
+ public void upCheck() throws InterruptedException;
+}
+
+interface Quads extends Shapes {
+ public int rectangle(int x, int y);
+ public int square(int x, int y);
+ public int trapezoid(int x, double off, int y);
+
+ public R0a checkMe();
+}
+
+/*
+ * More interfaces.
+ */
+interface Colors {
+ public int red(float howRed);
+ public int green(double howGreen);
+ public double blue(int howBlue);
+ public int mauve(String apology);
+
+ public String blob();
+
+ public R0aa checkMe();
+}
+
+/*
+ * Some return types.
+ */
+class R0base { int mBlah; }
+class R0a extends R0base { int mBlah_a; }
+class R0aa extends R0a { int mBlah_aa; }
+
+
+/*
+ * A class that implements them all.
+ */
+class Mix implements Quads, Colors {
+ public void circle(int r) {
+ System.out.println("--- circle " + r);
+ }
+ public int rectangle(int x, int y) {
+ System.out.println("--- rectangle " + x + "," + y);
+ return 4;
+ }
+ public int square(int x, int y) {
+ System.out.println("--- square " + x + "," + y);
+ return 4;
+ }
+ public int trapezoid(int x, double off, int y) {
+ System.out.println("--- trap " + x + "," + y + "," + off);
+ return 8;
+ }
+ public String blob() {
+ System.out.println("--- blob");
+ return "mix";
+ }
+
+ public int red(float howRed) {
+ System.out.println("--- red " + howRed);
+ return 0;
+ }
+ public int green(double howGreen) {
+ System.out.println("--- green " + howGreen);
+ return 1;
+ }
+ public double blue(int howBlue) {
+ System.out.println("--- blue " + howBlue);
+ return 2.54;
+ }
+ public int mauve(String apology) {
+ System.out.println("--- mauve " + apology);
+ return 3;
+ }
+
+ public R0aa checkMe() {
+ return null;
+ }
+ public void upChuck() {
+ throw new IndexOutOfBoundsException("upchuck");
+ }
+ public void upCheck() throws InterruptedException {
+ throw new InterruptedException("upcheck");
+ }
+}
+
+/*
+ * Invocation handler, defining the implementation of the proxy functions.
+ */
+class MyInvocationHandler implements InvocationHandler {
+ Object mObj;
+
+ public MyInvocationHandler(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 (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;
+ }
+}
diff --git a/test/044-proxy/src/Clash.java b/test/044-proxy/src/Clash.java
new file mode 100644
index 0000000..adeffdc
--- /dev/null
+++ b/test/044-proxy/src/Clash.java
@@ -0,0 +1,70 @@
+/*
+ * 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.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/*
+ * Try to instantiate a proxy class with interfaces that have conflicting
+ * duplicate methods (primitive vs. object).
+ */
+public class Clash {
+ public static void main(String[] args) {
+ InvocationHandler handler = new ClashInvocationHandler();
+
+ /* try passing in the same interface twice */
+ try {
+ Proxy.newProxyInstance(Clash.class.getClassLoader(),
+ new Class[] { Interface1A.class, Interface1A.class },
+ handler);
+ System.err.println("Dupe did not throw expected exception");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Dupe threw expected exception");
+ }
+
+ try {
+ Proxy.newProxyInstance(Clash.class.getClassLoader(),
+ new Class[] { Interface1A.class, Interface1B.class },
+ handler);
+ System.err.println("Clash did not throw expected exception");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Clash threw expected exception");
+ }
+ }
+}
+
+interface Interface1A {
+ public int thisIsOkay();
+
+ public float thisIsTrouble();
+}
+
+interface Interface1B {
+ public int thisIsOkay();
+
+ public Object thisIsTrouble();
+}
+
+class ClashInvocationHandler implements InvocationHandler {
+ /* don't really need to do anything -- should never get this far */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ return null;
+ }
+}
diff --git a/test/044-proxy/src/Clash2.java b/test/044-proxy/src/Clash2.java
new file mode 100644
index 0000000..2a384f4
--- /dev/null
+++ b/test/044-proxy/src/Clash2.java
@@ -0,0 +1,60 @@
+/*
+ * 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.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/*
+ * Try to instantiate a proxy class with interfaces that have conflicting
+ * duplicate methods (primitive types).
+ */
+public class Clash2 {
+ public static void main(String[] args) {
+ InvocationHandler handler = new Clash2InvocationHandler();
+
+ try {
+ Proxy.newProxyInstance(Clash.class.getClassLoader(),
+ new Class[] { Interface2A.class, Interface2B.class },
+ handler);
+ System.err.println("Clash2 did not throw expected exception");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Clash2 threw expected exception");
+ }
+ }
+}
+
+interface Interface2A {
+ public int thisIsOkay();
+
+ public int thisIsTrouble();
+}
+
+interface Interface2B {
+ public int thisIsOkay();
+
+ public short thisIsTrouble();
+}
+
+class Clash2InvocationHandler implements InvocationHandler {
+ /* don't really need to do anything -- should never get this far */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ return null;
+ }
+}
diff --git a/test/044-proxy/src/Clash3.java b/test/044-proxy/src/Clash3.java
new file mode 100644
index 0000000..6d6f2f2
--- /dev/null
+++ b/test/044-proxy/src/Clash3.java
@@ -0,0 +1,75 @@
+/*
+ * 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.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/*
+ * Try to instantiate a proxy class with interfaces that have conflicting
+ * duplicate methods (type tree with interface).
+ */
+public class Clash3 {
+ public static void main(String[] args) {
+ InvocationHandler handler = new Clash3InvocationHandler();
+
+ try {
+ Proxy.newProxyInstance(Clash.class.getClassLoader(),
+ new Class[] {
+ Interface3a.class,
+ Interface3base.class,
+ Interface3aa.class,
+ Interface3b.class },
+ handler);
+ System.err.println("Clash3 did not throw expected exception");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Clash3 threw expected exception");
+ }
+ }
+}
+
+class R3base implements I3 { int mBlah; public void x() {} }
+class R3a extends R3base { int mBlah_a; }
+class R3aa extends R3a { int mBlah_aa; }
+class R3b implements I3 { int mBlah_b; public void x() {} }
+
+interface I3 {
+ void x();
+}
+
+interface Interface3base {
+ public R3base thisIsTrouble();
+}
+
+interface Interface3a {
+ public R3a thisIsTrouble();
+}
+interface Interface3aa {
+ public R3aa thisIsTrouble();
+}
+interface Interface3b {
+ public R3b thisIsTrouble();
+}
+
+class Clash3InvocationHandler implements InvocationHandler {
+ /* don't really need to do anything -- should never get this far */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ return null;
+ }
+}
diff --git a/test/044-proxy/src/Clash4.java b/test/044-proxy/src/Clash4.java
new file mode 100644
index 0000000..1bfb37f
--- /dev/null
+++ b/test/044-proxy/src/Clash4.java
@@ -0,0 +1,77 @@
+/*
+ * 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.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/*
+ * Try to instantiate a proxy class with interfaces that have conflicting
+ * duplicate methods (tree of types).
+ */
+public class Clash4 {
+ public static void main(String[] args) {
+ InvocationHandler handler = new Clash4InvocationHandler();
+
+ try {
+ Proxy.newProxyInstance(Clash.class.getClassLoader(),
+ new Class[] {
+ Interface4a.class,
+ Interface4aa.class,
+ Interface4base.class,
+ Interface4b.class,
+ Interface4bb.class },
+ handler);
+ System.err.println("Clash4 did not throw expected exception");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Clash4 threw expected exception");
+ //System.out.println(iae);
+ }
+ }
+}
+
+class R4base { int mBlah; }
+class R4a extends R4base { int mBlah_a; }
+class R4aa extends R4a { int mBlah_aa; }
+class R4b extends R4base { int mBlah_b; }
+class R4bb extends R4b { int mBlah_bb; }
+
+interface Interface4base {
+ public R4base thisIsTrouble();
+}
+
+interface Interface4a {
+ public R4a thisIsTrouble();
+}
+interface Interface4aa {
+ public R4aa thisIsTrouble();
+}
+interface Interface4b {
+ public R4b thisIsTrouble();
+}
+interface Interface4bb {
+ public R4bb thisIsTrouble();
+}
+
+class Clash4InvocationHandler implements InvocationHandler {
+ /* don't really need to do anything -- should never get this far */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ return null;
+ }
+}
diff --git a/test/044-proxy/src/Main.java b/test/044-proxy/src/Main.java
new file mode 100644
index 0000000..01926af
--- /dev/null
+++ b/test/044-proxy/src/Main.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test java.lang.reflect.Proxy
+ */
+public class Main {
+ public static void main(String[] args) {
+ BasicTest.main(null);
+ Clash.main(null);
+ Clash2.main(null);
+ Clash3.main(null);
+ Clash4.main(null);
+ WrappedThrow.main(null);
+ }
+}
diff --git a/test/044-proxy/src/WrappedThrow.java b/test/044-proxy/src/WrappedThrow.java
new file mode 100644
index 0000000..27ae84e
--- /dev/null
+++ b/test/044-proxy/src/WrappedThrow.java
@@ -0,0 +1,244 @@
+/*
+ * 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.err.println("No exception thrown");
+ } catch (UndeclaredThrowableException ute) {
+ System.out.println("Got expected UTE");
+ } catch (Throwable t) {
+ System.err.println("Got unexpected exception: " + t);
+ }
+
+ try {
+ if1.throwFunky2();
+ System.err.println("No exception thrown");
+ } catch (IOException ioe) {
+ System.out.println("Got expected IOE");
+ } catch (Throwable t) {
+ System.err.println("Got unexpected exception: " + t);
+ }
+
+ try {
+ if2.throwFunky2();
+ System.err.println("No exception thrown");
+ } catch (IOException ioe) {
+ System.out.println("Got expected IOE");
+ } catch (Throwable t) {
+ System.err.println("Got unexpected exception: " + t);
+ }
+
+ /*
+ * Throw exceptions, walking down the hierarchy.
+ */
+ try {
+ if1.throwException();
+ System.err.println("No exception thrown");
+ } catch (UndeclaredThrowableException ute) {
+ System.out.println("Got expected UTE");
+ } catch (Throwable t) {
+ System.err.println("Got unexpected exception: " + t);
+ }
+
+ try {
+ if1.throwBase();
+ System.err.println("No exception thrown");
+ } catch (UndeclaredThrowableException ute) {
+ System.out.println("Got expected UTE");
+ } catch (Throwable t) {
+ System.err.println("Got unexpected exception: " + t);
+ }
+
+ try {
+ if2.throwSub();
+ System.err.println("No exception thrown");
+ } catch (SubException se) {
+ System.out.println("Got expected exception");
+ } catch (Throwable t) {
+ System.err.println("Got unexpected exception: " + t);
+ }
+
+ try {
+ if2.throwSubSub();
+ System.err.println("No exception thrown");
+ } catch (SubException se) {
+ System.out.println("Got expected exception");
+ } catch (Throwable t) {
+ System.err.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.err.println("No exception thrown");
+ } catch (BaseException se) {
+ System.out.println("Got expected exception");
+ } catch (Throwable t) {
+ System.err.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;
+ }
+}