1 /* 2 * Copyright (c) 2019, 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 import java.util.concurrent.BlockingQueue; 26 import java.util.concurrent.SynchronousQueue; 27 28 public class MethodSortingApp { 29 static class HelloA { 30 String aaaa() { return "aaaa"; } 31 String bbbb() { return "bbbb"; } 32 String dddd() { return "dddd"; } 33 String eeee() { return "eeee"; } 34 String gggg() { return "gggg"; } 35 } 36 37 static class HelloA1 extends HelloA { 38 String aaaa() { return "aaa-"; } 39 String dddd() { return "ddd-"; } 40 String gggg() { return "ggg-"; } 41 } 42 43 static class HelloB { 44 String aaaa() { return "aaaa"; } 45 String cccc() { return "cccc"; } 46 String dddd() { return "dddd"; } 47 String ffff() { return "ffff"; } 48 String gggg() { return "gggg"; } 49 } 50 51 static class HelloB1 extends HelloB { 52 String aaaa() { return "aaa-"; } 53 String dddd() { return "ddd-"; } 54 String gggg() { return "ggg-"; } 55 } 56 57 // Default methods in interfaces must be sorted 58 static interface InterfaceA { 59 default public String aaa() { return "aaa";} 60 default public String bbb() { return "bbb";} 61 default public String ddd() { return "ddd";} 62 default public String eee() { return "eee";} 63 default public String ggg() { return "ggg";} 64 } 65 66 static class ImplementorA implements InterfaceA { 67 public String aaa() { return "aa-";} 68 } 69 70 static class ImplementorA1 extends ImplementorA { 71 public String bbb() { return "bb-";} 72 } 73 74 static interface InterfaceB { 75 default public String aaa() { return "aaa"; } 76 default public String ccc() { return "ccc"; } 77 default public String ddd() { return "ddd"; } 78 default public String fff() { return "fff"; } 79 default public String ggg() { return "ggg"; } 80 } 81 82 static class ImplementorB implements InterfaceB { 83 public String ggg() { return "gg-";} 84 } 85 86 static class ImplementorB1 extends ImplementorB { 87 public String fff() { return "ff-";} 88 } 89 90 91 public static void main(String args[]) { 92 testSimpleMethods(); 93 testDefaultMethods(); 94 testMixedInterfaces(); 95 } 96 97 static void testSimpleMethods() { 98 // When HelloA and HelloB are copied into the dynamic archive, the Symbols 99 // for their method's names will have a different sorting order. This requires 100 // that the dumped InstanceKlass to re-sort their "methods" array and re-layout 101 // the vtables/itables. 102 HelloA1 a1 = new HelloA1(); 103 HelloA a = new HelloA(); 104 assertEqual(a.aaaa(), "aaaa"); 105 assertEqual(a.bbbb(), "bbbb"); 106 assertEqual(a.dddd(), "dddd"); 107 assertEqual(a.eeee(), "eeee"); 108 assertEqual(a.gggg(), "gggg"); 109 110 assertEqual(a1.aaaa(), "aaa-"); 111 assertEqual(a1.bbbb(), "bbbb"); 112 assertEqual(a1.dddd(), "ddd-"); 113 assertEqual(a1.eeee(), "eeee"); 114 assertEqual(a1.gggg(), "ggg-"); 115 116 HelloB b = new HelloB(); 117 assertEqual(b.aaaa(), "aaaa"); 118 assertEqual(b.cccc(), "cccc"); 119 assertEqual(b.dddd(), "dddd"); 120 assertEqual(b.ffff(), "ffff"); 121 assertEqual(b.gggg(), "gggg"); 122 123 HelloB b1 = new HelloB1(); 124 assertEqual(b1.aaaa(), "aaa-"); 125 assertEqual(b1.cccc(), "cccc"); 126 assertEqual(b1.dddd(), "ddd-"); 127 assertEqual(b1.ffff(), "ffff"); 128 assertEqual(b1.gggg(), "ggg-"); 129 } 130 131 static void testDefaultMethods() { 132 InterfaceA a1 = new ImplementorA1(); 133 InterfaceA a = new ImplementorA(); 134 135 assertEqual(a.aaa(), "aa-"); 136 assertEqual(a.bbb(), "bbb"); 137 assertEqual(a.ddd(), "ddd"); 138 assertEqual(a.eee(), "eee"); 139 assertEqual(a.ggg(), "ggg"); 140 141 assertEqual(a1.aaa(), "aa-"); 142 assertEqual(a1.bbb(), "bb-"); 143 assertEqual(a1.ddd(), "ddd"); 144 assertEqual(a1.eee(), "eee"); 145 assertEqual(a1.ggg(), "ggg"); 146 147 InterfaceB b = new ImplementorB(); 148 InterfaceB b1 = new ImplementorB1(); 149 150 assertEqual(b.aaa(), "aaa"); 151 assertEqual(b.ccc(), "ccc"); 152 assertEqual(b.ddd(), "ddd"); 153 assertEqual(b.fff(), "fff"); 154 assertEqual(b.ggg(), "gg-"); 155 156 assertEqual(b1.aaa(), "aaa"); 157 assertEqual(b1.ccc(), "ccc"); 158 assertEqual(b1.ddd(), "ddd"); 159 assertEqual(b1.fff(), "ff-"); 160 assertEqual(b1.ggg(), "gg-"); 161 } 162 163 // This is a regression test for an earlier bug in 164 // DynamicArchiveBuilder::relocate_buffer_to_target() 165 static void testMixedInterfaces() { 166 Object xx = new SynchronousQueue(); 167 BlockingQueue yy = (BlockingQueue)xx; 168 } 169 170 static private void assertEqual(String a, String b) { 171 if (!a.equals(b)) { 172 throw new RuntimeException(a + " is not equal to " + b); 173 } else { 174 System.out.println("Expected: " + a + ", got: " + b); 175 } 176 } 177 }