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