1 /*
   2  * Copyright (c) 2008, 2012, 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 /* @test
  25  * @summary unit tests for java.lang.invoke.MethodType
  26  * @compile MethodTypeTest.java
  27  * @run testng/othervm test.java.lang.invoke.MethodTypeTest
  28  */
  29 
  30 package test.java.lang.invoke;
  31 
  32 import java.io.IOException;
  33 import java.lang.invoke.MethodType;
  34 import java.lang.reflect.Method;
  35 
  36 import java.util.*;
  37 import org.testng.*;
  38 import static org.testng.AssertJUnit.*;
  39 import org.testng.annotations.*;
  40 
  41 /**
  42  *
  43  * @author jrose
  44  */
  45 public class MethodTypeTest {
  46 
  47     private Class<?> rtype;
  48     private Class<?>[] ptypes;
  49     private MethodType mt_viS, mt_OO, mt_OO2, mt_vv, mt_Vv, mt_Ov;
  50     private MethodType mt_iSI, mt_ISi, mt_ISI, mt_iSi;
  51     private MethodType mt_viO, mt_iO2, mt_OOi, mt_iOi;
  52     private MethodType mt_VIO, mt_IO2, mt_OOI, mt_IOI, mt_VIS;
  53     private MethodType mt_vOiSzA, mt_OO99;
  54     private MethodType[] GALLERY;
  55     private Method compareTo;
  56 
  57     @BeforeMethod
  58     public void setUp() throws Exception {
  59         rtype = void.class;
  60         ptypes = new Class<?>[] { int.class, String.class };
  61 
  62         mt_viS = MethodType.methodType(void.class, int.class, String.class);
  63         mt_OO = MethodType.methodType(Object.class, Object.class);
  64         mt_OO2 = MethodType.methodType(Object.class, Object.class, Object.class);
  65         mt_vv = MethodType.methodType(void.class);
  66         mt_Vv = MethodType.methodType(Void.class);
  67         mt_Ov = MethodType.methodType(Object.class);
  68         mt_iSI = MethodType.methodType(int.class, String.class, Integer.class);
  69         mt_ISi = MethodType.methodType(Integer.class, String.class, int.class);
  70         mt_ISI = MethodType.methodType(Integer.class, String.class, Integer.class);
  71         mt_iSi = MethodType.methodType(int.class, String.class, int.class);
  72 
  73         compareTo = String.class.getDeclaredMethod("compareTo", String.class);
  74 
  75         mt_viO = MethodType.methodType(void.class, int.class, Object.class);
  76         mt_iO2 = MethodType.methodType(int.class, Object.class, Object.class);
  77         mt_OOi = MethodType.methodType(Object.class, Object.class, int.class);
  78         mt_iOi = MethodType.methodType(int.class, Object.class, int.class);
  79 
  80         mt_VIO = MethodType.methodType(Void.class, Integer.class, Object.class);
  81         mt_IO2 = MethodType.methodType(Integer.class, Object.class, Object.class);
  82         mt_OOI = MethodType.methodType(Object.class, Object.class, Integer.class);
  83         mt_IOI = MethodType.methodType(Integer.class, Object.class, Integer.class);
  84         mt_VIS = MethodType.methodType(Void.class, Integer.class, String.class);
  85 
  86         mt_vOiSzA = MethodType.methodType(void.class, Object.class, int.class, String.class, boolean.class, Object[].class);
  87         mt_OO99 = MethodType.genericMethodType(99);
  88 
  89         GALLERY = new MethodType[] {
  90             mt_viS, mt_OO, mt_OO2, mt_vv, mt_Vv, mt_Ov,
  91             mt_iSI, mt_ISi, mt_ISI, mt_iSi,
  92             mt_viO, mt_iO2, mt_OOi, mt_iOi,
  93             mt_VIO, mt_IO2, mt_OOI, mt_IOI,
  94             mt_VIS, mt_vOiSzA, mt_OO99
  95         };
  96     }
  97 
  98     @AfterMethod
  99     public void tearDown() throws Exception {
 100     }
 101 
 102     /** Make sure the method types are all distinct. */
 103     @Test
 104     public void testDistinct() {
 105         List<MethodType> gallery2 = new ArrayList<>();
 106         for (MethodType mt : GALLERY) {
 107             assertFalse(mt.toString(), gallery2.contains(mt));
 108             gallery2.add(mt);
 109         }
 110         // check self-equality also:
 111         assertEquals(Arrays.asList(GALLERY), gallery2);
 112     }
 113 
 114     /**
 115      * Test of make method, of class MethodType.
 116      */
 117     @Test
 118     public void testMake_Class_ClassArr() {
 119         System.out.println("make (from type array)");
 120         MethodType result = MethodType.methodType(rtype, ptypes);
 121         assertSame(mt_viS, result);
 122     }
 123 
 124     /**
 125      * Test of make method, of class MethodType.
 126      */
 127     @Test
 128     public void testMake_Class_List() {
 129         System.out.println("make (from type list)");
 130         MethodType result = MethodType.methodType(rtype, Arrays.asList(ptypes));
 131         assertSame(mt_viS, result);
 132     }
 133 
 134     /**
 135      * Test of make method, of class MethodType.
 136      */
 137     @Test
 138     public void testMake_3args() {
 139         System.out.println("make (from type with varargs)");
 140         MethodType result = MethodType.methodType(rtype, ptypes[0], ptypes[1]);
 141         assertSame(mt_viS, result);
 142     }
 143 
 144     /**
 145      * Test of make method, of class MethodType.
 146      */
 147     @Test
 148     public void testMake_Class() {
 149         System.out.println("make (from single type)");
 150         Class<?> rt = Integer.class;
 151         MethodType expResult = MethodType.methodType(rt, new Class<?>[0]);
 152         MethodType result = MethodType.methodType(rt);
 153         assertSame(expResult, result);
 154     }
 155 
 156     @Test
 157     public void testMakeGeneric() {
 158         System.out.println("makeGeneric");
 159         int objectArgCount = 2;
 160         MethodType expResult = mt_OO2;
 161         MethodType result = MethodType.genericMethodType(objectArgCount);
 162         assertSame(expResult, result);
 163     }
 164 
 165     /**
 166      * Test of make method, of class MethodType.
 167      */
 168     @Test
 169     public void testMake_MethodType() {
 170         System.out.println("make (from rtype, MethodType)");
 171         MethodType expResult = mt_iO2;
 172         MethodType result = MethodType.methodType(int.class, mt_IO2);
 173         assertSame(expResult, result);
 174     }
 175 
 176     /**
 177      * Test of make method, of class MethodType.
 178      */
 179     @Test
 180     public void testMake_String_ClassLoader() {
 181         System.out.println("make (from bytecode signature)");
 182         ClassLoader loader = null;
 183         MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 184         String obj = "Ljava/lang/Object;";
 185         assertEquals(obj, concat(Object.class));
 186         String[] expResults = {
 187             "(ILjava/lang/String;)V",
 188             concat("(", obj, 2, ")", Object.class),
 189             "()V", "()"+obj,
 190             concat("(", String.class, Integer.class, ")I"),
 191             concat("(", String.class, "I)", Integer.class),
 192             concat("(", String.class, Integer.class, ")", Integer.class),
 193             concat("(", String.class, "I)I")
 194         };
 195         for (int i = 0; i < instances.length; i++) {
 196             MethodType instance = instances[i];
 197             String result = instance.toMethodDescriptorString();
 198             assertEquals("#"+i, expResults[i], result);
 199             MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
 200             assertSame("--#"+i, instance, parsed);
 201         }
 202     }
 203     private static String concat(Object... parts) {
 204         StringBuilder sb = new StringBuilder();
 205         Object prevPart = "";
 206         for (Object part : parts) {
 207             if (part instanceof Class) {
 208                 part = "L"+((Class)part).getName()+";";
 209             }
 210             if (part instanceof Integer) {
 211                 for (int n = (Integer) part; n > 1; n--)
 212                     sb.append(prevPart);
 213                 part = "";
 214             }
 215             sb.append(part);
 216             prevPart = part;
 217         }
 218         return sb.toString().replace('.', '/');
 219     }
 220 
 221     @Test
 222     public void testHasPrimitives() {
 223         System.out.println("hasPrimitives");
 224         MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 225         boolean[] expResults =   {true,   false,  true,  false, true,   true,   false,  true};
 226         for (int i = 0; i < instances.length; i++) {
 227             boolean result = instances[i].hasPrimitives();
 228             assertEquals("#"+i, expResults[i], result);
 229         }
 230     }
 231 
 232     @Test
 233     public void testHasWrappers() {
 234         System.out.println("hasWrappers");
 235         MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 236         boolean[] expResults =   {false,  false,  false, false, true,   true,   true,   false};
 237         for (int i = 0; i < instances.length; i++) {
 238             System.out.println("  hasWrappers "+instances[i]);
 239             boolean result = instances[i].hasWrappers();
 240             assertEquals("#"+i, expResults[i], result);
 241         }
 242     }
 243 
 244     @Test
 245     public void testErase() {
 246         System.out.println("erase");
 247         MethodType[] instances  = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 248         MethodType[] expResults = {mt_viO, mt_OO2, mt_vv, mt_Ov, mt_iO2, mt_OOi, mt_OO2, mt_iOi};
 249         for (int i = 0; i < instances.length; i++) {
 250             MethodType result = instances[i].erase();
 251             assertSame("#"+i, expResults[i], result);
 252         }
 253     }
 254 
 255     @Test
 256     public void testGeneric() {
 257         System.out.println("generic");
 258         MethodType[] instances =  {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 259         MethodType[] expResults = {mt_OO2, mt_OO2, mt_Ov, mt_Ov, mt_OO2, mt_OO2, mt_OO2, mt_OO2};
 260         for (int i = 0; i < instances.length; i++) {
 261             MethodType result = instances[i].generic();
 262             assertSame("#"+i, expResults[i], result);
 263         }
 264     }
 265 
 266     @Test
 267     public void testWrap() {
 268         System.out.println("wrap");
 269         MethodType[] instances =  {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 270         MethodType[] expResults = {mt_VIS, mt_OO2, mt_Vv, mt_Ov, mt_ISI, mt_ISI, mt_ISI, mt_ISI};
 271         for (int i = 0; i < instances.length; i++) {
 272             MethodType result = instances[i].wrap();
 273             assertSame("#"+i, expResults[i], result);
 274         }
 275     }
 276 
 277     @Test
 278     public void testUnwrap() {
 279         System.out.println("unwrap");
 280         MethodType[] instances =  {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 281         MethodType[] expResults = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSi, mt_iSi, mt_iSi, mt_iSi};
 282         for (int i = 0; i < instances.length; i++) {
 283             MethodType result = instances[i].unwrap();
 284             assertSame("#"+i, expResults[i], result);
 285         }
 286     }
 287 
 288     /**
 289      * Test of parameterType method, of class MethodType.
 290      */
 291     @Test
 292     public void testParameterType() {
 293         System.out.println("parameterType");
 294         for (int num = 0; num < ptypes.length; num++) {
 295             MethodType instance = mt_viS;
 296             Class<?> expResult = ptypes[num];
 297             Class<?> result = instance.parameterType(num);
 298             assertSame(expResult, result);
 299         }
 300     }
 301 
 302     /**
 303      * Test of parameterCount method, of class MethodType.
 304      */
 305     @Test
 306     public void testParameterCount() {
 307         System.out.println("parameterCount");
 308         MethodType instance = mt_viS;
 309         int expResult = 2;
 310         int result = instance.parameterCount();
 311         assertEquals(expResult, result);
 312     }
 313 
 314     /**
 315      * Test of returnType method, of class MethodType.
 316      */
 317     @Test
 318     public void testReturnType() {
 319         System.out.println("returnType");
 320         MethodType instance = mt_viS;
 321         Class<?> expResult = void.class;
 322         Class<?> result = instance.returnType();
 323         assertSame(expResult, result);
 324     }
 325 
 326     /**
 327      * Test of parameterList method, of class MethodType.
 328      */
 329     @Test
 330     public void testParameterList() {
 331         System.out.println("parameterList");
 332         MethodType instance = mt_viS;
 333         List<Class<?>> expResult = Arrays.asList(ptypes);
 334         List<Class<?>> result = instance.parameterList();
 335         assertEquals(expResult, result);
 336     }
 337 
 338     /**
 339      * Test of parameterArray method, of class MethodType.
 340      */
 341     @Test
 342     public void testParameterArray() {
 343         System.out.println("parameterArray");
 344         MethodType instance = mt_viS;
 345         Class<?>[] expResult = ptypes;
 346         Class<?>[] result = instance.parameterArray();
 347         assertEquals(Arrays.asList(expResult), Arrays.asList(result));
 348     }
 349 
 350     /**
 351      * Test of equals method, of class MethodType.
 352      */
 353     @Test
 354     public void testEquals_Object() {
 355         System.out.println("equals");
 356         Object x = null;
 357         MethodType instance = mt_viS;
 358         boolean expResult = false;
 359         boolean result = instance.equals(x);
 360         assertEquals(expResult, result);
 361     }
 362 
 363     /**
 364      * Test of equals method, of class MethodType.
 365      */
 366     @Test
 367     public void testEquals_MethodType() {
 368         System.out.println("equals");
 369         MethodType that = mt_viS;
 370         MethodType instance = mt_viS;
 371         boolean expResult = true;
 372         boolean result = instance.equals(that);
 373         assertEquals(expResult, result);
 374     }
 375 
 376     /**
 377      * Test of hashCode method, of class MethodType.
 378      */
 379     @Test
 380     public void testHashCode() {
 381         System.out.println("hashCode");
 382         MethodType instance = mt_viS;
 383         ArrayList<Class<?>> types = new ArrayList<>();
 384         types.add(instance.returnType());
 385         types.addAll(instance.parameterList());
 386         int expResult = types.hashCode();
 387         int result = instance.hashCode();
 388         assertEquals(expResult, result);
 389     }
 390 
 391     /**
 392      * Test of toString method, of class MethodType.
 393      */
 394     @Test
 395     public void testToString() {
 396         System.out.println("toString");
 397         MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
 398         //String expResult = "void[int, class java.lang.String]";
 399         String[] expResults = {
 400             "(int,String)void",
 401             "(Object,Object)Object",
 402             "()void",
 403             "()Object",
 404             "(String,Integer)int",
 405             "(String,int)Integer",
 406             "(String,Integer)Integer",
 407             "(String,int)int"
 408         };
 409         for (int i = 0; i < instances.length; i++) {
 410             MethodType instance = instances[i];
 411             String result = instance.toString();
 412             System.out.println("#"+i+":"+result);
 413             assertEquals("#"+i, expResults[i], result);
 414         }
 415     }
 416 
 417     private static byte[] writeSerial(Object x) throws java.io.IOException {
 418         try (java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
 419              java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(bout)
 420              ) {
 421             out.writeObject(x);
 422             out.flush();
 423             return bout.toByteArray();
 424         }
 425     }
 426     private static Object readSerial(byte[] wire) throws java.io.IOException, ClassNotFoundException {
 427         try (java.io.ByteArrayInputStream bin = new java.io.ByteArrayInputStream(wire);
 428              java.io.ObjectInputStream in = new java.io.ObjectInputStream(bin)) {
 429             return in.readObject();
 430         }
 431     }
 432     private static void testSerializedEquality(Object x) throws java.io.IOException, ClassNotFoundException {
 433         if (x instanceof Object[])
 434             x = Arrays.asList((Object[]) x);  // has proper equals method
 435         byte[] wire = writeSerial(x);
 436         Object y = readSerial(wire);
 437         assertEquals(x, y);
 438     }
 439 
 440     /** Test (de-)serialization. */
 441     @Test
 442     public void testSerialization() throws Throwable {
 443         System.out.println("serialization");
 444         for (MethodType mt : GALLERY) {
 445             testSerializedEquality(mt);
 446         }
 447         testSerializedEquality(GALLERY);
 448 
 449         // Make a list of mixed objects:
 450         List<Object> stuff = new ArrayList<>();
 451         Collections.addAll(stuff, GALLERY);  // copy #1
 452         Object[] triples = Arrays.copyOfRange(GALLERY, 0, GALLERY.length/2);
 453         Collections.addAll(stuff, triples);  // copy #3 (partial)
 454         for (MethodType mt : GALLERY) {
 455             Collections.addAll(stuff, mt.parameterArray());
 456         }
 457         Collections.shuffle(stuff, new Random(292));
 458         Collections.addAll(stuff, GALLERY);  // copy #2
 459         testSerializedEquality(stuff);
 460     }
 461 
 462     /** Test serialization formats. */
 463     @Test
 464     public void testPortableSerialFormat() throws Throwable {
 465         System.out.println("portable serial format");
 466         boolean generateData = false;
 467         //generateData = true;  // set this true to generate the following input data:
 468         Object[][] cases = {
 469             { mt_vv, new byte[] {  // ()void
 470                     (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x1b,
 471                     (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
 472                     (byte)0x67, (byte)0x2e, (byte)0x69, (byte)0x6e, (byte)0x76, (byte)0x6f, (byte)0x6b, (byte)0x65,
 473                     (byte)0x2e, (byte)0x4d, (byte)0x65, (byte)0x74, (byte)0x68, (byte)0x6f, (byte)0x64, (byte)0x54,
 474                     (byte)0x79, (byte)0x70, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 475                     (byte)0x00, (byte)0x01, (byte)0x24, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 476                     (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x6f, (byte)0x69, (byte)0x64,
 477                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 478                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x75, (byte)0x72, (byte)0x00,
 479                     (byte)0x12, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e,
 480                     (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x43, (byte)0x6c, (byte)0x61,
 481                     (byte)0x73, (byte)0x73, (byte)0x3b, (byte)0xab, (byte)0x16, (byte)0xd7, (byte)0xae, (byte)0xcb,
 482                     (byte)0xcd, (byte)0x5a, (byte)0x99, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 483                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78,
 484                 } },
 485             { mt_OO, new byte[] {  // (Object)Object
 486                     (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x1b,
 487                     (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
 488                     (byte)0x67, (byte)0x2e, (byte)0x69, (byte)0x6e, (byte)0x76, (byte)0x6f, (byte)0x6b, (byte)0x65,
 489                     (byte)0x2e, (byte)0x4d, (byte)0x65, (byte)0x74, (byte)0x68, (byte)0x6f, (byte)0x64, (byte)0x54,
 490                     (byte)0x79, (byte)0x70, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 491                     (byte)0x00, (byte)0x01, (byte)0x24, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 492                     (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
 493                     (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x4f, (byte)0x62,
 494                     (byte)0x6a, (byte)0x65, (byte)0x63, (byte)0x74, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 495                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78,
 496                     (byte)0x70, (byte)0x75, (byte)0x72, (byte)0x00, (byte)0x12, (byte)0x5b, (byte)0x4c, (byte)0x6a,
 497                     (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
 498                     (byte)0x2e, (byte)0x43, (byte)0x6c, (byte)0x61, (byte)0x73, (byte)0x73, (byte)0x3b, (byte)0xab,
 499                     (byte)0x16, (byte)0xd7, (byte)0xae, (byte)0xcb, (byte)0xcd, (byte)0x5a, (byte)0x99, (byte)0x02,
 500                     (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
 501                     (byte)0x71, (byte)0x00, (byte)0x7e, (byte)0x00, (byte)0x03, (byte)0x78,
 502                 } },
 503             { mt_vOiSzA, new byte[] {  // (Object,int,String,boolean,Object[])void
 504                     (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x1b,
 505                     (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
 506                     (byte)0x67, (byte)0x2e, (byte)0x69, (byte)0x6e, (byte)0x76, (byte)0x6f, (byte)0x6b, (byte)0x65,
 507                     (byte)0x2e, (byte)0x4d, (byte)0x65, (byte)0x74, (byte)0x68, (byte)0x6f, (byte)0x64, (byte)0x54,
 508                     (byte)0x79, (byte)0x70, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 509                     (byte)0x00, (byte)0x01, (byte)0x24, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 510                     (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x6f, (byte)0x69, (byte)0x64,
 511                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 512                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x75, (byte)0x72, (byte)0x00,
 513                     (byte)0x12, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e,
 514                     (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x43, (byte)0x6c, (byte)0x61,
 515                     (byte)0x73, (byte)0x73, (byte)0x3b, (byte)0xab, (byte)0x16, (byte)0xd7, (byte)0xae, (byte)0xcb,
 516                     (byte)0xcd, (byte)0x5a, (byte)0x99, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 517                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x10,
 518                     (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
 519                     (byte)0x67, (byte)0x2e, (byte)0x4f, (byte)0x62, (byte)0x6a, (byte)0x65, (byte)0x63, (byte)0x74,
 520                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 521                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00,
 522                     (byte)0x03, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 523                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78,
 524                     (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76,
 525                     (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x53,
 526                     (byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67, (byte)0xa0, (byte)0xf0, (byte)0xa4,
 527                     (byte)0x38, (byte)0x7a, (byte)0x3b, (byte)0xb3, (byte)0x42, (byte)0x02, (byte)0x00, (byte)0x00,
 528                     (byte)0x78, (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x07, (byte)0x62, (byte)0x6f,
 529                     (byte)0x6f, (byte)0x6c, (byte)0x65, (byte)0x61, (byte)0x6e, (byte)0x00, (byte)0x00, (byte)0x00,
 530                     (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
 531                     (byte)0x78, (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x13, (byte)0x5b, (byte)0x4c,
 532                     (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
 533                     (byte)0x67, (byte)0x2e, (byte)0x4f, (byte)0x62, (byte)0x6a, (byte)0x65, (byte)0x63, (byte)0x74,
 534                     (byte)0x3b, (byte)0x90, (byte)0xce, (byte)0x58, (byte)0x9f, (byte)0x10, (byte)0x73, (byte)0x29,
 535                     (byte)0x6c, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x78,
 536                 } },
 537         };
 538         for (Object[] c : cases) {
 539             MethodType mt = (MethodType) c[0];
 540             System.out.println("deserialize "+mt);
 541             byte[] wire = (byte[]) c[1];
 542             if (generateData) {
 543                 System.out.println("<generateData>");
 544                 wire = writeSerial(mt);
 545                 final String INDENT = "                ";
 546                 System.out.print("{  // "+mt);
 547                 for (int i = 0; i < wire.length; i++) {
 548                     if (i % 8 == 0) { System.out.println(); System.out.print(INDENT+"   "); }
 549                     String hex = Integer.toHexString(wire[i] & 0xFF);
 550                     if (hex.length() == 1)  hex = "0"+hex;
 551                     System.out.print(" (byte)0x"+hex+",");
 552                 }
 553                 System.out.println();
 554                 System.out.println(INDENT+"}");
 555                 System.out.println("</generateData>");
 556                 System.out.flush();
 557             }
 558             Object decode;
 559             try {
 560                 decode = readSerial(wire);
 561             } catch (IOException | ClassNotFoundException ex) {
 562                 decode = ex;  // oops!
 563             }
 564             assertEquals(mt, decode);
 565         }
 566     }
 567 }