1 /* 2 * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6805864 27 * @summary Redefine an abstract class that is called via a concrete 28 * class and via two interface objects and verify that the right 29 * methods are called. 30 * @comment converted from test/jdk/com/sun/jdi/RedefineAbstractClass.sh 31 * 32 * @library /test/lib 33 * @compile -g RedefineAbstractClass.java 34 * @run main/othervm RedefineAbstractClass 35 */ 36 37 import jdk.test.lib.process.OutputAnalyzer; 38 import lib.jdb.ClassTransformer; 39 import lib.jdb.JdbCommand; 40 import lib.jdb.JdbTest; 41 42 class RedefineAbstractClassTarg { 43 public static void main(String[] args) { 44 System.out.println("This is RedefineAbstractClass"); 45 46 MyConcreteClass foo = new MyConcreteClass(); 47 // do the work once before redefine 48 foo.doWork(); main(String args[])49 50 System.out.println("stop here for redefine"); // @1 breakpoint 51 52 // do the work again after redefine 53 foo.doWork(); 54 55 System.out.println("stop here to check results"); // @2 breakpoint 56 } 57 } 58 59 interface MyInterface1 { 60 public boolean checkFunc(); 61 public boolean isMyInterface1(); 62 } main(String[] args)63 64 interface MyInterface2 { 65 public boolean checkFunc(); 66 public boolean isMyInterface2(); 67 } 68 69 abstract class MyAbstractClass implements MyInterface1, MyInterface2 { 70 static int counter = 0; 71 public boolean checkFunc() { 72 counter++; runTest(String jdwpArg)73 System.out.println("MyAbstractClass.checkFunc() called."); 74 // @1 uncomment System.out.println("This is call " + counter + " to checkFunc"); 75 return true; 76 } 77 public boolean isMyInterface1() { 78 System.out.println("MyAbstractClass.isMyInterface1() called."); 79 return true; 80 } 81 public boolean isMyInterface2() { 82 System.out.println("MyAbstractClass.isMyInterface2() called."); 83 return true; 84 } 85 } 86 87 class MyConcreteClass extends MyAbstractClass { 88 public void doWork() { 89 // checkFunc() is called via invokevirtual here; MyConcreteClass 90 // inherits via MyAbstractClass 91 System.out.println("In doWork() calling checkFunc(): " + checkFunc()); 92 tryDebug(long pid)93 MyInterface1 if1 = (MyInterface1) this; 94 // checkFunc() is called via invokeinterface here; this call will 95 // use the first itable entry 96 System.out.println("In doWork() calling if1.checkFunc(): " + if1.checkFunc()); 97 98 MyInterface2 if2 = (MyInterface2) this; 99 // checkFunc() is called via invokeinterface here; this call will 100 // use the second itable entry 101 System.out.println("In doWork() calling if2.checkFunc(): " + if2.checkFunc()); 102 } 103 } 104 105 106 public class RedefineAbstractClass extends JdbTest { 107 public static void main(String argv[]) { 108 new RedefineAbstractClass().run(); 109 } 110 111 private RedefineAbstractClass() { 112 super(DEBUGGEE_CLASS, SOURCE_FILE); 113 } 114 115 private static final String DEBUGGEE_CLASS = RedefineAbstractClassTarg.class.getName(); 116 private static final String SOURCE_FILE = "RedefineAbstractClass.java"; 117 private static final String ABSTRACT_CLASS = "MyAbstractClass"; 118 119 @Override 120 protected void runCases() { 121 setBreakpoints(1); 122 setBreakpoints(2); 123 jdb.command(JdbCommand.run()); 124 125 // modified version of redefineClass function 126 String transformedClassFile = ClassTransformer.fromTestSource(SOURCE_FILE) 127 .transform(1, ABSTRACT_CLASS, "-g"); 128 jdb.command(JdbCommand.redefine(ABSTRACT_CLASS, transformedClassFile)); 129 // end modified version of redefineClass function 130 131 // this will continue to the second breakpoint 132 jdb.command(JdbCommand.cont()); 133 134 new OutputAnalyzer(getDebuggeeOutput()) 135 .shouldContain("This is call 4 to checkFunc") 136 .shouldContain("This is call 5 to checkFunc") 137 .shouldContain("This is call 6 to checkFunc"); 138 } 139 } 140