ObjectOutputStreamTest.java revision 5d709784bbf5001012d7f25172927d46f6c1abe1
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.Externalizable;
23import java.io.FileInputStream;
24import java.io.FileOutputStream;
25import java.io.IOException;
26import java.io.NotActiveException;
27import java.io.NotSerializableException;
28import java.io.ObjectInput;
29import java.io.ObjectInputStream;
30import java.io.ObjectOutput;
31import java.io.ObjectOutputStream;
32import java.io.ObjectStreamClass;
33import java.io.ObjectStreamException;
34import java.io.ObjectStreamField;
35import java.io.OutputStream;
36import java.io.Serializable;
37import java.io.SerializablePermission;
38import java.io.WriteAbortedException;
39import java.security.Permission;
40import java.util.Arrays;
41
42import tests.support.Support_ASimpleOutputStream;
43import tests.support.Support_IOTestSecurityManager;
44import tests.support.Support_OutputStream;
45import dalvik.annotation.TestLevel;
46import dalvik.annotation.TestTargetClass;
47import dalvik.annotation.TestTargetNew;
48import dalvik.annotation.TestTargets;
49
50@TestTargetClass(
51        value = ObjectOutputStream.class,
52        untestedMethods = {
53            @TestTargetNew(
54                    method = "annotateClass",
55                    args = {Class.class},
56                    level = TestLevel.NOT_NECESSARY,
57                    notes = "According to specification, the implementation " +
58                            "does nothing."
59            ),
60            @TestTargetNew(
61                    method = "annotateProxyClass",
62                    args = {Class.class},
63                    level = TestLevel.NOT_NECESSARY,
64                    notes = "According to specification, the implementation " +
65                            "does nothing."
66            )
67        }
68)
69public class ObjectOutputStreamTest extends junit.framework.TestCase implements
70        Serializable {
71
72    static final long serialVersionUID = 1L;
73
74    java.io.File f;
75
76    public class SerializableTestHelper implements Serializable {
77        public String aField1;
78
79        public String aField2;
80
81        SerializableTestHelper() {
82            aField1 = null;
83            aField2 = null;
84        }
85
86        SerializableTestHelper(String s, String t) {
87            aField1 = s;
88            aField2 = t;
89        }
90
91        private void readObject(ObjectInputStream ois) throws IOException {
92            // note aField2 is not read
93            try {
94                ObjectInputStream.GetField fields = ois.readFields();
95                aField1 = (String) fields.get("aField1", "Zap");
96            } catch (Exception e) {
97            }
98        }
99
100        private void writeObject(ObjectOutputStream oos) throws IOException {
101            // note aField2 is not written
102            ObjectOutputStream.PutField fields = oos.putFields();
103            fields.put("aField1", aField1);
104            oos.writeFields();
105        }
106
107        public String getText1() {
108            return aField1;
109        }
110
111        public void setText1(String s) {
112            aField1 = s;
113        }
114
115        public String getText2() {
116            return aField2;
117        }
118
119        public void setText2(String s) {
120            aField2 = s;
121        }
122    }
123
124    private static class SpecTestSuperClass implements Runnable, Serializable {
125        static final long serialVersionUID = 1L;
126        protected java.lang.String instVar;
127
128        public void run() {
129        }
130    }
131
132    private static class SpecTest extends SpecTestSuperClass implements
133            Cloneable, Serializable {
134        static final long serialVersionUID = 1L;
135
136        public java.lang.String instVar1;
137
138        public static java.lang.String staticVar1;
139
140        public static java.lang.String staticVar2;
141        {
142            instVar1 = "NonStaticInitialValue";
143        }
144        static {
145            staticVar1 = "StaticInitialValue";
146            staticVar1 = new String(staticVar1);
147        }
148
149        public Object method(Object objParam, Object objParam2) {
150            return new Object();
151        }
152
153        public boolean method(boolean bParam, Object objParam) {
154            return true;
155        }
156
157        public boolean method(boolean bParam, Object objParam, Object objParam2) {
158            return true;
159        }
160
161    }
162
163    private static class SpecTestSubclass extends SpecTest implements
164            Serializable {
165        static final long serialVersionUID = 1L;
166        public transient java.lang.String transientInstVar = "transientValue";
167    }
168
169    private static class ReadWriteObject implements java.io.Serializable {
170        static final long serialVersionUID = 1L;
171
172        public boolean calledWriteObject = false;
173
174        public boolean calledReadObject = false;
175
176        public ReadWriteObject() {
177            super();
178        }
179
180        private void readObject(java.io.ObjectInputStream in)
181                throws java.io.IOException, ClassNotFoundException {
182            calledReadObject = true;
183            in.readObject();
184        }
185
186        private void writeObject(java.io.ObjectOutputStream out)
187                throws java.io.IOException {
188            calledWriteObject = true;
189            out.writeObject(FOO);
190        }
191    }
192
193    private static class PublicReadWriteObject implements java.io.Serializable {
194        public boolean calledWriteObject = false;
195
196        public boolean calledReadObject = false;
197
198        public PublicReadWriteObject() {
199            super();
200        }
201
202        public void readObject(java.io.ObjectInputStream in)
203                throws java.io.IOException, ClassNotFoundException {
204            calledReadObject = true;
205            in.readObject();
206        }
207
208        public void writeObject(java.io.ObjectOutputStream out)
209                throws java.io.IOException {
210            calledWriteObject = true;
211            out.writeObject(FOO);
212        }
213    }
214
215    private static class FieldOrder implements Serializable {
216        String aaa1NonPrimitive = "aaa1";
217
218        int bbb1PrimitiveInt = 5;
219
220        boolean aaa2PrimitiveBoolean = true;
221
222        String bbb2NonPrimitive = "bbb2";
223    }
224
225    private static class JustReadObject implements java.io.Serializable {
226        public boolean calledReadObject = false;
227
228        public JustReadObject() {
229            super();
230        }
231
232        private void readObject(java.io.ObjectInputStream in)
233                throws java.io.IOException, ClassNotFoundException {
234            calledReadObject = true;
235            in.defaultReadObject();
236        }
237    }
238
239    private static class JustWriteObject implements java.io.Serializable {
240        static final long serialVersionUID = 1L;
241        public boolean calledWriteObject = false;
242
243        public JustWriteObject() {
244            super();
245        }
246
247        private void writeObject(java.io.ObjectOutputStream out)
248                throws java.io.IOException, ClassNotFoundException {
249            calledWriteObject = true;
250            out.defaultWriteObject();
251        }
252    }
253
254    private static class ClassBasedReplacementWhenDumping implements
255            java.io.Serializable {
256        public boolean calledReplacement = false;
257
258        public ClassBasedReplacementWhenDumping() {
259            super();
260        }
261
262        private Object writeReplace() {
263            calledReplacement = true;
264            return FOO; // Replacement is a String
265        }
266    }
267
268    private static class MultipleClassBasedReplacementWhenDumping implements
269            java.io.Serializable {
270        private static class C1 implements java.io.Serializable {
271            private Object writeReplace() {
272                return new C2();
273            }
274        }
275
276        private static class C2 implements java.io.Serializable {
277            private Object writeReplace() {
278                return new C3();
279            }
280        }
281
282        private static class C3 implements java.io.Serializable {
283            private Object writeReplace() {
284                return FOO;
285            }
286        }
287
288        public MultipleClassBasedReplacementWhenDumping() {
289            super();
290        }
291
292        private Object writeReplace() {
293            return new C1();
294        }
295    }
296
297    private static class ClassBasedReplacementWhenLoading implements
298            java.io.Serializable {
299        public ClassBasedReplacementWhenLoading() {
300            super();
301        }
302
303        private Object readResolve() {
304            return FOO; // Replacement is a String
305        }
306    }
307
308    private static class ClassBasedReplacementWhenLoadingViolatesFieldType
309            implements java.io.Serializable {
310        public ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
311
312        public ClassBasedReplacementWhenLoadingViolatesFieldType() {
313            super();
314        }
315    }
316
317    private static class MyExceptionWhenDumping implements java.io.Serializable {
318        private static class MyException extends java.io.IOException {
319        };
320
321        public boolean anInstanceVar = false;
322
323        public MyExceptionWhenDumping() {
324            super();
325        }
326
327        private void readObject(java.io.ObjectInputStream in)
328                throws java.io.IOException, ClassNotFoundException {
329            in.defaultReadObject();
330        }
331
332        private void writeObject(java.io.ObjectOutputStream out)
333                throws java.io.IOException, ClassNotFoundException {
334            throw new MyException();
335        }
336    }
337
338    private static class NonSerializableExceptionWhenDumping implements
339            java.io.Serializable {
340        public Object anInstanceVar = new Object();
341
342        public NonSerializableExceptionWhenDumping() {
343            super();
344        }
345    }
346
347    private static class MyUnserializableExceptionWhenDumping implements
348            java.io.Serializable {
349        private static class MyException extends java.io.IOException {
350            private Object notSerializable = new Object();
351        };
352
353        public boolean anInstanceVar = false;
354
355        public MyUnserializableExceptionWhenDumping() {
356            super();
357        }
358
359        private void readObject(java.io.ObjectInputStream in)
360                throws java.io.IOException, ClassNotFoundException {
361            in.defaultReadObject();
362        }
363
364        private void writeObject(java.io.ObjectOutputStream out)
365                throws java.io.IOException, ClassNotFoundException {
366            throw new MyException();
367        }
368    }
369
370    private static class WithUnmatchingSerialPersistentFields implements
371            java.io.Serializable {
372        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
373                "value", String.class) };
374
375        public int anInstanceVar = 5;
376
377        public WithUnmatchingSerialPersistentFields() {
378            super();
379        }
380    }
381
382    private static class WithMatchingSerialPersistentFields implements
383            java.io.Serializable {
384        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
385                "anInstanceVar", String.class) };
386
387        public String anInstanceVar = FOO + FOO;
388
389        public WithMatchingSerialPersistentFields() {
390            super();
391        }
392    }
393
394    private static class SerialPersistentFields implements java.io.Serializable {
395        private static final String SIMULATED_FIELD_NAME = "text";
396
397        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
398                SIMULATED_FIELD_NAME, String.class) };
399
400        public int anInstanceVar = 5;
401
402        public SerialPersistentFields() {
403            super();
404        }
405
406        private void readObject(java.io.ObjectInputStream in)
407                throws java.io.IOException, ClassNotFoundException {
408            ObjectInputStream.GetField fields = in.readFields();
409            anInstanceVar = Integer.parseInt((String) fields.get(
410                    SIMULATED_FIELD_NAME, "-5"));
411        }
412
413        private void writeObject(java.io.ObjectOutputStream out)
414                throws java.io.IOException, ClassNotFoundException {
415            ObjectOutputStream.PutField fields = out.putFields();
416            fields.put(SIMULATED_FIELD_NAME, Integer.toString(anInstanceVar));
417            out.writeFields();
418        }
419    }
420
421    private static class WriteFieldsWithoutFetchingPutFields implements
422            java.io.Serializable {
423        private static final String SIMULATED_FIELD_NAME = "text";
424
425        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
426                SIMULATED_FIELD_NAME, String.class) };
427
428        public int anInstanceVar = 5;
429
430        public WriteFieldsWithoutFetchingPutFields() {
431            super();
432        }
433
434        private void readObject(java.io.ObjectInputStream in)
435                throws java.io.IOException, ClassNotFoundException {
436            in.readFields();
437        }
438
439        private void writeObject(java.io.ObjectOutputStream out)
440                throws java.io.IOException, ClassNotFoundException {
441            out.writeFields();
442        }
443    }
444
445    private static class SerialPersistentFieldsWithoutField implements
446            java.io.Serializable {
447        public int anInstanceVar = 5;
448
449        public SerialPersistentFieldsWithoutField() {
450            super();
451        }
452
453        private void readObject(java.io.ObjectInputStream in)
454                throws java.io.IOException, ClassNotFoundException {
455            in.readFields();
456        }
457
458        private void writeObject(java.io.ObjectOutputStream out)
459                throws java.io.IOException, ClassNotFoundException {
460            out.putFields();
461            out.writeFields();
462        }
463    }
464
465    private static class NotSerializable {
466        private int foo;
467
468        public NotSerializable() {
469        }
470
471        protected Object writeReplace() throws ObjectStreamException {
472            return new Integer(42);
473        }
474    }
475
476    private static class WriteReplaceObject implements Serializable {
477        private Object replaceObject;
478
479        private static enum Color {
480            red, blue, green
481        };
482
483        public WriteReplaceObject(Object o) {
484            replaceObject = o;
485        }
486
487        protected Object writeReplace() throws ObjectStreamException {
488            return replaceObject;
489        }
490    }
491
492    private static class ExternalizableWithReplace implements Externalizable {
493        private int foo;
494
495        public ExternalizableWithReplace() {
496        }
497
498        protected Object writeReplace() throws ObjectStreamException {
499            return new Integer(42);
500        }
501
502        public void writeExternal(ObjectOutput out) {
503        }
504
505        public void readExternal(ObjectInput in) {
506        }
507    }
508
509    private static class ObjectOutputStreamWithReplace extends ObjectOutputStream {
510        public ObjectOutputStreamWithReplace(OutputStream out) throws IOException {
511            super(out);
512            enableReplaceObject(true);
513        }
514
515        protected Object replaceObject(Object obj) throws IOException {
516            if (obj instanceof NotSerializable) {
517                return new Long(10);
518            } else if (obj instanceof Integer) {
519                return new Long(((Integer) obj).longValue());
520            } else {
521                return obj;
522            }
523        }
524    }
525
526    private static class ObjectOutputStreamWithReplace2 extends
527            ObjectOutputStream {
528        public ObjectOutputStreamWithReplace2(OutputStream out)
529                throws IOException {
530            super(out);
531            enableReplaceObject(true);
532        }
533
534        protected Object replaceObject(Object obj) throws IOException {
535            return new Long(10);
536        }
537    }
538
539    private static class BasicObjectOutputStream extends ObjectOutputStream {
540        public boolean writeStreamHeaderCalled;
541
542        public BasicObjectOutputStream() throws IOException, SecurityException {
543            super();
544            writeStreamHeaderCalled = false;
545        }
546
547        public BasicObjectOutputStream(OutputStream output) throws IOException {
548            super(output);
549        }
550
551        public void drain() throws IOException {
552            super.drain();
553        }
554
555        public boolean enableReplaceObject(boolean enable)
556                throws SecurityException {
557            return super.enableReplaceObject(enable);
558        }
559
560        public void writeObjectOverride(Object object) throws IOException {
561            super.writeObjectOverride(object);
562        }
563
564        public void writeStreamHeader() throws IOException {
565            super.writeStreamHeader();
566            writeStreamHeaderCalled = true;
567        }
568}
569
570    private static class NoFlushTestOutputStream extends ByteArrayOutputStream {
571        public boolean flushCalled;
572
573        public NoFlushTestOutputStream() {
574            super();
575            flushCalled = false;
576        }
577
578        public void flush() throws IOException {
579            super.flush();
580            flushCalled = true;
581        }
582    }
583
584    protected static final String MODE_XLOAD = "xload";
585
586    protected static final String MODE_XDUMP = "xdump";
587
588    static final String FOO = "foo";
589
590    static final String MSG_WITE_FAILED = "Failed to write: ";
591
592    private static final boolean DEBUG = false;
593
594    protected static boolean xload = false;
595
596    protected static boolean xdump = false;
597
598    protected static String xFileName = null;
599
600    protected ObjectInputStream ois;
601
602    protected ObjectOutputStream oos;
603
604    protected ObjectOutputStream oos_ioe;
605
606    protected Support_OutputStream sos;
607
608    protected ByteArrayOutputStream bao;
609
610    static final int INIT_INT_VALUE = 7;
611
612    static final String INIT_STR_VALUE = "a string that is blortz";
613
614    /**
615     * @tests java.io.ObjectInputStream#ObjectOutputStream()
616     */
617    @TestTargetNew(
618        level = TestLevel.COMPLETE,
619        notes = "Verifies the protected ObjectOutputStream() constructor.",
620        method = "ObjectOutputStream",
621        args = {}
622    )
623    public void test_Constructor() throws IOException {
624        SecurityManager sm = System.getSecurityManager();
625        System.setSecurityManager(new Support_IOTestSecurityManager());
626
627        try {
628            oos = new BasicObjectOutputStream();
629            fail("SecurityException expected.");
630        } catch (SecurityException e) {
631            // expected
632        } finally {
633            System.setSecurityManager(sm);
634        }
635    }
636
637    /**
638     * @tests java.io.ObjectOutputStream#ObjectOutputStream(java.io.OutputStream)
639     */
640    @TestTargetNew(
641        level = TestLevel.PARTIAL_COMPLETE,
642        notes = "Checks valid construction, NullPointerException and IOException.",
643        method = "ObjectOutputStream",
644        args = {java.io.OutputStream.class}
645    )
646    public void test_ConstructorLjava_io_OutputStream() throws IOException {
647        oos.close();
648        oos = new ObjectOutputStream(new ByteArrayOutputStream());
649        oos.close();
650
651        try {
652            oos = new ObjectOutputStream(null);
653            fail("Test 1: NullPointerException expected.");
654        } catch (NullPointerException e) {
655            // Expected.
656        }
657
658        Support_ASimpleOutputStream sos = new Support_ASimpleOutputStream(true);
659        try {
660            oos = new ObjectOutputStream(sos);
661            fail("Test 2: IOException expected.");
662        } catch (IOException e) {
663            // Expected.
664        }
665    }
666
667    /**
668     * @tests java.io.ObjectOutputStream#ObjectOutputStream(java.io.OutputStream)
669     */
670    @TestTargetNew(
671        level = TestLevel.PARTIAL_COMPLETE,
672        notes = "Checks SecurityException.",
673        method = "ObjectOutputStream",
674        args = {java.io.OutputStream.class}
675    )
676    public void test_ConstructorLjava_io_OutputStream_subtest0() throws IOException {
677
678        // custom security manager
679        SecurityManager sm = new SecurityManager() {
680
681            final SerializablePermission forbidenPermission =
682                new SerializablePermission("enableSubclassImplementation");
683
684            public void checkPermission(Permission perm) {
685                if (forbidenPermission.equals(perm)) {
686                    throw new SecurityException();
687                }
688            }
689        };
690
691        SecurityManager oldSm = System.getSecurityManager();
692        System.setSecurityManager(sm);
693        try {
694            ByteArrayOutputStream out = new ByteArrayOutputStream();
695            // should not cause SecurityException
696            new ObjectOutputStream(out);
697            // should not cause SecurityException
698            class SubTest1 extends ObjectOutputStream {
699                SubTest1(OutputStream out) throws IOException {
700                    super(out);
701                }
702            }
703
704            // should not cause SecurityException
705            new SubTest1(out);
706            class SubTest2 extends ObjectOutputStream {
707                SubTest2(OutputStream out) throws IOException {
708                    super(out);
709                }
710
711                public void writeUnshared(Object obj) throws IOException {
712                }
713            }
714
715            try {
716                new SubTest2(out);
717                fail("should throw SecurityException 1");
718            } catch (SecurityException e) {
719            }
720            class SubTest3 extends ObjectOutputStream {
721                SubTest3(OutputStream out) throws IOException {
722                    super(out);
723                }
724
725                public PutField putFields() throws IOException {
726                    return null;
727                }
728            }
729
730            try {
731                new SubTest3(out);
732                fail("should throw SecurityException 2");
733            } catch (SecurityException e) {
734            }
735        } finally {
736            System.setSecurityManager(oldSm);
737        }
738    }
739
740    /**
741     * @tests java.io.ObjectOutputStream#close()
742     */
743    @TestTargetNew(
744        level = TestLevel.COMPLETE,
745        method = "close",
746        args = {}
747    )
748    public void test_close() throws IOException {
749        int outputSize = bao.size();
750        // Writing of a primitive type should be buffered.
751        oos.writeInt(42);
752        assertTrue("Test 1: Primitive data unexpectedly written to the target stream.",
753                bao.size() == outputSize);
754        // Closing should write the buffered data to the target stream.
755        oos.close();
756        assertTrue("Test 2: Primitive data has not been written to the the target stream.",
757                bao.size() > outputSize);
758
759        try {
760            oos_ioe.close();
761            fail("Test 3: IOException expected.");
762        } catch (IOException e) {
763            // Expected.
764        }
765    }
766
767    /**
768     * @tests java.io.ObjectOutputStream#drain()
769     */
770    @TestTargetNew(
771        level = TestLevel.COMPLETE,
772        method = "drain",
773        args = {}
774    )
775    public void test_drain() throws IOException {
776        NoFlushTestOutputStream target = new NoFlushTestOutputStream();
777        BasicObjectOutputStream boos = new BasicObjectOutputStream(target);
778        int initialSize = target.size();
779        boolean written = false;
780
781        boos.writeBytes("Lorem ipsum");
782        // If there is no buffer then the bytes have already been written.
783        written = (target.size() > initialSize);
784
785        boos.drain();
786        assertTrue("Content has not been written to the target.",
787                written || (target.size() > initialSize));
788        assertFalse("flush() has been called on the target.",
789                target.flushCalled);
790    }
791
792    /**
793     * @tests java.io.ObjectOutputStream#defaultWriteObject()
794     */
795    @TestTargetNew(
796        level = TestLevel.SUFFICIENT,
797        notes = "IOException can not be tested because this method" +
798                "always throws a NotActiveException if called directly.",
799        method = "defaultWriteObject",
800        args = {}
801    )
802    public void test_defaultWriteObject() throws IOException {
803        try {
804            oos.defaultWriteObject();
805            fail("Test 1: NotActiveException expected.");
806        } catch (NotActiveException e) {
807            // Expected.
808        }
809    }
810
811    /**
812     * @tests java.io.ObjectOutputStream#enableReplaceObject(boolean)
813     */
814    @TestTargetNew(
815        level = TestLevel.COMPLETE,
816        method = "enableReplaceObject",
817        args = {boolean.class}
818    )
819    public void test_enableReplaceObjectB() throws IOException {
820        // Start testing without a SecurityManager.
821        BasicObjectOutputStream boos = new BasicObjectOutputStream();
822        assertFalse("Test 1: Object resolving must be disabled by default.",
823                boos.enableReplaceObject(true));
824
825        assertTrue("Test 2: enableReplaceObject did not return the previous value.",
826                boos.enableReplaceObject(false));
827
828        // Test 3: Check that a security exception is thrown.
829        SecurityManager sm = System.getSecurityManager();
830        System.setSecurityManager(new Support_IOTestSecurityManager());
831        try {
832            boos.enableReplaceObject(true);
833            fail("Test 3: SecurityException expected.");
834        } catch (SecurityException e) {
835            // expected
836        } finally {
837            System.setSecurityManager(sm);
838        }
839    }
840
841    /**
842     * @tests java.io.ObjectOutputStream#flush()
843     */
844    @TestTargetNew(
845        level = TestLevel.COMPLETE,
846        method = "flush",
847        args = {}
848    )
849    public void test_flush() throws Exception {
850        // Test for method void java.io.ObjectOutputStream.flush()
851        int size = bao.size();
852        oos.writeByte(127);
853        assertTrue("Test 1: Data already flushed.", bao.size() == size);
854        oos.flush();
855        assertTrue("Test 2: Failed to flush data.", bao.size() > size);
856
857        try {
858            oos_ioe.flush();
859            fail("Test 3: IOException expected.");
860        } catch (IOException e) {
861            // Expected.
862        }
863    }
864
865    /**
866     * @tests java.io.ObjectOutputStream#putFields()
867     */
868    @TestTargetNew(
869        level = TestLevel.SUFFICIENT,
870        notes = "IOException can not be tested because this method" +
871                "always throws a NotActiveException if called directly.",
872        method = "putFields",
873        args = {}
874    )
875    public void test_putFields() throws Exception {
876        /*
877         * "SerializableTestHelper" is an object created for these tests with
878         * two fields (Strings) and simple implementations of readObject and
879         * writeObject which simply read and write the first field but not the
880         * second one.
881         */
882        SerializableTestHelper sth;
883
884        try {
885            oos.putFields();
886            fail("Test 1: NotActiveException expected.");
887        } catch (NotActiveException e) {
888            // Expected.
889        }
890
891        oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
892        oos.flush();
893        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
894        sth = (SerializableTestHelper) (ois.readObject());
895        assertEquals("Test 2: readFields or writeFields failed; first field not set.",
896                "Gabba", sth.getText1());
897        assertNull("Test 3: readFields or writeFields failed; second field should not have been set.",
898                sth.getText2());
899    }
900
901    /**
902     * @tests java.io.ObjectOutputStream#reset()
903     */
904    @TestTargetNew(
905        level = TestLevel.COMPLETE,
906        method = "reset",
907        args = {}
908    )
909    public void test_reset() throws Exception {
910        String o = "HelloWorld";
911        sos = new Support_OutputStream(200);
912        oos.close();
913        oos = new ObjectOutputStream(sos);
914        oos.writeObject(o);
915        oos.writeObject(o);
916        oos.reset();
917        oos.writeObject(o);
918
919        sos.setThrowsException(true);
920        try {
921            oos.reset();
922            fail("Test 1: IOException expected.");
923        } catch (IOException e) {
924            // Expected.
925        }
926        sos.setThrowsException(false);
927
928        ois = new ObjectInputStream(new ByteArrayInputStream(sos.toByteArray()));
929        assertEquals("Test 2: Incorrect object read.", o, ois.readObject());
930        assertEquals("Test 3: Incorrect object read.", o, ois.readObject());
931        assertEquals("Test 4: Incorrect object read.", o, ois.readObject());
932        ois.close();
933    }
934
935    private static class ExternalTest implements Externalizable {
936        public String value;
937
938        public ExternalTest() {
939        }
940
941        public void setValue(String val) {
942            value = val;
943        }
944
945        public String getValue() {
946            return value;
947        }
948
949        public void writeExternal(ObjectOutput output) {
950            try {
951                output.writeUTF(value);
952            } catch (IOException e) {
953                e.printStackTrace();
954            }
955        }
956
957        public void readExternal(ObjectInput input) {
958            try {
959                value = input.readUTF();
960            } catch (IOException e) {
961                e.printStackTrace();
962            }
963        }
964    }
965
966    /**
967     * @tests java.io.ObjectOutputStream#useProtocolVersion(int)
968     */
969    @TestTargetNew(
970        level = TestLevel.SUFFICIENT,
971        notes = "IOException seems to be never thrown, therefore there is no such test.",
972        method = "useProtocolVersion",
973        args = {int.class}
974    )
975    public void test_useProtocolVersionI() throws Exception {
976
977        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
978        ExternalTest t1 = new ExternalTest();
979        t1.setValue("hello1");
980        oos.writeObject(t1);
981        oos.close();
982        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
983        ExternalTest t2 = (ExternalTest) ois.readObject();
984        ois.close();
985        assertTrue(
986                "Cannot read/write PROTOCAL_VERSION_1 Externalizable objects: "
987                        + t2.getValue(), t1.getValue().equals(t2.getValue()));
988    }
989
990    /**
991     * @tests java.io.ObjectOutputStream#write(byte[])
992     */
993    @TestTargetNew(
994            level = TestLevel.SUFFICIENT,
995            notes = "Tests against golden file missing. IOException can " +
996                    "not be checked since is never thrown (primitive data " +
997                    "is written into a self-expanding buffer).",
998            method = "write",
999            args = {byte[].class}
1000    )
1001    public void test_write$B() throws Exception {
1002        // Test for method void java.io.ObjectOutputStream.write(byte [])
1003        byte[] buf = new byte[10];
1004        oos.write("HelloWorld".getBytes());
1005        oos.close();
1006        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1007        ois.read(buf, 0, 10);
1008        ois.close();
1009        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
1010                10));
1011    }
1012
1013    /**
1014     * @tests java.io.ObjectOutputStream#write(byte[], int, int)
1015     */
1016    @TestTargetNew(
1017            level = TestLevel.SUFFICIENT,
1018            notes = "Tests against golden file missing. IOException can " +
1019                    "not be checked since is never thrown (primitive data " +
1020                    "is written into a self-expanding buffer).",
1021            method = "write",
1022            args = {byte[].class, int.class, int.class}
1023    )
1024    public void test_write$BII() throws Exception {
1025        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
1026        // int)
1027        byte[] buf = new byte[10];
1028        oos.write("HelloWorld".getBytes(), 0, 10);
1029        oos.close();
1030        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1031        ois.read(buf, 0, 10);
1032        ois.close();
1033        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
1034                10));
1035
1036        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1037        try {
1038            ois.read(buf, 0, -1);
1039            fail("IndexOutOfBoundsException not thrown");
1040        } catch (IndexOutOfBoundsException e) {
1041            // Expected
1042        }
1043        try {
1044            ois.read(buf, -1, 1);
1045            fail("IndexOutOfBoundsException not thrown");
1046        } catch (IndexOutOfBoundsException e) {
1047            // Expected
1048        }
1049        try {
1050            ois.read(buf, 10, 1);
1051            fail("IndexOutOfBoundsException not thrown");
1052        } catch (IndexOutOfBoundsException e) {
1053            // Expected
1054        }
1055        ois.close();
1056
1057    }
1058
1059    /**
1060     * @tests java.io.ObjectOutputStream#write(int)
1061     */
1062    @TestTargetNew(
1063            level = TestLevel.SUFFICIENT,
1064            notes = "Tests against golden file missing. IOException can " +
1065                    "not be checked since is never thrown (primitive data " +
1066                    "is written into a self-expanding buffer).",
1067            method = "write",
1068            args = {int.class}
1069    )
1070    public void test_writeI() throws Exception {
1071        // Test for method void java.io.ObjectOutputStream.write(int)
1072        oos.write('T');
1073        oos.close();
1074        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1075        assertEquals("Read incorrect byte", 'T', ois.read());
1076        ois.close();
1077    }
1078
1079    /**
1080     * @tests java.io.ObjectOutputStream#writeBytes(java.lang.String)
1081     */
1082    @TestTargetNew(
1083            level = TestLevel.SUFFICIENT,
1084            notes = "Tests against golden file missing. IOException can " +
1085                    "not be checked since is never thrown (primitive data " +
1086                    "is written into a self-expanding buffer).",
1087            method = "writeBytes",
1088            args = {java.lang.String.class}
1089    )
1090    public void test_writeBytesLjava_lang_String() throws Exception {
1091        // Test for method void
1092        // java.io.ObjectOutputStream.writeBytes(java.lang.String)
1093        byte[] buf = new byte[10];
1094        oos.writeBytes("HelloWorld");
1095        oos.close();
1096        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1097        ois.readFully(buf);
1098        ois.close();
1099        assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(
1100                buf, 0, 10));
1101    }
1102
1103    /**
1104     * @tests java.io.ObjectOutputStream#writeChars(java.lang.String)
1105     */
1106    @TestTargetNew(
1107            level = TestLevel.SUFFICIENT,
1108            notes = "Tests against golden file missing. IOException can " +
1109                    "not be checked since is never thrown (primitive data " +
1110                    "is written into a self-expanding buffer).",
1111            method = "writeChars",
1112            args = {java.lang.String.class}
1113    )
1114    public void test_writeCharsLjava_lang_String() throws Exception {
1115        // Test for method void
1116        // java.io.ObjectOutputStream.writeChars(java.lang.String)
1117        int avail = 0;
1118        char[] buf = new char[10];
1119        oos.writeChars("HelloWorld");
1120        oos.close();
1121        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1122        // Number of prim data bytes in stream / 2 to give char index
1123        avail = ois.available() / 2;
1124        for (int i = 0; i < avail; ++i)
1125            buf[i] = ois.readChar();
1126        ois.close();
1127        assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0,
1128                10));
1129    }
1130
1131    /**
1132     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
1133     */
1134    @TestTargetNew(
1135        level = TestLevel.COMPLETE,
1136        notes = "",
1137        method = "writeObject",
1138        args = {java.lang.Object.class}
1139    )
1140    public void test_writeObjectLjava_lang_Object() throws Exception {
1141        // Test for method void
1142        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
1143
1144        Object objToSave = null;
1145        Object objLoaded;
1146
1147        SerialPersistentFieldsWithoutField spf = new SerialPersistentFieldsWithoutField();
1148        final int CONST = -500;
1149        spf.anInstanceVar = CONST;
1150        objToSave = spf;
1151        if (DEBUG)
1152            System.out.println("Obj = " + objToSave);
1153        objLoaded = dumpAndReload(objToSave);
1154        assertTrue(
1155                "serialPersistentFields do not work properly in this implementation",
1156                ((SerialPersistentFieldsWithoutField) objLoaded).anInstanceVar != CONST);
1157
1158    }
1159
1160    /**
1161     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
1162     */
1163    @TestTargetNew(
1164        level = TestLevel.COMPLETE,
1165        notes = "",
1166        method = "writeObject",
1167        args = {java.lang.Object.class}
1168    )
1169    public void test_writeObject_NotSerializable() throws Exception {
1170        ObjectOutput out = null;
1171        try {
1172            out = new ObjectOutputStream(new ByteArrayOutputStream());
1173            out.writeObject(new NotSerializable());
1174            fail("Expected NotSerializableException");
1175        } catch (NotSerializableException e) {}
1176        out.writeObject(new ExternalizableWithReplace());
1177    }
1178
1179    /**
1180     * @tests java.io.ObjectOutputStream#writeObjectOverride(Object)
1181     */
1182    @TestTargetNew(
1183        level = TestLevel.COMPLETE,
1184        notes = "Verifies that writeObjectOverride() throws an IOException.",
1185        method = "writeObjectOverride",
1186        args = {java.lang.Object.class}
1187    )
1188    public void test_writeObjectOverrideLjava_lang_Object() throws IOException {
1189        BasicObjectOutputStream boos =
1190                new BasicObjectOutputStream(new ByteArrayOutputStream());
1191
1192        try {
1193            boos.writeObjectOverride(new Object());
1194            fail("IOException expected.");
1195        }
1196        catch (IOException e) {
1197        }
1198        finally {
1199            boos.close();
1200        }
1201    }
1202
1203    /**
1204     * @tests java.io.ObjectOutputStream#writeStreamHeader()
1205     */
1206    @TestTargetNew(
1207        level = TestLevel.COMPLETE,
1208        notes = "Verifies writeStreamHeader().",
1209        method = "writeStreamHeader",
1210        args = {}
1211    )
1212    public void test_writeStreamHeader() throws IOException {
1213        BasicObjectOutputStream boos;
1214        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1215        short s;
1216        byte[] buffer;
1217
1218        // Test 1: Make sure that writeStreamHeader() has been called.
1219        boos = new BasicObjectOutputStream(baos);
1220        try {
1221            assertTrue("Test 1: writeStreamHeader() has not been called.",
1222                         boos.writeStreamHeaderCalled);
1223
1224            // Test 2: Check that at least four bytes have been written.
1225            buffer = baos.toByteArray();
1226            assertTrue("Test 2: At least four bytes should have been written",
1227                        buffer.length >= 4);
1228
1229            // Test 3: Check the magic number.
1230            s = buffer[0];
1231            s <<= 8;
1232            s += ((short) buffer[1] & 0x00ff);
1233            assertEquals("Test 3: Invalid magic number written.",
1234                        java.io.ObjectStreamConstants.STREAM_MAGIC, s);
1235
1236            // Test 4: Check the stream version number.
1237            s = buffer[2];
1238            s <<= 8;
1239            s += ((short) buffer[3] & 0x00ff);
1240            assertEquals("Invalid stream version number written.",
1241                        java.io.ObjectStreamConstants.STREAM_VERSION, s);
1242        }
1243        finally {
1244            boos.close();
1245        }
1246    }
1247
1248    /**
1249     * @tests java.io.ObjectOutputStream#writeUTF(java.lang.String)
1250     */
1251    @TestTargetNew(
1252        level = TestLevel.PARTIAL,
1253        notes = "IOException checking missed.",
1254        method = "writeUTF",
1255        args = {java.lang.String.class}
1256    )
1257    public void test_writeUTFLjava_lang_String() throws Exception {
1258        // Test for method void
1259        // java.io.ObjectOutputStream.writeUTF(java.lang.String)
1260        oos.writeUTF("HelloWorld");
1261        oos.close();
1262        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
1263        assertEquals("Wrote incorrect UTF value", "HelloWorld", ois.readUTF());
1264    }
1265
1266    /**
1267     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
1268     */
1269    @TestTargetNew(
1270        level = TestLevel.COMPLETE,
1271        notes = "",
1272        method = "writeObject",
1273        args = {java.lang.Object.class}
1274    )
1275    public void test_writeObject_Exception() throws ClassNotFoundException, IOException {
1276        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
1277        ObjectOutputStream oos = new ObjectOutputStream(baos);
1278
1279        try {
1280            oos.writeObject(new Object());
1281            fail("should throw ObjectStreamException");
1282        } catch (ObjectStreamException e) {
1283            // expected
1284        } finally {
1285            oos.close();
1286            baos.close();
1287        }
1288
1289        byte[] bytes = baos.toByteArray();
1290        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
1291                bytes));
1292        try {
1293            ois.readObject();
1294            fail("should throw WriteAbortedException");
1295        } catch (WriteAbortedException e) {
1296            // expected
1297        } finally {
1298            ois.close();
1299        }
1300    }
1301
1302    /**
1303     * Sets up the fixture, for example, open a network connection. This method
1304     * is called before a test is executed.
1305     */
1306    protected void setUp() throws Exception {
1307        super.setUp();
1308        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1309        oos_ioe = new ObjectOutputStream(sos = new Support_OutputStream());
1310        sos.setThrowsException(true);
1311    }
1312
1313    /**
1314     * Tears down the fixture, for example, close a network connection. This
1315     * method is called after a test is executed.
1316     */
1317    protected void tearDown() throws Exception {
1318        super.tearDown();
1319        if (oos != null) {
1320            try {
1321                oos.close();
1322            } catch (Exception e) {}
1323        }
1324        if (oos_ioe != null) {
1325            try {
1326                oos_ioe.close();
1327            } catch (Exception e) {}
1328        }
1329        if (f != null && f.exists()) {
1330            if (!f.delete()) {
1331                fail("Error cleaning up files during teardown");
1332            }
1333        }
1334    }
1335
1336    protected Object reload() throws IOException, ClassNotFoundException {
1337
1338        // Choose the load stream
1339        if (xload || xdump) {
1340            // Load from pre-existing file
1341            ois = new ObjectInputStream(new FileInputStream(xFileName + "-"
1342                    + getName() + ".ser"));
1343        } else {
1344            // Just load from memory, we dumped to memory
1345            ois = new ObjectInputStream(new ByteArrayInputStream(bao
1346                    .toByteArray()));
1347        }
1348
1349        try {
1350            return ois.readObject();
1351        } finally {
1352            ois.close();
1353        }
1354    }
1355
1356    protected void dump(Object o) throws IOException, ClassNotFoundException {
1357
1358        // Choose the dump stream
1359        if (xdump) {
1360            oos = new ObjectOutputStream(new FileOutputStream(
1361                    f = new java.io.File(xFileName + "-" + getName() + ".ser")));
1362        } else {
1363            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1364        }
1365
1366        // Dump the object
1367        try {
1368            oos.writeObject(o);
1369        } finally {
1370            oos.close();
1371        }
1372    }
1373
1374    /**
1375     * @tests java.io.ObjectOutputStream#writeInt(int)
1376     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
1377     * @tests java.io.ObjectOutputStream#writeUTF(java.lang.String)
1378     */
1379    @TestTargets({
1380        @TestTargetNew(
1381            level = TestLevel.PARTIAL,
1382            notes = "",
1383            method = "writeInt",
1384            args = {int.class}
1385        ),
1386        @TestTargetNew(
1387            level = TestLevel.PARTIAL,
1388            notes = "",
1389            method = "writeObject",
1390            args = {java.lang.Object.class}
1391        ),
1392        @TestTargetNew(
1393            level = TestLevel.PARTIAL,
1394            notes = "",
1395            method = "writeUTF",
1396            args = {java.lang.String.class}
1397        )
1398    })
1399    public void testMixPrimitivesAndObjects() throws Exception {
1400        int i = 7;
1401        String s1 = "string 1";
1402        String s2 = "string 2";
1403        byte[] bytes = { 1, 2, 3 };
1404        try {
1405            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1406            oos.writeInt(i);
1407            oos.writeObject(s1);
1408            oos.writeUTF(s2);
1409            oos.writeObject(bytes);
1410            oos.close();
1411
1412            ois = new ObjectInputStream(new ByteArrayInputStream(bao
1413                    .toByteArray()));
1414
1415            int j = ois.readInt();
1416            assertTrue("Wrong int :" + j, i == j);
1417
1418            String l1 = (String) ois.readObject();
1419            assertTrue("Wrong obj String :" + l1, s1.equals(l1));
1420
1421            String l2 = ois.readUTF();
1422            assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
1423
1424            byte[] bytes2 = (byte[]) ois.readObject();
1425            assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
1426        } finally {
1427            try {
1428                if (oos != null)
1429                    oos.close();
1430                if (ois != null)
1431                    ois.close();
1432            } catch (IOException e) {}
1433        }
1434    }
1435
1436    /**
1437     * @tests java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
1438     */
1439    @TestTargetNew(
1440        level = TestLevel.COMPLETE,
1441        notes = "",
1442        method = "writeUnshared",
1443        args = {java.lang.Object.class}
1444    )
1445    public void test_writeUnshared() throws Exception {
1446        //Regression for HARMONY-187
1447        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1448        ObjectOutputStream oos = new ObjectOutputStream(baos);
1449
1450        Object o = "foobar";
1451        oos.writeObject(o);
1452        oos.writeUnshared(o);
1453        oos.writeObject(o);
1454        oos.flush();
1455
1456        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream (baos.toByteArray()));
1457
1458        Object[] oa = new Object[3];
1459        for (int i = 0; i < oa.length; i++) {
1460            oa[i] = ois.readObject();
1461        }
1462
1463        oos.close();
1464        ois.close();
1465
1466        // All three conditions must be met
1467        assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
1468        assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
1469        assertSame("oa[0] == oa[2]", oa[0], oa[2]);
1470    }
1471
1472    /**
1473     * @tests java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
1474     */
1475    @TestTargetNew(
1476        level = TestLevel.COMPLETE,
1477        notes = "",
1478        method = "writeUnshared",
1479        args = {java.lang.Object.class}
1480    )
1481    public void test_writeUnshared2() throws Exception {
1482        //Regression for HARMONY-187
1483        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1484        ObjectOutputStream oos = new ObjectOutputStream(baos);
1485
1486        Object o = new Object[1];
1487        oos.writeObject(o);
1488        oos.writeUnshared(o);
1489        oos.writeObject(o);
1490        oos.flush();
1491
1492        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream (baos.toByteArray()));
1493
1494        Object[] oa = new Object[3];
1495        for (int i = 0; i < oa.length; i++) {
1496            oa[i] = ois.readObject();
1497        }
1498
1499        oos.close();
1500        ois.close();
1501
1502        // All three conditions must be met
1503        assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
1504        assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
1505        assertSame("oa[0] == oa[2]", oa[0], oa[2]);
1506    }
1507
1508    protected Object dumpAndReload(Object o) throws IOException,
1509            ClassNotFoundException {
1510        dump(o);
1511        return reload();
1512    }
1513
1514    /**
1515     * @tests java.io.ObjectOutputStream#useProtocolVersion(int)
1516     */
1517    @TestTargetNew(
1518        level = TestLevel.PARTIAL,
1519        notes = "IOException & IllegalStateException checking missed.",
1520        method = "useProtocolVersion",
1521        args = {int.class}
1522    )
1523    public void test_useProtocolVersionI_2() throws Exception {
1524        ObjectOutputStream oos = new ObjectOutputStream(
1525                new ByteArrayOutputStream());
1526
1527        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
1528        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_2);
1529        try {
1530            oos.useProtocolVersion(3);
1531            fail("Protocol 3 should not be accepted");
1532        } catch (IllegalArgumentException e) {
1533            // expected
1534        } finally {
1535            oos.close();
1536        }
1537    }
1538
1539    /**
1540     * @tests java.io.ObjectOutputStream#replaceObject(java.lang.Object)
1541     */
1542    @TestTargetNew(
1543        level = TestLevel.COMPLETE,
1544        notes = "",
1545        method = "replaceObject",
1546        args = {java.lang.Object.class}
1547    )
1548    public void test_replaceObject() throws Exception {
1549        //Regression for HARMONY-1429
1550        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1551        ObjectOutputStreamWithReplace oos = new ObjectOutputStreamWithReplace(baos);
1552
1553        oos.writeObject(new NotSerializable());
1554        oos.flush();
1555        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream (baos.toByteArray()));
1556        Object obj = ois.readObject();
1557        oos.close();
1558        ois.close();
1559        assertTrue("replaceObject has not been called", (obj instanceof Long));
1560
1561        //Regression for HARMONY-2239
1562        Object replaceObject = int.class;
1563        baos = new ByteArrayOutputStream();
1564        ObjectOutputStreamWithReplace2 oos2 = new ObjectOutputStreamWithReplace2(
1565                baos);
1566        oos2.writeObject(new WriteReplaceObject(replaceObject));
1567        oos2.flush();
1568        ois = new ObjectInputStream(
1569                new ByteArrayInputStream(baos.toByteArray()));
1570        obj = ois.readObject();
1571        oos.close();
1572        ois.close();
1573        assertTrue("replaceObject has not been called", (obj instanceof Long));
1574
1575        replaceObject = ObjectStreamClass.lookup(Integer.class);
1576        baos = new ByteArrayOutputStream();
1577        oos2 = new ObjectOutputStreamWithReplace2(baos);
1578        oos2.writeObject(new WriteReplaceObject(replaceObject));
1579        oos2.flush();
1580        ois = new ObjectInputStream(
1581                new ByteArrayInputStream(baos.toByteArray()));
1582        obj = ois.readObject();
1583        oos.close();
1584        ois.close();
1585        assertTrue("replaceObject has not been called", (obj instanceof Long));
1586
1587        replaceObject = WriteReplaceObject.Color.red;
1588        baos = new ByteArrayOutputStream();
1589        oos2 = new ObjectOutputStreamWithReplace2(baos);
1590        oos2.writeObject(new WriteReplaceObject(replaceObject));
1591        oos2.flush();
1592        ois = new ObjectInputStream(
1593                new ByteArrayInputStream(baos.toByteArray()));
1594        obj = ois.readObject();
1595        oos.close();
1596        ois.close();
1597        assertTrue("replaceObject has not been called", (obj instanceof Long));
1598
1599        // Regression for HARMONY-3158
1600        Object obj1;
1601        Object obj2;
1602        Object obj3;
1603
1604        baos = new ByteArrayOutputStream();
1605        oos = new ObjectOutputStreamWithReplace(baos);
1606
1607        oos.writeObject(new Integer(99));
1608        oos.writeObject(Integer.class);
1609        oos.writeObject(ObjectStreamClass.lookup(Integer.class));
1610        oos.flush();
1611
1612        ois = new ObjectInputStream(new ByteArrayInputStream (baos.toByteArray()));
1613        obj1 = ois.readObject();
1614        obj2 = ois.readObject();
1615        obj3 = ois.readObject();
1616        oos.close();
1617        ois.close();
1618
1619        assertTrue("1st replaceObject worked incorrectly", obj1 instanceof Long);
1620        assertEquals("1st replaceObject worked incorrectly",
1621                99, ((Long) obj1).longValue());
1622        assertEquals("2nd replaceObject worked incorrectly", Integer.class, obj2);
1623        assertEquals("3rd replaceObject worked incorrectly",
1624                ObjectStreamClass.class, obj3.getClass());
1625    }
1626}
1627