SerializationStressTest.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package tests.api.java.io; 19 20import java.io.ByteArrayInputStream; 21import java.io.ByteArrayOutputStream; 22import java.io.DataInputStream; 23import java.io.FileInputStream; 24import java.io.FileOutputStream; 25import java.io.IOException; 26import java.io.InputStream; 27import java.io.InvalidObjectException; 28import java.io.NotActiveException; 29import java.io.ObjectInputStream; 30import java.io.ObjectOutputStream; 31import java.io.ObjectStreamClass; 32import java.io.ObjectStreamException; 33import java.io.Serializable; 34import java.io.StreamCorruptedException; 35import java.io.WriteAbortedException; 36import java.security.Permission; 37import java.security.PermissionCollection; 38import java.util.ArrayList; 39import java.util.Arrays; 40import java.util.Calendar; 41import java.util.GregorianCalendar; 42import java.util.HashMap; 43import java.util.HashSet; 44import java.util.Hashtable; 45import java.util.IdentityHashMap; 46import java.util.LinkedHashMap; 47import java.util.LinkedHashSet; 48import java.util.LinkedList; 49import java.util.List; 50import java.util.Map; 51import java.util.PropertyPermission; 52import java.util.Set; 53import java.util.SimpleTimeZone; 54import java.util.SortedMap; 55import java.util.SortedSet; 56import java.util.TimeZone; 57import java.util.TreeMap; 58import java.util.TreeSet; 59import java.util.Vector; 60 61/** 62 * Automated Test Suite for class java.io.ObjectOutputStream 63 * 64 */ 65public class SerializationStressTest extends junit.framework.TestCase implements 66 Serializable { 67 68 // protected static final String MODE_XLOAD = "xload"; 69 70 // protected static final String MODE_XDUMP = "xdump"; 71 72 static final String FOO = "foo"; 73 74 static final String MSG_TEST_FAILED = "Failed to write/read/assertion checking: "; 75 76 protected static final boolean DEBUG = false; 77 78 protected static boolean xload = false; 79 80 protected static boolean xdump = false; 81 82 protected static String xFileName = null; 83 84 protected transient int dumpCount = 0; 85 86 protected transient ObjectInputStream ois; 87 88 protected transient ObjectOutputStream oos; 89 90 protected transient ByteArrayOutputStream bao; 91 92 // ----------------------------------------------------------------------------------- 93 94 private static class ObjectInputStreamSubclass extends ObjectInputStream { 95 private Vector resolvedClasses = new Vector(); 96 97 public ObjectInputStreamSubclass(InputStream in) throws IOException, 98 StreamCorruptedException { 99 super(in); 100 } 101 102 public Class resolveClass(ObjectStreamClass osClass) 103 throws IOException, ClassNotFoundException { 104 Class result = super.resolveClass(osClass); 105 resolvedClasses.addElement(result); 106 return result; 107 } 108 109 public Class[] resolvedClasses() { 110 return (Class[]) resolvedClasses.toArray(new Class[resolvedClasses 111 .size()]); 112 } 113 } 114 115 static final Map TABLE = new Hashtable(); 116 117 static final Map MAP = new HashMap(); 118 119 static final SortedMap TREE = new TreeMap(); 120 121 static final LinkedHashMap LINKEDMAP = new LinkedHashMap(); 122 123 static final LinkedHashSet LINKEDSET = new LinkedHashSet(); 124 125 static final IdentityHashMap IDENTITYMAP = new IdentityHashMap(); 126 127 static final List ALIST = Arrays.asList(new String[] { "a", "list", "of", 128 "strings" }); 129 130 static final List LIST = new ArrayList(ALIST); 131 132 static final Set SET = new HashSet(Arrays.asList(new String[] { "one", 133 "two", "three" })); 134 135 static final Permission PERM = new PropertyPermission("file.encoding", 136 "write"); 137 138 static final PermissionCollection PERMCOL = PERM.newPermissionCollection(); 139 140 static final SortedSet SORTSET = new TreeSet(Arrays.asList(new String[] { 141 "one", "two", "three" })); 142 143 static final java.text.DateFormat DATEFORM = java.text.DateFormat 144 .getInstance(); 145 146 static final java.text.ChoiceFormat CHOICE = new java.text.ChoiceFormat( 147 "1#one|2#two|3#three"); 148 149 static final java.text.NumberFormat NUMBERFORM = java.text.NumberFormat 150 .getInstance(); 151 152 static final java.text.MessageFormat MESSAGE = new java.text.MessageFormat( 153 "the time: {0,time} and date {0,date}"); 154 155 static final LinkedList LINKEDLIST = new LinkedList(Arrays 156 .asList(new String[] { "a", "linked", "list", "of", "strings" })); 157 158 static final SimpleTimeZone TIME_ZONE = new SimpleTimeZone(3600000, 159 "S-TEST"); 160 161 static final Calendar CALENDAR = new GregorianCalendar(TIME_ZONE); 162 163 static { 164 TABLE.put("one", "1"); 165 TABLE.put("two", "2"); 166 TABLE.put("three", "3"); 167 MAP.put("one", "1"); 168 MAP.put("two", "2"); 169 MAP.put("three", "3"); 170 LINKEDMAP.put("one", "1"); 171 LINKEDMAP.put("two", "2"); 172 LINKEDMAP.put("three", "3"); 173 IDENTITYMAP.put("one", "1"); 174 IDENTITYMAP.put("two", "2"); 175 IDENTITYMAP.put("three", "3"); 176 LINKEDSET.add("one"); 177 LINKEDSET.add("two"); 178 LINKEDSET.add("three"); 179 TREE.put("one", "1"); 180 TREE.put("two", "2"); 181 TREE.put("three", "3"); 182 PERMCOL.add(PERM); 183 // To make sure they all use the same Calendar 184 CALENDAR.setTimeZone(new SimpleTimeZone(0, "GMT")); 185 CALENDAR.set(1999, Calendar.JUNE, 23, 15, 47, 13); 186 CALENDAR.set(Calendar.MILLISECOND, 553); 187 DATEFORM.setCalendar(CALENDAR); 188 java.text.DateFormatSymbols symbols = new java.text.DateFormatSymbols(); 189 symbols.setZoneStrings(new String[][] { { "a", "b", "c", "d" }, 190 { "e", "f", "g", "h" } }); 191 ((java.text.SimpleDateFormat) DATEFORM).setDateFormatSymbols(symbols); 192 DATEFORM.setNumberFormat(new java.text.DecimalFormat("#.#;'-'#.#")); 193 DATEFORM.setTimeZone(TimeZone.getTimeZone("EST")); 194 ((java.text.DecimalFormat) NUMBERFORM).applyPattern("#.#;'-'#.#"); 195 MESSAGE.setFormat(0, DATEFORM); 196 MESSAGE.setFormat(1, DATEFORM); 197 } 198 199 public SerializationStressTest() { 200 } 201 202 public SerializationStressTest(String name) { 203 super(name); 204 } 205 206 public String getDumpName() { 207 return getName() + dumpCount; 208 } 209 210 protected void dump(Object o) throws IOException, ClassNotFoundException { 211 if (dumpCount > 0) 212 setUp(); 213 // Dump the object 214 try { 215 oos.writeObject(o); 216 } finally { 217 oos.close(); 218 } 219 } 220 221 protected Object dumpAndReload(Object o) throws IOException, 222 ClassNotFoundException { 223 dump(o); 224 return reload(); 225 } 226 227 protected InputStream loadStream() throws IOException { 228 // Choose the load stream 229 if (xload || xdump) { 230 // Load from pre-existing file 231 return new FileInputStream(xFileName + "-" + getDumpName() + ".ser"); 232 } else { 233 // Just load from memory, we dumped to memory 234 return new ByteArrayInputStream(bao.toByteArray()); 235 } 236 } 237 238 protected Object reload() throws IOException, ClassNotFoundException { 239 ois = new ObjectInputStream(loadStream()); 240 dumpCount++; 241 try { 242 return ois.readObject(); 243 } finally { 244 ois.close(); 245 } 246 } 247 248 /** 249 * Sets up the fixture, for example, open a network connection. This method 250 * is called before a test is executed. 251 */ 252 protected void setUp() { 253 try { 254 if (xdump) { 255 oos = new ObjectOutputStream(new FileOutputStream(xFileName 256 + "-" + getDumpName() + ".ser")); 257 } else { 258 oos = new ObjectOutputStream(bao = new ByteArrayOutputStream()); 259 } 260 } catch (Exception e) { 261 fail("Exception thrown during setup : " + e.getMessage()); 262 } 263 } 264 265 /** 266 * Tears down the fixture, for example, close a network connection. This 267 * method is called after a test is executed. 268 */ 269 protected void tearDown() { 270 if (oos != null) { 271 try { 272 oos.close(); 273 } catch (Exception e) { 274 } 275 } 276 } 277 278 public void test_1_Constructor() { 279 // Test for method java.io.ObjectOutputStream(java.io.OutputStream) 280 281 try { 282 oos.close(); 283 oos = new ObjectOutputStream(new ByteArrayOutputStream()); 284 oos.close(); 285 } catch (Exception e) { 286 fail("Failed to create ObjectOutputStream : " + e.getMessage()); 287 } 288 } 289 290 public void test_2_close() { 291 // Test for method void java.io.ObjectOutputStream.close() 292 try { 293 oos.close(); 294 oos = new ObjectOutputStream(bao = new ByteArrayOutputStream()); 295 oos.close(); 296 oos.writeChar('T'); 297 oos.writeObject(FOO); 298 // Writing to a closed stream does not cause problems. This is 299 // the expected behavior 300 } catch (IOException e) { 301 fail("Operation on closed stream threw IOException : " 302 + e.getMessage()); 303 } 304 } 305 306 public void test_3_defaultWriteObject() { 307 // Test for method void java.io.ObjectOutputStream.defaultWriteObject() 308 309 try { 310 oos.defaultWriteObject(); 311 } catch (NotActiveException e) { 312 // Correct 313 return; 314 } catch (IOException e) { 315 } 316 fail( 317 "Failed to throw NotActiveException when invoked outside readObject"); 318 } 319 320 public void test_4_flush() { 321 // Test for method void java.io.ObjectOutputStream.flush() 322 try { 323 oos.close(); 324 oos = new ObjectOutputStream(bao = new ByteArrayOutputStream()); 325 int size = bao.size(); 326 oos.writeByte(127); 327 assertTrue("Data flushed already", bao.size() == size); 328 oos.flush(); 329 assertTrue("Failed to flush data", bao.size() > size); 330 // we don't know how many bytes are actually written for 1 byte, 331 // so we test > <before> 332 oos.close(); 333 oos = null; 334 } catch (IOException e) { 335 fail("IOException serializing data : " + e.getMessage()); 336 } 337 } 338 339 public void test_5_reset() { 340 // Test for method void java.io.ObjectOutputStream.reset() 341 try { 342 String o = "HelloWorld"; 343 oos.writeObject(o); 344 oos.writeObject(o); 345 oos.reset(); 346 oos.writeObject(o); 347 ois = new ObjectInputStream(loadStream()); 348 ois.close(); 349 } catch (IOException e) { 350 fail("IOException serializing data : " + e.getMessage()); 351 } 352 } 353 354 public void test_6_write() { 355 // Test for method void java.io.ObjectOutputStream.write(byte [], int, 356 // int) 357 try { 358 byte[] buf = new byte[255]; 359 byte[] output = new byte[255]; 360 for (int i = 0; i < output.length; i++) 361 output[i] = (byte) i; 362 oos.write(output, 0, output.length); 363 oos.close(); 364 ois = new ObjectInputStream(loadStream()); 365 ois.readFully(buf); 366 ois.close(); 367 for (int i = 0; i < output.length; i++) 368 if (buf[i] != output[i]) 369 fail("Read incorrect byte: " + i); 370 } catch (IOException e) { 371 fail("IOException serializing data : " + e.getMessage()); 372 } 373 } 374 375 public void test_6a_write() { 376 // Test for method void java.io.ObjectOutputStream.write(byte [], int, 377 // int) 378 try { 379 byte[] buf = new byte[256]; 380 byte[] output = new byte[256]; 381 for (int i = 0; i < output.length; i++) 382 output[i] = (byte) (i & 0xff); 383 oos.write(output, 0, output.length); 384 oos.close(); 385 ois = new ObjectInputStream(loadStream()); 386 ois.readFully(buf); 387 ois.close(); 388 for (int i = 0; i < output.length; i++) 389 if (buf[i] != output[i]) 390 fail("Read incorrect byte: " + i); 391 } catch (IOException e) { 392 fail("IOException serializing data : " + e.getMessage()); 393 } 394 } 395 396 public void test_7_write() { 397 // Test for method void java.io.ObjectOutputStream.write(int) 398 try { 399 byte[] buf = new byte[10]; 400 oos.write('T'); 401 oos.close(); 402 ois = new ObjectInputStream(loadStream()); 403 assertEquals("Read incorrect byte", 'T', ois.read()); 404 ois.close(); 405 } catch (IOException e) { 406 fail("IOException serializing data : " + e.getMessage()); 407 } 408 } 409 410 public void test_8_write() { 411 // Test for method void java.io.ObjectOutputStream.write(byte []) 412 try { 413 byte[] buf = new byte[10]; 414 oos.write("HelloWorld".getBytes()); 415 oos.close(); 416 ois = new ObjectInputStream(loadStream()); 417 ois.read(buf, 0, 10); 418 ois.close(); 419 assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 10) 420 ); 421 } catch (IOException e) { 422 fail("IOException serializing data : " + e.getMessage()); 423 } 424 } 425 426 public void test_9_writeBoolean() { 427 // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean) 428 try { 429 oos.writeBoolean(true); 430 oos.close(); 431 ois = new ObjectInputStream(loadStream()); 432 assertTrue("Wrote incorrect byte value", ois.readBoolean()); 433 } catch (IOException e) { 434 fail("IOException serializing data : " + e.getMessage()); 435 } 436 } 437 438 public void test_10_writeByte() { 439 // Test for method void java.io.ObjectOutputStream.writeByte(int) 440 try { 441 oos.writeByte(127); 442 oos.close(); 443 ois = new ObjectInputStream(loadStream()); 444 assertEquals("Wrote incorrect byte value", 127, ois.readByte()); 445 } catch (IOException e) { 446 fail("IOException serializing data : " + e.getMessage()); 447 } 448 } 449 450 public void test_11_writeBytes() { 451 // Test for method void 452 // java.io.ObjectOutputStream.writeBytes(java.lang.String) 453 try { 454 byte[] buf = new byte[10]; 455 oos.writeBytes("HelloWorld"); 456 oos.close(); 457 ois = new ObjectInputStream(loadStream()); 458 ois.readFully(buf); 459 ois.close(); 460 assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(buf, 0, 10) 461 ); 462 } catch (IOException e) { 463 fail("IOException serializing data : " + e.getMessage()); 464 } 465 } 466 467 public void test_12_writeChar() { 468 // Test for method void java.io.ObjectOutputStream.writeChar(int) 469 try { 470 oos.writeChar('T'); 471 oos.close(); 472 ois = new ObjectInputStream(loadStream()); 473 assertEquals("Wrote incorrect char value", 'T', ois.readChar()); 474 } catch (IOException e) { 475 fail("IOException serializing data : " + e.getMessage()); 476 } 477 } 478 479 public void test_13_writeChars() { 480 // Test for method void 481 // java.io.ObjectOutputStream.writeChars(java.lang.String) 482 try { 483 int avail = 0; 484 char[] buf = new char[10]; 485 oos.writeChars("HelloWorld"); 486 oos.close(); 487 ois = new ObjectInputStream(loadStream()); 488 // Number of prim data bytes in stream / 2 to give char index 489 avail = ois.available() / 2; 490 for (int i = 0; i < avail; ++i) 491 buf[i] = ois.readChar(); 492 ois.close(); 493 assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0, 10) 494 ); 495 } catch (IOException e) { 496 fail("IOException serializing data : " + e.getMessage()); 497 } 498 } 499 500 public void test_14_writeDouble() { 501 // Test for method void java.io.ObjectOutputStream.writeDouble(double) 502 try { 503 oos.writeDouble(Double.MAX_VALUE); 504 oos.close(); 505 ois = new ObjectInputStream(loadStream()); 506 assertTrue("Wrote incorrect double value", 507 ois.readDouble() == Double.MAX_VALUE); 508 } catch (IOException e) { 509 fail("IOException serializing data : " + e.getMessage()); 510 } 511 } 512 513 public void test_15_writeFloat() { 514 // Test for method void java.io.ObjectOutputStream.writeFloat(float) 515 try { 516 oos.writeFloat(Float.MAX_VALUE); 517 oos.close(); 518 ois = new ObjectInputStream(loadStream()); 519 assertTrue("Wrote incorrect double value", 520 ois.readFloat() == Float.MAX_VALUE); 521 ois.close(); 522 ois = null; 523 } catch (IOException e) { 524 fail("IOException serializing data : " + e.getMessage()); 525 } 526 } 527 528 public void test_16_writeInt() { 529 // Test for method void java.io.ObjectOutputStream.writeInt(int) 530 try { 531 oos.writeInt(Integer.MAX_VALUE); 532 oos.close(); 533 ois = new ObjectInputStream(loadStream()); 534 assertTrue("Wrote incorrect double value", 535 ois.readInt() == Integer.MAX_VALUE); 536 ois.close(); 537 } catch (IOException e) { 538 fail("IOException serializing data : " + e.getMessage()); 539 } 540 } 541 542 public void test_17_writeLong() { 543 // Test for method void java.io.ObjectOutputStream.writeLong(long) 544 try { 545 oos.writeLong(Long.MAX_VALUE); 546 oos.close(); 547 ois = new ObjectInputStream(loadStream()); 548 assertTrue("Wrote incorrect double value", 549 ois.readLong() == Long.MAX_VALUE); 550 } catch (IOException e) { 551 fail("IOException serializing data : " + e.getMessage()); 552 } 553 } 554 555 public void test_19_writeShort() { 556 // Test for method void java.io.ObjectOutputStream.writeShort(int) 557 try { 558 oos.writeShort(127); 559 oos.close(); 560 ois = new ObjectInputStream(loadStream()); 561 assertEquals("Wrote incorrect short value", 127, ois.readShort()); 562 } catch (IOException e) { 563 fail("IOException serializing data : " + e.getMessage()); 564 } 565 } 566 567 public void test_20_writeUTF() { 568 // Test for method void 569 // java.io.ObjectOutputStream.writeUTF(java.lang.String) 570 try { 571 oos.writeUTF("HelloWorld"); 572 oos.close(); 573 ois = new ObjectInputStream(loadStream()); 574 assertEquals("Wrote incorrect UTF value", 575 "HelloWorld", ois.readUTF()); 576 } catch (IOException e) { 577 fail("IOException serializing data : " + e.getMessage()); 578 } 579 } 580 581 public void test_25_available() { 582 try { 583 oos.writeObject(FOO); 584 oos.writeObject(FOO); 585 oos.flush(); 586 int available1 = 0; 587 int available2 = 0; 588 Object obj1 = null; 589 Object obj2 = null; 590 ObjectInputStream ois = new ObjectInputStream(loadStream()); 591 available1 = ois.available(); 592 obj1 = ois.readObject(); 593 available2 = ois.available(); 594 obj2 = ois.readObject(); 595 596 assertEquals("available returned incorrect value", 0, available1); 597 assertEquals("available returned incorrect value", 0, available2); 598 599 assertTrue("available caused incorrect reading", FOO.equals(obj1)); 600 assertTrue("available returned incorrect value", FOO.equals(obj2)); 601 602 } catch (IOException e) { 603 fail("IOException serializing object : " + e.getMessage()); 604 } catch (ClassNotFoundException e) { 605 fail("Unable to read Object type : " + e.toString()); 606 } catch (Error err) { 607 System.out.println("Error " + err); 608 throw err; 609 } 610 611 } 612 613 protected void t_MixPrimitivesAndObjects() throws IOException, 614 ClassNotFoundException { 615 int i = 7; 616 String s1 = "string 1"; 617 String s2 = "string 2"; 618 byte[] bytes = { 1, 2, 3 }; 619 620 oos.writeInt(i); 621 oos.writeObject(s1); 622 oos.writeUTF(s2); 623 oos.writeObject(bytes); 624 oos.close(); 625 try { 626 ois = new ObjectInputStream(loadStream()); 627 628 int j = ois.readInt(); 629 assertTrue("Wrong int :" + j, i == j); 630 631 String l1 = (String) ois.readObject(); 632 assertTrue("Wrong obj String :" + l1, s1.equals(l1)); 633 634 String l2 = (String) ois.readUTF(); 635 assertTrue("Wrong UTF String :" + l2, s2.equals(l2)); 636 637 byte[] bytes2 = (byte[]) ois.readObject(); 638 assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2)); 639 640 } finally { 641 ois.close(); 642 } 643 } 644 645 public void test_resolveClass() { 646 try { 647 oos.writeObject(new Object[] { Integer.class, new Integer(1) }); 648 oos.close(); 649 650 ois = new ObjectInputStreamSubclass(loadStream()); 651 ois.readObject(); 652 ois.close(); 653 } catch (IOException e1) { 654 fail("IOException : " + e1.getMessage()); 655 } catch (ClassNotFoundException e2) { 656 fail("ClassNotFoundException : " + e2.getMessage()); 657 } 658 659 Class[] resolvedClasses = ((ObjectInputStreamSubclass) ois) 660 .resolvedClasses(); 661 assertEquals("missing resolved", 3, resolvedClasses.length); 662 assertTrue("resolved class 1", resolvedClasses[0] == Object[].class); 663 assertTrue("resolved class 2", resolvedClasses[1] == Integer.class); 664 assertTrue("resolved class 3", resolvedClasses[2] == Number.class); 665 } 666 667 public void test_reset() { 668 try { 669 oos.reset(); 670 oos.writeObject("R"); 671 oos.reset(); 672 oos.writeByte(24); 673 oos.close(); 674 675 DataInputStream dis = new DataInputStream(loadStream()); 676 byte[] input = new byte[dis.available()]; 677 dis.readFully(input); 678 byte[] result = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0, 679 (byte) 5, (byte) 0x79, (byte) 0x74, (byte) 0, (byte) 1, 680 (byte) 'R', (byte) 0x79, (byte) 0x77, (byte) 1, (byte) 24 }; 681 assertTrue("incorrect output", Arrays.equals(input, result)); 682 683 ois = new ObjectInputStreamSubclass(loadStream()); 684 assertEquals("Wrong result from readObject()", "R", ois.readObject() 685 ); 686 assertEquals("Wrong result from readByte()", 24, ois.readByte()); 687 ois.close(); 688 } catch (IOException e1) { 689 fail("IOException : " + e1.getMessage()); 690 } catch (ClassNotFoundException e2) { 691 fail("ClassNotFoundException : " + e2.getMessage()); 692 } 693 } 694 695 public void test_serialVersionUID(Class clazz, long svUID) { 696 final String idWrong = "serialVersionUID is wrong for: "; 697 long reflectedSvUID = 0L; 698 try { 699 reflectedSvUID = clazz.getField("serialVersionUID").getLong(null); 700 } catch (Exception e) { 701 fail("Unable to determine serialVersionUID of " + clazz); 702 } 703 assertTrue(idWrong + clazz + ": " + reflectedSvUID + " does not equal " 704 + svUID, reflectedSvUID == svUID); 705 } 706 707 private static class ResolveObjectTest implements Serializable { 708 Object field1, field2; 709 } 710 711 private static class ResolveObjectInputStream extends ObjectInputStream { 712 ResolveObjectInputStream(InputStream in) 713 throws StreamCorruptedException, IOException { 714 super(in); 715 } 716 717 public void enableResolve() { 718 enableResolveObject(true); 719 } 720 721 public Object resolveObject(Object obj) { 722 if (obj instanceof Vector) // test_1_resolveObject() 723 return new Hashtable(); 724 else if ("abc".equals(obj)) // test_2_resolveObject() 725 return "ABC"; 726 else if (obj instanceof String) // test_3_resolveObject() 727 return String.valueOf(((String) obj).length()); 728 else if (obj instanceof int[]) // test_4_resolveObject() 729 return new Object[1]; 730 else if (obj instanceof Object[] && ((Object[]) obj).length == 2) // test_5_resolveObject() 731 return new char[1]; 732 return obj; 733 } 734 } 735 736 public void test_1_resolveObject() { 737 try { 738 ResolveObjectTest obj = new ResolveObjectTest(); 739 obj.field1 = new Vector(); 740 obj.field2 = obj.field1; 741 oos.writeObject(obj); 742 oos.close(); 743 ois = new ResolveObjectInputStream(loadStream()); 744 ((ResolveObjectInputStream) ois).enableResolve(); 745 ResolveObjectTest result = null; 746 try { 747 result = (ResolveObjectTest) ois.readObject(); 748 } catch (ClassNotFoundException e) { 749 fail(e.toString()); 750 } 751 assertTrue("Object not resolved", 752 result.field1 instanceof Hashtable); 753 assertTrue("Second reference not resolved", 754 result.field1 == result.field2); 755 } catch (IOException e) { 756 fail("IOException serializing data : " + e.getMessage()); 757 } 758 } 759 760 public void test_2_resolveObject() { 761 try { 762 ResolveObjectTest obj = new ResolveObjectTest(); 763 obj.field1 = "abc"; 764 obj.field2 = obj.field1; 765 oos.writeObject(obj); 766 oos.close(); 767 ois = new ResolveObjectInputStream(loadStream()); 768 ((ResolveObjectInputStream) ois).enableResolve(); 769 ResolveObjectTest result = null; 770 try { 771 result = (ResolveObjectTest) ois.readObject(); 772 } catch (ClassNotFoundException e) { 773 fail(e.toString()); 774 } 775 assertEquals("String not resolved", "ABC", result.field1); 776 assertTrue("Second reference not resolved", 777 result.field1 == result.field2); 778 } catch (IOException e) { 779 fail("IOException serializing data : " + e.getMessage()); 780 } 781 } 782 783 public void test_3_resolveObject() { 784 try { 785 ResolveObjectTest obj = new ResolveObjectTest(); 786 char[] lchars = new char[70000]; 787 obj.field1 = new String(lchars); 788 obj.field2 = obj.field1; 789 oos.writeObject(obj); 790 oos.close(); 791 ois = new ResolveObjectInputStream(loadStream()); 792 ((ResolveObjectInputStream) ois).enableResolve(); 793 ResolveObjectTest result = null; 794 try { 795 result = (ResolveObjectTest) ois.readObject(); 796 } catch (ClassNotFoundException e) { 797 fail(e.toString()); 798 } 799 assertTrue("Long String not resolved", "70000" 800 .equals(result.field1)); 801 assertTrue("Second reference not resolved", 802 result.field1 == result.field2); 803 } catch (IOException e) { 804 fail("IOException serializing data : " + e.getMessage()); 805 } 806 } 807 808 public void test_4_resolveObject() { 809 try { 810 ResolveObjectTest obj = new ResolveObjectTest(); 811 obj.field1 = new int[5]; 812 obj.field2 = obj.field1; 813 oos.writeObject(obj); 814 oos.close(); 815 ois = new ResolveObjectInputStream(loadStream()); 816 ((ResolveObjectInputStream) ois).enableResolve(); 817 ResolveObjectTest result = null; 818 try { 819 result = (ResolveObjectTest) ois.readObject(); 820 } catch (ClassNotFoundException e) { 821 fail(e.toString()); 822 } 823 Class cl = new Object[0].getClass(); 824 assertTrue("int[] not resolved", result.field1.getClass() == cl); 825 assertTrue("Second reference not resolved", 826 result.field1 == result.field2); 827 } catch (IOException e) { 828 fail("IOException serializing data : " + e.getMessage()); 829 } 830 } 831 832 public void test_5_resolveObject() { 833 try { 834 ResolveObjectTest obj = new ResolveObjectTest(); 835 obj.field1 = new Object[2]; 836 obj.field2 = obj.field1; 837 oos.writeObject(obj); 838 oos.close(); 839 ois = new ResolveObjectInputStream(loadStream()); 840 ((ResolveObjectInputStream) ois).enableResolve(); 841 ResolveObjectTest result = null; 842 try { 843 result = (ResolveObjectTest) ois.readObject(); 844 } catch (ClassNotFoundException e) { 845 fail(e.toString()); 846 } 847 Class cl = new char[0].getClass(); 848 assertTrue("int[] not resolved", result.field1.getClass() == cl); 849 assertTrue("Second reference not resolved", 850 result.field1 == result.field2); 851 } catch (IOException e) { 852 fail("IOException serializing data : " + e.getMessage()); 853 } 854 } 855 856 static class WriteReplaceTestA implements Serializable { 857 public Object writeReplace() throws ObjectStreamException { 858 return new ReadResolveTestB(); 859 } 860 } 861 862 static class WriteReplaceTestB extends WriteReplaceTestA { 863 } 864 865 static class WriteReplaceTestC extends WriteReplaceTestA { 866 public Object writeReplace() throws ObjectStreamException { 867 return new ReadResolveTestC(); 868 } 869 } 870 871 static class WriteReplaceTestD implements Serializable { 872 private Object writeReplace() throws ObjectStreamException { 873 return new ReadResolveTestD(); 874 } 875 } 876 877 static class WriteReplaceTestE extends WriteReplaceTestD { 878 } 879 880 static class WriteReplaceTestF implements Serializable { 881 int type, readType; 882 883 public WriteReplaceTestF(int type, int readType) { 884 this.type = type; 885 this.readType = readType; 886 } 887 888 public Object writeReplace() throws ObjectStreamException { 889 switch (type) { 890 case 0: 891 throw new InvalidObjectException("invalid"); 892 case 1: 893 throw new RuntimeException("runtime"); 894 case 2: 895 throw new Error("error"); 896 default: 897 return new ReadResolveTestE(readType); 898 } 899 } 900 } 901 902 static class ReadResolveTestA implements Serializable { 903 public Object readResolve() throws ObjectStreamException { 904 return new ReadResolveTestA(); 905 } 906 } 907 908 static class ReadResolveTestB extends ReadResolveTestA { 909 } 910 911 static class ReadResolveTestC implements Serializable { 912 private Object readResolve() throws ObjectStreamException { 913 return new ReadResolveTestB(); 914 } 915 } 916 917 static class ReadResolveTestD extends ReadResolveTestC { 918 } 919 920 static class ReadResolveTestE implements Serializable { 921 int type; 922 923 public ReadResolveTestE(int type) { 924 this.type = type; 925 } 926 927 public Object readResolve() throws ObjectStreamException { 928 switch (type) { 929 case 0: 930 throw new InvalidObjectException("invalid"); 931 case 1: 932 throw new RuntimeException("runtime"); 933 case 2: 934 throw new Error("error"); 935 case 3: 936 return this; 937 default: 938 return new ReadResolveTestF(); 939 } 940 } 941 } 942 943 static class ReadResolveTestF implements Serializable { 944 } 945 946 public void test_1_writeReplace() { 947 try { 948 Vector v = new Vector(); 949 v.addElement(new WriteReplaceTestA()); 950 v.addElement(new WriteReplaceTestB()); 951 v.addElement(new WriteReplaceTestB()); 952 v.addElement(new WriteReplaceTestC()); 953 v.addElement(new WriteReplaceTestD()); 954 v.addElement(new WriteReplaceTestE()); 955 oos.writeObject(v); 956 oos.close(); 957 ois = new ObjectInputStream(loadStream()); 958 Vector result = (Vector) ois.readObject(); 959 assertTrue("invalid 0 : " + result.elementAt(0), result 960 .elementAt(0).getClass() == ReadResolveTestA.class); 961 assertTrue("invalid 1 : " + result.elementAt(1), result 962 .elementAt(1).getClass() == ReadResolveTestA.class); 963 assertTrue("invalid 2 : " + result.elementAt(2), result 964 .elementAt(2).getClass() == ReadResolveTestA.class); 965 assertTrue("invalid 3 : " + result.elementAt(3), result 966 .elementAt(3).getClass() == ReadResolveTestB.class); 967 assertTrue("invalid 4 : " + result.elementAt(4), result 968 .elementAt(4).getClass() == ReadResolveTestD.class); 969 assertTrue("invalid 5 : " + result.elementAt(5), result 970 .elementAt(5).getClass() == WriteReplaceTestE.class); 971 } catch (IOException e) { 972 fail("IOException serializing data : " + e.getMessage()); 973 } catch (ClassNotFoundException e) { 974 fail("ClassNotFoundException serializing data : " + e.getMessage()); 975 } 976 } 977 978 public void test_2_writeReplace() { 979 try { 980 boolean exception = false; 981 try { 982 oos.writeObject(new WriteReplaceTestF(0, -1)); 983 } catch (ObjectStreamException e) { 984 exception = true; 985 } 986 assertTrue("Should throw ObjectStreamException", exception); 987 exception = false; 988 try { 989 oos.writeObject(new WriteReplaceTestF(1, -1)); 990 } catch (RuntimeException e) { 991 exception = true; 992 } 993 assertTrue("Should throw RuntimeException", exception); 994 exception = false; 995 try { 996 oos.writeObject(new WriteReplaceTestF(2, -1)); 997 } catch (Error e) { 998 exception = true; 999 } 1000 assertTrue("Should throw Error", exception); 1001 1002 oos.writeObject(new WriteReplaceTestF(3, 0)); 1003 oos.writeObject(new WriteReplaceTestF(3, 1)); 1004 oos.writeObject(new WriteReplaceTestF(3, 2)); 1005 WriteReplaceTestF test = new WriteReplaceTestF(3, 3); 1006 oos.writeObject(test); 1007 oos.writeObject(test); 1008 WriteReplaceTestF test2 = new WriteReplaceTestF(3, 4); 1009 oos.writeObject(test2); 1010 oos.writeObject(test2); 1011 oos.close(); 1012 ois = new ObjectInputStream(loadStream()); 1013 try { 1014 ois.readObject(); 1015 } catch (WriteAbortedException e) { 1016 } 1017 1018 exception = false; 1019 try { 1020 ois.readObject(); 1021 } catch (ObjectStreamException e) { 1022 exception = true; 1023 } 1024 assertTrue("Expected ObjectStreamException", exception); 1025 exception = false; 1026 try { 1027 ois.readObject(); 1028 } catch (RuntimeException e) { 1029 exception = true; 1030 } 1031 assertTrue("Expected RuntimeException", exception); 1032 exception = false; 1033 try { 1034 ois.readObject(); 1035 } catch (Error e) { 1036 exception = true; 1037 } 1038 assertTrue("Expected Error", exception); 1039 1040 Object readE1 = ois.readObject(); 1041 Object readE2 = ois.readObject(); 1042 assertTrue("Replaced objects should be identical", readE1 == readE2); 1043 Object readF1 = ois.readObject(); 1044 Object readF2 = ois.readObject(); 1045 assertTrue("Replaced resolved objects should be identical: " 1046 + readF1 + " " + readF2, readF1 == readF2); 1047 } catch (IOException e) { 1048 fail("IOException serializing data : " + e.getMessage()); 1049 } catch (ClassNotFoundException e) { 1050 fail("ClassNotFoundException serializing data : " + e.getMessage()); 1051 } 1052 } 1053} 1054