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