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.Externalizable;
23import java.io.File;
24import java.io.FileInputStream;
25import java.io.FileOutputStream;
26import java.io.IOException;
27import java.io.NotActiveException;
28import java.io.NotSerializableException;
29import java.io.ObjectInput;
30import java.io.ObjectInputStream;
31import java.io.ObjectOutput;
32import java.io.ObjectOutputStream;
33import java.io.ObjectStreamClass;
34import java.io.ObjectStreamConstants;
35import java.io.ObjectStreamException;
36import java.io.ObjectStreamField;
37import java.io.OutputStream;
38import java.io.Serializable;
39import java.io.SerializablePermission;
40import java.io.WriteAbortedException;
41import java.security.Permission;
42import java.util.Arrays;
43
44import junit.framework.TestCase;
45
46@SuppressWarnings( { "unused", "serial" })
47public class ObjectOutputStreamTest extends TestCase implements Serializable {
48
49    File f;
50
51    public class SerializableTestHelper implements Serializable {
52        public String aField1;
53
54        public String aField2;
55
56        SerializableTestHelper() {
57            aField1 = null;
58            aField2 = null;
59        }
60
61        SerializableTestHelper(String s, String t) {
62            aField1 = s;
63            aField2 = t;
64        }
65
66        private void readObject(ObjectInputStream ois) throws IOException {
67            // note aField2 is not read
68            try {
69                ObjectInputStream.GetField fields = ois.readFields();
70                aField1 = (String) fields.get("aField1", "Zap");
71            } catch (Exception e) {
72            }
73        }
74
75        private void writeObject(ObjectOutputStream oos) throws IOException {
76            // note aField2 is not written
77            ObjectOutputStream.PutField fields = oos.putFields();
78            fields.put("aField1", aField1);
79            oos.writeFields();
80        }
81
82        public String getText1() {
83            return aField1;
84        }
85
86        public void setText1(String s) {
87            aField1 = s;
88        }
89
90        public String getText2() {
91            return aField2;
92        }
93
94        public void setText2(String s) {
95            aField2 = s;
96        }
97    }
98
99    private static class SerializationTest implements java.io.Serializable {
100        int anInt = INIT_INT_VALUE;
101
102        public SerializationTest() {
103            super();
104        }
105    }
106
107    private static class SerializationTestSubclass1 extends SerializationTest
108            implements Serializable {
109        String aString = INIT_STR_VALUE;
110
111        public SerializationTestSubclass1() {
112            super();
113            // Just to change default superclass init value
114            anInt = INIT_INT_VALUE / 2;
115        }
116    }
117
118    private static class SpecTestSuperClass implements Runnable, Serializable {
119        protected java.lang.String instVar;
120
121        public void run() {
122        }
123    }
124
125    private static class SpecTest extends SpecTestSuperClass implements
126            Cloneable, Serializable {
127        public java.lang.String instVar1;
128
129        public static java.lang.String staticVar1;
130
131        public static java.lang.String staticVar2;
132        {
133            instVar1 = "NonStaticInitialValue";
134        }
135        static {
136            staticVar1 = "StaticInitialValue";
137            staticVar1 = new String(staticVar1);
138        }
139
140        public Object method(Object objParam, Object objParam2) {
141            return new Object();
142        }
143
144        public boolean method(boolean bParam, Object objParam) {
145            return true;
146        }
147
148        public boolean method(boolean bParam, Object objParam, Object objParam2) {
149            return true;
150        }
151
152    }
153
154    private static class SpecTestSubclass extends SpecTest implements
155            Serializable {
156        public transient java.lang.String transientInstVar = "transientValue";
157    }
158
159    private static class ReadWriteObject implements java.io.Serializable {
160        public boolean calledWriteObject = false;
161
162        public boolean calledReadObject = false;
163
164        public ReadWriteObject() {
165            super();
166        }
167
168        private void readObject(java.io.ObjectInputStream in)
169                throws java.io.IOException, ClassNotFoundException {
170            calledReadObject = true;
171            in.readObject();
172        }
173
174        private void writeObject(java.io.ObjectOutputStream out)
175                throws java.io.IOException {
176            calledWriteObject = true;
177            out.writeObject(FOO);
178        }
179    }
180
181    private static class PublicReadWriteObject implements java.io.Serializable {
182        public boolean calledWriteObject = false;
183
184        public boolean calledReadObject = false;
185
186        public PublicReadWriteObject() {
187            super();
188        }
189
190        public void readObject(java.io.ObjectInputStream in)
191                throws java.io.IOException, ClassNotFoundException {
192            calledReadObject = true;
193            in.readObject();
194        }
195
196        public void writeObject(java.io.ObjectOutputStream out)
197                throws java.io.IOException {
198            calledWriteObject = true;
199            out.writeObject(FOO);
200        }
201    }
202
203    private static class FieldOrder implements Serializable {
204        String aaa1NonPrimitive = "aaa1";
205
206        int bbb1PrimitiveInt = 5;
207
208        boolean aaa2PrimitiveBoolean = true;
209
210        String bbb2NonPrimitive = "bbb2";
211    }
212
213    private static class JustReadObject implements java.io.Serializable {
214        public boolean calledReadObject = false;
215
216        public JustReadObject() {
217            super();
218        }
219
220        private void readObject(java.io.ObjectInputStream in)
221                throws java.io.IOException, ClassNotFoundException {
222            calledReadObject = true;
223            in.defaultReadObject();
224        }
225    }
226
227    private static class JustWriteObject implements java.io.Serializable {
228        public boolean calledWriteObject = false;
229
230        public JustWriteObject() {
231            super();
232        }
233
234        private void writeObject(java.io.ObjectOutputStream out)
235                throws java.io.IOException, ClassNotFoundException {
236            calledWriteObject = true;
237            out.defaultWriteObject();
238        }
239    }
240
241    private static class ClassBasedReplacementWhenDumping implements
242            java.io.Serializable {
243        public boolean calledReplacement = false;
244
245        public ClassBasedReplacementWhenDumping() {
246            super();
247        }
248
249        private Object writeReplace() {
250            calledReplacement = true;
251            return FOO; // Replacement is a String
252        }
253    }
254
255    private static class MultipleClassBasedReplacementWhenDumping implements
256            java.io.Serializable {
257        private static class C1 implements java.io.Serializable {
258            private Object writeReplace() {
259                return new C2();
260            }
261        }
262
263        private static class C2 implements java.io.Serializable {
264            private Object writeReplace() {
265                return new C3();
266            }
267        }
268
269        private static class C3 implements java.io.Serializable {
270            private Object writeReplace() {
271                return FOO;
272            }
273        }
274
275        public MultipleClassBasedReplacementWhenDumping() {
276            super();
277        }
278
279        private Object writeReplace() {
280            return new C1();
281        }
282    }
283
284    private static class ClassBasedReplacementWhenLoading implements
285            java.io.Serializable {
286        public ClassBasedReplacementWhenLoading() {
287            super();
288        }
289
290        private Object readResolve() {
291            return FOO; // Replacement is a String
292        }
293    }
294
295    private static class ClassBasedReplacementWhenLoadingViolatesFieldType
296            implements java.io.Serializable {
297        public ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
298
299        public ClassBasedReplacementWhenLoadingViolatesFieldType() {
300            super();
301        }
302    }
303
304    private static class MyExceptionWhenDumping implements java.io.Serializable {
305        private static class MyException extends java.io.IOException {
306        };
307
308        public boolean anInstanceVar = false;
309
310        public MyExceptionWhenDumping() {
311            super();
312        }
313
314        private void readObject(java.io.ObjectInputStream in)
315                throws java.io.IOException, ClassNotFoundException {
316            in.defaultReadObject();
317        }
318
319        private void writeObject(java.io.ObjectOutputStream out)
320                throws java.io.IOException, ClassNotFoundException {
321            throw new MyException();
322        }
323    }
324
325    private static class NonSerializableExceptionWhenDumping implements
326            java.io.Serializable {
327        public Object anInstanceVar = new Object();
328
329        public NonSerializableExceptionWhenDumping() {
330            super();
331        }
332    }
333
334    private static class MyUnserializableExceptionWhenDumping implements
335            java.io.Serializable {
336        private static class MyException extends java.io.IOException {
337            private Object notSerializable = new Object();
338        };
339
340        public boolean anInstanceVar = false;
341
342        public MyUnserializableExceptionWhenDumping() {
343            super();
344        }
345
346        private void readObject(java.io.ObjectInputStream in)
347                throws java.io.IOException, ClassNotFoundException {
348            in.defaultReadObject();
349        }
350
351        private void writeObject(java.io.ObjectOutputStream out)
352                throws java.io.IOException, ClassNotFoundException {
353            throw new MyException();
354        }
355    }
356
357    private static class WithUnmatchingSerialPersistentFields implements
358            java.io.Serializable {
359        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
360                "value", String.class) };
361
362        public int anInstanceVar = 5;
363
364        public WithUnmatchingSerialPersistentFields() {
365            super();
366        }
367    }
368
369    private static class WithMatchingSerialPersistentFields implements
370            java.io.Serializable {
371        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
372                "anInstanceVar", String.class) };
373
374        public String anInstanceVar = FOO + FOO;
375
376        public WithMatchingSerialPersistentFields() {
377            super();
378        }
379    }
380
381    private static class SerialPersistentFields implements java.io.Serializable {
382        private static final String SIMULATED_FIELD_NAME = "text";
383
384        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
385                SIMULATED_FIELD_NAME, String.class) };
386
387        public int anInstanceVar = 5;
388
389        public SerialPersistentFields() {
390            super();
391        }
392
393        private void readObject(java.io.ObjectInputStream in)
394                throws java.io.IOException, ClassNotFoundException {
395            ObjectInputStream.GetField fields = in.readFields();
396            anInstanceVar = Integer.parseInt((String) fields.get(
397                    SIMULATED_FIELD_NAME, "-5"));
398        }
399
400        private void writeObject(java.io.ObjectOutputStream out)
401                throws java.io.IOException, ClassNotFoundException {
402            ObjectOutputStream.PutField fields = out.putFields();
403            fields.put(SIMULATED_FIELD_NAME, Integer.toString(anInstanceVar));
404            out.writeFields();
405        }
406    }
407
408    private static class WriteFieldsWithoutFetchingPutFields implements
409            java.io.Serializable {
410        private static final String SIMULATED_FIELD_NAME = "text";
411
412        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
413                SIMULATED_FIELD_NAME, String.class) };
414
415        public int anInstanceVar = 5;
416
417        public WriteFieldsWithoutFetchingPutFields() {
418            super();
419        }
420
421        private void readObject(java.io.ObjectInputStream in)
422                throws java.io.IOException, ClassNotFoundException {
423            in.readFields();
424        }
425
426        private void writeObject(java.io.ObjectOutputStream out)
427                throws java.io.IOException, ClassNotFoundException {
428            out.writeFields();
429        }
430    }
431
432    private static class SerialPersistentFieldsWithoutField implements
433            java.io.Serializable {
434        public int anInstanceVar = 5;
435
436        public SerialPersistentFieldsWithoutField() {
437            super();
438        }
439
440        private void readObject(java.io.ObjectInputStream in)
441                throws java.io.IOException, ClassNotFoundException {
442            in.readFields();
443        }
444
445        private void writeObject(java.io.ObjectOutputStream out)
446                throws java.io.IOException, ClassNotFoundException {
447            out.putFields();
448            out.writeFields();
449        }
450    }
451
452    private static class NotSerializable {
453        private int foo;
454
455        public NotSerializable() {
456        }
457
458        protected Object writeReplace() throws ObjectStreamException {
459            return new Integer(42);
460        }
461    }
462
463    private static class WriteReplaceObject implements Serializable {
464        private Object replaceObject;
465
466        private static enum Color {
467            red, blue, green
468        };
469
470        public WriteReplaceObject(Object o) {
471            replaceObject = o;
472        }
473
474        protected Object writeReplace() throws ObjectStreamException {
475            return replaceObject;
476        }
477    }
478
479    private static class ExternalizableWithReplace implements Externalizable {
480        private int foo;
481
482        public ExternalizableWithReplace() {
483        }
484
485        protected Object writeReplace() throws ObjectStreamException {
486            return new Integer(42);
487        }
488
489        public void writeExternal(ObjectOutput out) {
490        }
491
492        public void readExternal(ObjectInput in) {
493        }
494    }
495
496    private static class ObjectOutputStreamWithReplace extends
497            ObjectOutputStream {
498        public ObjectOutputStreamWithReplace(OutputStream out)
499                throws IOException {
500            super(out);
501            enableReplaceObject(true);
502        }
503
504        protected Object replaceObject(Object obj) throws IOException {
505            if (obj instanceof NotSerializable) {
506                return new Long(10);
507            }
508            if (obj instanceof Integer) {
509                return new Long(((Integer) obj).longValue());
510            }
511            return super.replaceObject(obj);
512        }
513    }
514
515    private static class ObjectOutputStreamWithReplace2 extends
516            ObjectOutputStream {
517        public ObjectOutputStreamWithReplace2(OutputStream out)
518                throws IOException {
519            super(out);
520            enableReplaceObject(true);
521        }
522
523        protected Object replaceObject(Object obj) throws IOException {
524            return new Long(10);
525        }
526    }
527
528    private static class ObjectOutputStreamWriteOverride extends
529            ObjectOutputStream {
530        String test = "test";
531
532        protected ObjectOutputStreamWriteOverride() throws IOException,
533                SecurityException {
534            super();
535        }
536
537        @Override
538        protected void writeObjectOverride(Object object) throws IOException {
539            test = null;
540            super.writeObjectOverride(object);
541        }
542    }
543
544    protected static final String MODE_XLOAD = "xload";
545
546    protected static final String MODE_XDUMP = "xdump";
547
548    static final String FOO = "foo";
549
550    static final String MSG_WITE_FAILED = "Failed to write: ";
551
552    private static final boolean DEBUG = false;
553
554    protected static boolean xload = false;
555
556    protected static boolean xdump = false;
557
558    protected static String xFileName = null;
559
560    protected ObjectInputStream ois;
561
562    protected ObjectOutputStream oos;
563
564    protected ByteArrayOutputStream bao;
565
566    static final int INIT_INT_VALUE = 7;
567
568    static final String INIT_STR_VALUE = "a string that is blortz";
569
570    /**
571     * @tests java.io.ObjectOutputStream#ObjectOutputStream(java.io.OutputStream)
572     */
573    public void test_ConstructorLjava_io_OutputStream() throws IOException {
574        // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
575        oos.close();
576        oos = new ObjectOutputStream(new ByteArrayOutputStream());
577        oos.close();
578    }
579
580    /**
581     * @tests java.io.ObjectOutputStream#close()
582     */
583    public void test_close() {
584        // Test for method void java.io.ObjectOutputStream.close()
585    }
586
587    /**
588     * @tests java.io.ObjectOutputStream#defaultWriteObject()
589     */
590    public void test_defaultWriteObject() throws IOException {
591        // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
592        try {
593            oos.defaultWriteObject();
594            fail("Failed to throw NotActiveException");
595        } catch (NotActiveException e) {
596            // Correct
597        }
598    }
599
600    /**
601     * @tests java.io.ObjectOutputStream#flush()
602     */
603    public void test_flush() throws Exception {
604        // Test for method void java.io.ObjectOutputStream.flush()
605        int size = bao.size();
606        oos.writeByte(127);
607        assertTrue("Data flushed already", bao.size() == size);
608        oos.flush();
609        assertTrue("Failed to flush data", bao.size() > size);
610        // we don't know how many bytes are actually written for 1
611        // byte, so we test > <before>
612        oos.close();
613        oos = null;
614    }
615
616    /**
617     * @tests java.io.ObjectOutputStream#putFields()
618     */
619    public void test_putFields() throws Exception {
620        // Test for method java.io.ObjectOutputStream$PutField
621        // java.io.ObjectOutputStream.putFields()
622
623        SerializableTestHelper sth;
624
625        /*
626         * "SerializableTestHelper" is an object created for these tests with
627         * two fields (Strings) and simple implementations of readObject and
628         * writeObject which simply read and write the first field but not the
629         * second
630         */
631
632        oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
633        oos.flush();
634        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
635        sth = (SerializableTestHelper) (ois.readObject());
636        assertEquals("readFields / writeFields failed--first field not set",
637                "Gabba", sth.getText1());
638        assertNull(
639                "readFields / writeFields failed--second field should not have been set",
640                sth.getText2());
641    }
642
643    /**
644     * @tests java.io.ObjectOutputStream#reset()
645     */
646    public void test_reset() throws Exception {
647        // Test for method void java.io.ObjectOutputStream.reset()
648        String o = "HelloWorld";
649        oos.writeObject(o);
650        oos.writeObject(o);
651        oos.reset();
652        oos.writeObject(o);
653        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
654        ois.close();
655    }
656
657    private static class ExternalTest implements Externalizable {
658        public String value;
659
660        public ExternalTest() {
661        }
662
663        public void setValue(String val) {
664            value = val;
665        }
666
667        public String getValue() {
668            return value;
669        }
670
671        public void writeExternal(ObjectOutput output) {
672            try {
673                output.writeUTF(value);
674            } catch (IOException e) {
675                e.printStackTrace();
676            }
677        }
678
679        public void readExternal(ObjectInput input) {
680            try {
681                value = input.readUTF();
682            } catch (IOException e) {
683                e.printStackTrace();
684            }
685        }
686    }
687
688    /**
689     * @tests java.io.ObjectOutputStream#useProtocolVersion(int)
690     */
691    public void test_useProtocolVersionI() throws Exception {
692        // Test for method void
693        // java.io.ObjectOutputStream.useProtocolVersion(int)
694        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
695        ExternalTest t1 = new ExternalTest();
696        t1.setValue("hello1");
697        oos.writeObject(t1);
698        oos.close();
699        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
700        ExternalTest t2 = (ExternalTest) ois.readObject();
701        ois.close();
702        assertTrue(
703                "Cannot read/write PROTOCAL_VERSION_1 Externalizable objects: "
704                        + t2.getValue(), t1.getValue().equals(t2.getValue()));
705
706        // Cannot set protocol version when stream in-flight
707        ObjectOutputStream out = new ObjectOutputStream(
708                new ByteArrayOutputStream());
709        out.writeObject("hello world");
710        try {
711            out.useProtocolVersion(ObjectStreamConstants.PROTOCOL_VERSION_1);
712            fail("Expected IllegalStateException");
713        } catch (IllegalStateException e) {
714            // Expected
715        }
716    }
717
718    /**
719     * @tests java.io.ObjectOutputStream#write(byte[])
720     */
721    public void test_write$B() throws Exception {
722        // Test for method void java.io.ObjectOutputStream.write(byte [])
723        byte[] buf = new byte[10];
724        oos.write("HelloWorld".getBytes());
725        oos.close();
726        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
727        ois.read(buf, 0, 10);
728        ois.close();
729        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
730                10));
731    }
732
733    /**
734     * @tests java.io.ObjectOutputStream#write(byte[], int, int)
735     */
736    public void test_write$BII() throws Exception {
737        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
738        // int)
739        byte[] buf = new byte[10];
740        oos.write("HelloWorld".getBytes(), 0, 10);
741        oos.close();
742        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
743        ois.read(buf, 0, 10);
744        ois.close();
745        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
746                10));
747    }
748
749    /**
750     * @tests java.io.ObjectOutputStream#write(int)
751     */
752    public void test_writeI() throws Exception {
753        // Test for method void java.io.ObjectOutputStream.write(int)
754        oos.write('T');
755        oos.close();
756        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
757        assertEquals("Read incorrect byte", 'T', ois.read());
758        ois.close();
759    }
760
761    /**
762     * @tests java.io.ObjectOutputStream#writeBoolean(boolean)
763     */
764    public void test_writeBooleanZ() throws Exception {
765        // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
766        oos.writeBoolean(true);
767        oos.close();
768        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
769        assertTrue("Wrote incorrect byte value", ois.readBoolean());
770    }
771
772    /**
773     * @tests java.io.ObjectOutputStream#writeByte(int)
774     */
775    public void test_writeByteI() throws Exception {
776        // Test for method void java.io.ObjectOutputStream.writeByte(int)
777        oos.writeByte(127);
778        oos.close();
779        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
780        assertEquals("Wrote incorrect byte value", 127, ois.readByte());
781    }
782
783    /**
784     * @tests java.io.ObjectOutputStream#writeBytes(java.lang.String)
785     */
786    public void test_writeBytesLjava_lang_String() throws Exception {
787        // Test for method void
788        // java.io.ObjectOutputStream.writeBytes(java.lang.String)
789        byte[] buf = new byte[10];
790        oos.writeBytes("HelloWorld");
791        oos.close();
792        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
793        ois.readFully(buf);
794        ois.close();
795        assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(
796                buf, 0, 10, "UTF-8"));
797    }
798
799    /**
800     * @tests java.io.ObjectOutputStream#writeChar(int)
801     */
802    public void test_writeCharI() throws Exception {
803        // Test for method void java.io.ObjectOutputStream.writeChar(int)
804        oos.writeChar('T');
805        oos.close();
806        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
807        assertEquals("Wrote incorrect char value", 'T', ois.readChar());
808    }
809
810    /**
811     * @tests java.io.ObjectOutputStream#writeChars(java.lang.String)
812     */
813    public void test_writeCharsLjava_lang_String() throws Exception {
814        // Test for method void
815        // java.io.ObjectOutputStream.writeChars(java.lang.String)
816        int avail = 0;
817        char[] buf = new char[10];
818        oos.writeChars("HelloWorld");
819        oos.close();
820        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
821        // Number of prim data bytes in stream / 2 to give char index
822        avail = ois.available() / 2;
823        for (int i = 0; i < avail; ++i)
824            buf[i] = ois.readChar();
825        ois.close();
826        assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0,
827                10));
828    }
829
830    /**
831     * @tests java.io.ObjectOutputStream#writeDouble(double)
832     */
833    public void test_writeDoubleD() throws Exception {
834        // Test for method void java.io.ObjectOutputStream.writeDouble(double)
835        oos.writeDouble(Double.MAX_VALUE);
836        oos.close();
837        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
838        assertTrue("Wrote incorrect double value",
839                ois.readDouble() == Double.MAX_VALUE);
840    }
841
842    /**
843     * @tests java.io.ObjectOutputStream#writeFields()
844     */
845    public void test_writeFields() {
846        // Test for method void java.io.ObjectOutputStream.writeFields()
847        assertTrue("Used to test", true);
848    }
849
850    /**
851     * @tests java.io.ObjectOutputStream#writeFloat(float)
852     */
853    public void test_writeFloatF() throws Exception {
854        // Test for method void java.io.ObjectOutputStream.writeFloat(float)
855        oos.writeFloat(Float.MAX_VALUE);
856        oos.close();
857        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
858        assertTrue("Wrote incorrect double value",
859                ois.readFloat() == Float.MAX_VALUE);
860        ois.close();
861        ois = null;
862    }
863
864    /**
865     * @tests java.io.ObjectOutputStream#writeInt(int)
866     */
867    public void test_writeIntI() throws Exception {
868        // Test for method void java.io.ObjectOutputStream.writeInt(int)
869        oos.writeInt(Integer.MAX_VALUE);
870        oos.close();
871        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
872        assertTrue("Wrote incorrect double value",
873                ois.readInt() == Integer.MAX_VALUE);
874        ois.close();
875    }
876
877    /**
878     * @tests java.io.ObjectOutputStream#writeLong(long)
879     */
880    public void test_writeLongJ() throws Exception {
881        // Test for method void java.io.ObjectOutputStream.writeLong(long)
882        oos.writeLong(Long.MAX_VALUE);
883        oos.close();
884        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
885        assertTrue("Wrote incorrect double value",
886                ois.readLong() == Long.MAX_VALUE);
887    }
888
889    /**
890     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
891     */
892    public void test_writeObjectLjava_lang_Object() throws Exception {
893        // Test for method void
894        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
895
896        Object objToSave = null;
897        Object objLoaded;
898
899        SerialPersistentFieldsWithoutField spf = new SerialPersistentFieldsWithoutField();
900        final int CONST = -500;
901        spf.anInstanceVar = CONST;
902        objToSave = spf;
903        if (DEBUG)
904            System.out.println("Obj = " + objToSave);
905        objLoaded = dumpAndReload(objToSave);
906        assertTrue(
907                "serialPersistentFields do not work properly in this implementation",
908                ((SerialPersistentFieldsWithoutField) objLoaded).anInstanceVar != CONST);
909
910    }
911
912    /**
913     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
914     */
915    public void test_writeObject_NotSerializable() throws Exception {
916        ObjectOutput out = null;
917        try {
918            out = new ObjectOutputStream(new ByteArrayOutputStream());
919            out.writeObject(new NotSerializable());
920            fail("Expected NotSerializableException");
921        } catch (NotSerializableException e) {
922        }
923        out.writeObject(new ExternalizableWithReplace());
924    }
925
926    /**
927     * @tests {@link java.io.ObjectOutputStream#writeObjectOverride(Object)}
928     */
929    public void test_writeObject_WriteOverride() throws Exception {
930        ObjectOutputStreamWriteOverride mockOut = new ObjectOutputStreamWriteOverride();
931        mockOut.writeObject(new Object());
932        assertNull(mockOut.test);
933    }
934
935    /**
936     * @tests java.io.ObjectOutputStream#writeShort(int)
937     */
938    public void test_writeShortI() throws Exception {
939        // Test for method void java.io.ObjectOutputStream.writeShort(int)
940        oos.writeShort(127);
941        oos.close();
942        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
943        assertEquals("Wrote incorrect short value", 127, ois.readShort());
944    }
945
946    /**
947     * @tests java.io.ObjectOutputStream#writeUTF(java.lang.String)
948     */
949    public void test_writeUTFLjava_lang_String() throws Exception {
950        // Test for method void
951        // java.io.ObjectOutputStream.writeUTF(java.lang.String)
952        oos.writeUTF("HelloWorld");
953        oos.close();
954        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
955        assertEquals("Wrote incorrect UTF value", "HelloWorld", ois.readUTF());
956    }
957
958    /**
959     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
960     */
961    public void test_writeObject_Exception() throws ClassNotFoundException,
962            IOException {
963        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
964        ObjectOutputStream oos = new ObjectOutputStream(baos);
965
966        try {
967            oos.writeObject(new Object());
968            fail("should throw ObjectStreamException");
969        } catch (ObjectStreamException e) {
970            // expected
971        } finally {
972            oos.close();
973            baos.close();
974        }
975
976        byte[] bytes = baos.toByteArray();
977        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
978                bytes));
979        try {
980            ois.readObject();
981            fail("should throw WriteAbortedException");
982        } catch (WriteAbortedException e) {
983            // expected
984        } finally {
985            ois.close();
986        }
987    }
988
989    /**
990     * @tests {@link java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class<T>)}
991     */
992    public void test_annotateProxyClass() throws SecurityException, IOException {
993        MockObjectOutputStream mockObjectOutputStream = new MockObjectOutputStream();
994        mockObjectOutputStream.annotateProxyClass(this.getClass());
995        assertEquals("The default implementation is doing nothing.",
996                mockObjectOutputStream, mockObjectOutputStream);
997
998    }
999
1000    class MockObjectOutputStream extends ObjectOutputStream {
1001
1002        protected MockObjectOutputStream() throws IOException,
1003                SecurityException {
1004            super();
1005        }
1006
1007        @Override
1008        public void annotateProxyClass(Class<?> aClass) throws IOException {
1009            super.annotateProxyClass(aClass);
1010        }
1011
1012    }
1013
1014    /**
1015     * Sets up the fixture, for example, open a network connection. This method
1016     * is called before a test is executed.
1017     */
1018    protected void setUp() throws Exception {
1019        super.setUp();
1020        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1021    }
1022
1023    /**
1024     * Tears down the fixture, for example, close a network connection. This
1025     * method is called after a test is executed.
1026     */
1027    protected void tearDown() throws Exception {
1028        super.tearDown();
1029        if (oos != null) {
1030            try {
1031                oos.close();
1032            } catch (Exception e) {
1033            }
1034        }
1035        if (f != null && f.exists()) {
1036            if (!f.delete()) {
1037                fail("Error cleaning up files during teardown");
1038            }
1039        }
1040    }
1041
1042    protected Object reload() throws IOException, ClassNotFoundException {
1043
1044        // Choose the load stream
1045        if (xload || xdump) {
1046            // Load from pre-existing file
1047            ois = new ObjectInputStream(new FileInputStream(xFileName + "-"
1048                    + getName() + ".ser"));
1049        } else {
1050            // Just load from memory, we dumped to memory
1051            ois = new ObjectInputStream(new ByteArrayInputStream(bao
1052                    .toByteArray()));
1053        }
1054
1055        try {
1056            return ois.readObject();
1057        } finally {
1058            ois.close();
1059        }
1060    }
1061
1062    protected void dump(Object o) throws IOException, ClassNotFoundException {
1063
1064        // Choose the dump stream
1065        if (xdump) {
1066            oos = new ObjectOutputStream(new FileOutputStream(
1067                    f = new java.io.File(xFileName + "-" + getName() + ".ser")));
1068        } else {
1069            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1070        }
1071
1072        // Dump the object
1073        try {
1074            oos.writeObject(o);
1075        } finally {
1076            oos.close();
1077        }
1078    }
1079
1080    /**
1081     * @tests java.io.ObjectOutputStream#writeInt(int)
1082     * @tests java.io.ObjectOutputStream#writeObject(java.lang.Object)
1083     * @tests java.io.ObjectOutputStream#writeUTF(java.lang.String)
1084     */
1085
1086    public void testMixPrimitivesAndObjects() throws Exception {
1087        int i = 7;
1088        String s1 = "string 1";
1089        String s2 = "string 2";
1090        byte[] bytes = { 1, 2, 3 };
1091        try {
1092            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1093            oos.writeInt(i);
1094            oos.writeObject(s1);
1095            oos.writeUTF(s2);
1096            oos.writeObject(bytes);
1097            oos.close();
1098
1099            ois = new ObjectInputStream(new ByteArrayInputStream(bao
1100                    .toByteArray()));
1101
1102            int j = ois.readInt();
1103            assertTrue("Wrong int :" + j, i == j);
1104
1105            String l1 = (String) ois.readObject();
1106            assertTrue("Wrong obj String :" + l1, s1.equals(l1));
1107
1108            String l2 = ois.readUTF();
1109            assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
1110
1111            byte[] bytes2 = (byte[]) ois.readObject();
1112            assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
1113        } finally {
1114            try {
1115                if (oos != null)
1116                    oos.close();
1117                if (ois != null)
1118                    ois.close();
1119            } catch (IOException e) {
1120            }
1121        }
1122    }
1123
1124    /**
1125     * @tests java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
1126     */
1127    public void test_writeUnshared() throws Exception {
1128        // Regression for HARMONY-187
1129        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1130        ObjectOutputStream oos = new ObjectOutputStream(baos);
1131
1132        Object o = "foobar";
1133        oos.writeObject(o);
1134        oos.writeUnshared(o);
1135        oos.writeObject(o);
1136        oos.flush();
1137
1138        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
1139                baos.toByteArray()));
1140
1141        Object[] oa = new Object[3];
1142        for (int i = 0; i < oa.length; i++) {
1143            oa[i] = ois.readObject();
1144        }
1145
1146        oos.close();
1147        ois.close();
1148
1149        // All three conditions must be met
1150        assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
1151        assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
1152        assertSame("oa[0] == oa[2]", oa[0], oa[2]);
1153    }
1154
1155    /**
1156     * @tests java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
1157     */
1158    public void test_writeUnshared2() throws Exception {
1159        // Regression for HARMONY-187
1160        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1161        ObjectOutputStream oos = new ObjectOutputStream(baos);
1162
1163        Object o = new Object[1];
1164        oos.writeObject(o);
1165        oos.writeUnshared(o);
1166        oos.writeObject(o);
1167        oos.flush();
1168
1169        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
1170                baos.toByteArray()));
1171
1172        Object[] oa = new Object[3];
1173        for (int i = 0; i < oa.length; i++) {
1174            oa[i] = ois.readObject();
1175        }
1176
1177        oos.close();
1178        ois.close();
1179
1180        // All three conditions must be met
1181        assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
1182        assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
1183        assertSame("oa[0] == oa[2]", oa[0], oa[2]);
1184    }
1185
1186    protected Object dumpAndReload(Object o) throws IOException,
1187            ClassNotFoundException {
1188        dump(o);
1189        return reload();
1190    }
1191
1192    /**
1193     * @tests java.io.ObjectOutputStream#useProtocolVersion(int)
1194     */
1195    public void test_useProtocolVersionI_2() throws Exception {
1196        ObjectOutputStream oos = new ObjectOutputStream(
1197                new ByteArrayOutputStream());
1198
1199        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
1200        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_2);
1201        try {
1202            oos.useProtocolVersion(3);
1203            fail("Protocol 3 should not be accepted");
1204        } catch (IllegalArgumentException e) {
1205            // expected
1206        } finally {
1207            oos.close();
1208        }
1209    }
1210
1211    /**
1212     * @tests java.io.ObjectOutputStream#replaceObject(java.lang.Object)
1213     */
1214    public void test_replaceObject() throws Exception {
1215        // Regression for HARMONY-1429
1216        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1217        ObjectOutputStreamWithReplace oos = new ObjectOutputStreamWithReplace(
1218                baos);
1219
1220        oos.writeObject(new NotSerializable());
1221        oos.flush();
1222        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
1223                baos.toByteArray()));
1224        Object obj = ois.readObject();
1225        oos.close();
1226        ois.close();
1227        assertTrue("replaceObject has not been called", (obj instanceof Long));
1228
1229        // Regression for HARMONY-2239
1230        Object replaceObject = int.class;
1231        baos = new ByteArrayOutputStream();
1232        ObjectOutputStreamWithReplace2 oos2 = new ObjectOutputStreamWithReplace2(
1233                baos);
1234        oos2.writeObject(new WriteReplaceObject(replaceObject));
1235        oos2.flush();
1236        ois = new ObjectInputStream(
1237                new ByteArrayInputStream(baos.toByteArray()));
1238        obj = ois.readObject();
1239        oos.close();
1240        ois.close();
1241        assertTrue("replaceObject has not been called", (obj instanceof Long));
1242
1243        replaceObject = ObjectStreamClass.lookup(Integer.class);
1244        baos = new ByteArrayOutputStream();
1245        oos2 = new ObjectOutputStreamWithReplace2(baos);
1246        oos2.writeObject(new WriteReplaceObject(replaceObject));
1247        oos2.flush();
1248        ois = new ObjectInputStream(
1249                new ByteArrayInputStream(baos.toByteArray()));
1250        obj = ois.readObject();
1251        oos.close();
1252        ois.close();
1253        assertTrue("replaceObject has not been called", (obj instanceof Long));
1254
1255        replaceObject = WriteReplaceObject.Color.red;
1256        baos = new ByteArrayOutputStream();
1257        oos2 = new ObjectOutputStreamWithReplace2(baos);
1258        oos2.writeObject(new WriteReplaceObject(replaceObject));
1259        oos2.flush();
1260        ois = new ObjectInputStream(
1261                new ByteArrayInputStream(baos.toByteArray()));
1262        obj = ois.readObject();
1263        oos.close();
1264        ois.close();
1265        assertTrue("replaceObject has not been called", (obj instanceof Long));
1266
1267        // Regression for HARMONY-3158
1268        Object obj1;
1269        Object obj2;
1270        Object obj3;
1271
1272        baos = new ByteArrayOutputStream();
1273        oos = new ObjectOutputStreamWithReplace(baos);
1274
1275        oos.writeObject(new Integer(99));
1276        oos.writeObject(Integer.class);
1277        oos.writeObject(ObjectStreamClass.lookup(Integer.class));
1278        oos.flush();
1279
1280        ois = new ObjectInputStream(
1281                new ByteArrayInputStream(baos.toByteArray()));
1282        obj1 = ois.readObject();
1283        obj2 = ois.readObject();
1284        obj3 = ois.readObject();
1285        oos.close();
1286        ois.close();
1287
1288        assertTrue("1st replaceObject worked incorrectly", obj1 instanceof Long);
1289        assertEquals("1st replaceObject worked incorrectly", 99, ((Long) obj1)
1290                .longValue());
1291        assertEquals("2nd replaceObject worked incorrectly", Integer.class,
1292                obj2);
1293        assertEquals("3rd replaceObject worked incorrectly",
1294                ObjectStreamClass.class, obj3.getClass());
1295    }
1296
1297    public void test_putFieldWrite() throws Exception {
1298        // Regression test for HARMONY-6483
1299        ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream());
1300        try {
1301            oos.writeObject(new OutputObject());
1302            fail("Should throw an IllegalArgumentException");
1303        } catch (IllegalArgumentException iae) {
1304            // Expected
1305        }
1306    }
1307
1308    private static class OutputObject implements Serializable {
1309        private void writeObject(ObjectOutputStream oos) throws IOException {
1310            ObjectOutputStream oos2 = new ObjectOutputStream(new ByteArrayOutputStream());
1311            ObjectOutputStream.PutField putField = oos.putFields();
1312            putField.write(oos2);
1313        }
1314    }
1315}
1316