1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.reflect.InvocationTargetException; 18 import java.lang.reflect.Method; 19 20 // 21 // Two classes A and B with method foo(). 22 // 23 24 class A { A()25 A() { System.out.println("new A"); } 26 foo()27 public void foo() { System.out.println("I am A's foo"); } 28 29 // We previously used to invoke this method with a Y instance, due 30 // to invoke-super underspecified behavior. bar()31 public void bar() { System.out.println("I am A's bar"); } 32 } 33 34 class B { B()35 B() { System.out.println("new B"); } 36 foo()37 public void foo() { System.out.println("I am B's foo"); } 38 } 39 40 // 41 // Two subclasses X and Y that call foo() on super. 42 // 43 44 class X extends A { foo()45 public void foo() { super.foo(); } 46 } 47 48 class Y extends B { foo()49 public void foo() { super.foo(); } 50 } 51 52 // 53 // Driver class. 54 // 55 56 public class Main { 57 main(String[] args)58 public static void main(String[] args) throws Exception { 59 // The normal stuff, X's super goes to A, Y's super goes to B. 60 new X().foo(); 61 new Y().foo(); 62 63 // And now it gets interesting. 64 65 // In bytecode, we define a class Z that is a subclass of A, and we call 66 // invoke-super on an instance of Y. 67 Class<?> z = Class.forName("Z"); 68 Method m = z.getMethod("foo"); 69 try { 70 m.invoke(z.newInstance()); 71 throw new Error("Expected InvocationTargetException"); 72 } catch (InvocationTargetException e) { 73 if (!(e.getCause() instanceof NoSuchMethodError)) { 74 throw new Error("Expected NoSuchMethodError"); 75 } 76 } 77 78 System.out.println("passed"); 79 } 80 } 81