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 junit.framework.TestCase;
21import org.apache.harmony.testframework.serialization.SerializationTest;
22import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
23import tests.support.Support_ASimpleInputStream;
24import java.io.BufferedInputStream;
25import java.io.ByteArrayInputStream;
26import java.io.ByteArrayOutputStream;
27import java.io.EOFException;
28import java.io.Externalizable;
29import java.io.File;
30import java.io.FileInputStream;
31import java.io.FileOutputStream;
32import java.io.IOException;
33import java.io.InputStream;
34import java.io.InvalidObjectException;
35import java.io.NotActiveException;
36import java.io.ObjectInput;
37import java.io.ObjectInputStream;
38import java.io.ObjectInputValidation;
39import java.io.ObjectOutput;
40import java.io.ObjectOutputStream;
41import java.io.ObjectStreamClass;
42import java.io.ObjectStreamException;
43import java.io.OutputStream;
44import java.io.PipedInputStream;
45import java.io.PipedOutputStream;
46import java.io.Serializable;
47import java.io.StreamCorruptedException;
48import java.lang.reflect.Proxy;
49import java.util.Arrays;
50import java.util.HashMap;
51import java.util.Hashtable;
52import java.util.Vector;
53
54@SuppressWarnings("serial")
55public class ObjectInputStreamTest extends TestCase implements
56        Serializable {
57
58    public class SerializableTestHelper implements Serializable {
59
60        public String aField1;
61
62        public String aField2;
63
64        SerializableTestHelper() {
65            aField1 = null;
66            aField2 = null;
67        }
68
69        SerializableTestHelper(String s, String t) {
70            aField1 = s;
71            aField2 = t;
72        }
73
74        private void readObject(ObjectInputStream ois) throws Exception {
75            // note aField2 is not read
76            ObjectInputStream.GetField fields = ois.readFields();
77            aField1 = (String) fields.get("aField1", "Zap");
78        }
79
80        private void writeObject(ObjectOutputStream oos) throws IOException {
81            // note aField2 is not written
82            ObjectOutputStream.PutField fields = oos.putFields();
83            fields.put("aField1", aField1);
84            oos.writeFields();
85        }
86
87        public String getText1() {
88            return aField1;
89        }
90
91        public void setText1(String s) {
92            aField1 = s;
93        }
94
95        public String getText2() {
96            return aField2;
97        }
98
99        public void setText2(String s) {
100            aField2 = s;
101        }
102    }
103
104    public static class A1 implements Serializable {
105
106        private static final long serialVersionUID = 5942584913446079661L;
107
108        B1 b1 = new B1();
109
110        B1 b2 = b1;
111
112        Vector v = new Vector();
113    }
114
115    public static class B1 implements Serializable {
116
117        int i = 5;
118
119        Hashtable h = new Hashtable();
120    }
121
122    static final long serialVersionUID = 1L;
123
124    ObjectInputStream ois;
125
126    ObjectOutputStream oos;
127
128    ByteArrayOutputStream bao;
129
130    boolean readStreamHeaderCalled;
131
132    private final String testString = "Lorem ipsum...";
133
134    private final int testLength = testString.length();
135
136    public void test_ConstructorLjava_io_InputStream_IOException() throws IOException {
137        oos.writeObject(testString);
138        oos.close();
139
140        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
141        sis.throwExceptionOnNextUse = true;
142        try {
143            ois = new ObjectInputStream(sis);
144            fail("Test 1: IOException expected.");
145        } catch (IOException e) {
146            // Expected.
147        }
148        sis.throwExceptionOnNextUse = false;
149    }
150
151    public void test_ClassDescriptor() throws IOException,
152            ClassNotFoundException {
153
154        ByteArrayOutputStream baos = new ByteArrayOutputStream();
155        ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc(
156                baos);
157        oos.writeObject(String.class);
158        oos.close();
159        Class<?> cls = TestClassForSerialization.class;
160        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
161        ObjectInputStreamWithReadDesc ois = new ObjectInputStreamWithReadDesc(
162                bais, cls);
163        Object obj = ois.readObject();
164        ois.close();
165        assertEquals(cls, obj);
166    }
167
168    public void test_available_IOException() throws IOException {
169        oos.writeObject(testString);
170        oos.close();
171
172        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
173        ois = new ObjectInputStream(sis);
174        sis.throwExceptionOnNextUse = true;
175        try {
176            ois.available();
177            fail("Test 1: IOException expected.");
178        } catch (IOException e) {
179            // Expected.
180        }
181        sis.throwExceptionOnNextUse = false;
182        ois.close();
183    }
184
185    public void test_close() throws Exception {
186        // Test for method void java.io.ObjectInputStream.close()
187        oos.writeObject(testString);
188        oos.close();
189
190        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
191        ois = new ObjectInputStream(sis);
192        sis.throwExceptionOnNextUse = true;
193        try {
194            ois.close();
195            fail("Test 1: IOException expected.");
196        } catch (IOException e) {
197            // Expected.
198        }
199        sis.throwExceptionOnNextUse = false;
200        ois.close();
201    }
202
203    public void test_enableResolveObjectB() throws IOException {
204        // Start testing without a SecurityManager.
205        BasicObjectInputStream bois = new BasicObjectInputStream();
206        assertFalse("Test 1: Object resolving must be disabled by default.",
207                bois.enableResolveObject(true));
208
209        assertTrue("Test 2: enableResolveObject did not return the previous value.",
210                bois.enableResolveObject(false));
211    }
212
213    public void test_read_IOException() throws IOException {
214        oos.writeObject(testString);
215        oos.close();
216
217        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
218        ois = new ObjectInputStream(sis);
219        sis.throwExceptionOnNextUse = true;
220        try {
221            ois.read();
222            fail("Test 1: IOException expected.");
223        } catch (IOException e) {
224            // Expected.
225        }
226        sis.throwExceptionOnNextUse = false;
227        ois.close();
228    }
229
230    public void test_read$BII_Exception() throws IOException {
231        byte[] buf = new byte[testLength];
232        oos.writeObject(testString);
233        oos.close();
234
235        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
236        try {
237            ois.read(buf, 0, -1);
238            fail("IndexOutOfBoundsException was not thrown.");
239        } catch (IndexOutOfBoundsException e) {
240            // Expected
241        }
242        try {
243            ois.read(buf, -1,1);
244            fail("IndexOutOfBoundsException was not thrown.");
245        } catch (IndexOutOfBoundsException e) {
246            // Expected
247        }
248        try {
249            ois.read(buf, testLength, 1);
250            fail("IndexOutOfBoundsException was not thrown.");
251        } catch (IndexOutOfBoundsException e) {
252            // Expected
253        }
254        ois.close();
255
256
257        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
258        ois = new ObjectInputStream(sis);
259        sis.throwExceptionOnNextUse = true;
260        try {
261            ois.read(buf, 0, testLength);
262            fail("Test 1: IOException expected.");
263        } catch (IOException e) {
264            // Expected.
265        }
266        sis.throwExceptionOnNextUse = false;
267        ois.close();
268    }
269
270    public void test_readFully$B() throws IOException {
271        byte[] buf = new byte[testLength];
272        oos.writeBytes(testString);
273        oos.close();
274        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
275        ois.readFully(buf);
276        assertEquals("Test 1: Incorrect bytes read;",
277                testString, new String(buf));
278        ois.close();
279
280        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
281        ois.read();
282        try {
283            ois.readFully(buf);
284            fail("Test 2: EOFException expected.");
285        } catch (EOFException e) {
286            // Expected.
287        }
288    }
289
290    public void test_readFully$B_Exception() throws IOException {
291        byte[] buf = new byte[testLength];
292        oos.writeObject(testString);
293        oos.close();
294
295        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
296        ois = new ObjectInputStream(sis);
297        sis.throwExceptionOnNextUse = true;
298        try {
299            ois.readFully(buf);
300            fail("Test 1: IOException expected.");
301        } catch (IOException e) {
302            // Expected.
303        }
304        sis.throwExceptionOnNextUse = false;
305        ois.close();
306    }
307
308    public void test_readFully$BII() throws IOException {
309        // Test for method void java.io.ObjectInputStream.readFully(byte [],
310        // int, int)
311        byte[] buf = new byte[testLength];
312        oos.writeBytes(testString);
313        oos.close();
314        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
315        ois.readFully(buf, 0, testLength);
316        assertEquals("Read incorrect bytes", testString, new String(buf));
317        ois.close();
318
319        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
320        ois.read();
321        try {
322            ois.readFully(buf);
323            fail("Test 2: EOFException expected.");
324        } catch (EOFException e) {
325            // Expected.
326        }
327    }
328
329    public void test_readFully$BII_Exception() throws IOException {
330        byte[] buf = new byte[testLength];
331        oos.writeObject(testString);
332        oos.close();
333
334        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
335        try {
336            ois.readFully(buf, 0, -1);
337            fail("IndexOutOfBoundsException was not thrown.");
338        } catch (IndexOutOfBoundsException e) {
339            // Expected
340        }
341        try {
342            ois.readFully(buf, -1,1);
343            fail("IndexOutOfBoundsException was not thrown.");
344        } catch (IndexOutOfBoundsException e) {
345            // Expected
346        }
347        try {
348            ois.readFully(buf, testLength, 1);
349            fail("IndexOutOfBoundsException was not thrown.");
350        } catch (IndexOutOfBoundsException e) {
351            // Expected
352        }
353        ois.close();
354
355        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
356        ois = new ObjectInputStream(sis);
357        sis.throwExceptionOnNextUse = true;
358        try {
359            ois.readFully(buf, 0, 1);
360            fail("Test 1: IOException expected.");
361        } catch (IOException e) {
362            // Expected.
363        }
364        sis.throwExceptionOnNextUse = false;
365        ois.close();
366    }
367
368    public void test_readLine_IOException() throws IOException {
369        oos.writeObject(testString);
370        oos.close();
371
372        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
373        ois = new ObjectInputStream(sis);
374        sis.throwExceptionOnNextUse = true;
375        try {
376            ois.readLine();
377            fail("Test 1: IOException expected.");
378        } catch (IOException e) {
379            // Expected.
380        }
381        sis.throwExceptionOnNextUse = false;
382        ois.close();
383    }
384
385    private void fillStreamHeader(byte[] buffer) {
386        short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
387        short version = java.io.ObjectStreamConstants.STREAM_VERSION;
388
389        if (buffer.length < 4) {
390            throw new IllegalArgumentException("The buffer's minimal length must be 4.");
391        }
392
393        // Initialize the buffer with the correct header for object streams
394        buffer[0] = (byte) (magic >> 8);
395        buffer[1] = (byte) magic;
396        buffer[2] = (byte) (version >> 8);
397        buffer[3] = (byte) (version);
398    }
399
400    public void test_readObjectOverride() throws Exception {
401        byte[] buffer = new byte[4];
402
403        // Initialize the buffer with the correct header for object streams
404        fillStreamHeader(buffer);
405
406        // Test 1: Check that readObjectOverride() returns null if there
407        // is no input stream.
408        BasicObjectInputStream bois = new BasicObjectInputStream();
409        assertNull("Test 1:", bois.readObjectOverride());
410
411        // Test 2: Check that readObjectOverride() returns null if it isn't overriden.
412        //
413        // On Android M and below, this method threw an IOException.
414        bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
415        assertNull(bois.readObjectOverride());
416        bois.close();
417    }
418
419    public void test_readObjectMissingClasses() throws Exception {
420        SerializationTest.verifySelf(new A1(), new SerializableAssert() {
421            public void assertDeserialized(Serializable initial,
422                    Serializable deserialized) {
423                assertEquals(5, ((A1) deserialized).b1.i);
424            }
425        });
426    }
427
428    public void test_readStreamHeader() throws IOException {
429        String testString = "Lorem ipsum";
430        BasicObjectInputStream bois;
431        short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
432        short version = java.io.ObjectStreamConstants.STREAM_VERSION;
433        byte[] buffer = new byte[20];
434
435        // Initialize the buffer with the correct header for object streams
436        fillStreamHeader(buffer);
437        System.arraycopy(testString.getBytes(), 0, buffer, 4, testString.length());
438
439        // Test 1: readStreamHeader should not throw a StreamCorruptedException.
440        // It should get called by the ObjectInputStream constructor.
441        try {
442            readStreamHeaderCalled = false;
443            bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
444            bois.close();
445        } catch (StreamCorruptedException e) {
446            fail("Test 1: Unexpected StreamCorruptedException.");
447        }
448        assertTrue("Test 1: readStreamHeader() has not been called.",
449                    readStreamHeaderCalled);
450
451        // Test 2: Make the stream magic number invalid and check that
452        // readStreamHeader() throws an exception.
453        buffer[0] = (byte)magic;
454        buffer[1] = (byte)(magic >> 8);
455        try {
456            readStreamHeaderCalled = false;
457            bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
458            fail("Test 2: StreamCorruptedException expected.");
459            bois.close();
460        } catch (StreamCorruptedException e) {
461        }
462        assertTrue("Test 2: readStreamHeader() has not been called.",
463                    readStreamHeaderCalled);
464
465        // Test 3: Make the stream version invalid and check that
466        // readStreamHeader() throws an exception.
467        buffer[0] = (byte)(magic >> 8);
468        buffer[1] = (byte)magic;
469        buffer[2] = (byte)(version);
470        buffer[3] = (byte)(version >> 8);
471        try {
472            readStreamHeaderCalled = false;
473            bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
474            fail("Test 3: StreamCorruptedException expected.");
475            bois.close();
476        } catch (StreamCorruptedException e) {
477        }
478        assertTrue("Test 3: readStreamHeader() has not been called.",
479                    readStreamHeaderCalled);
480    }
481
482    public void test_readUnsignedByte() throws IOException {
483        oos.writeByte(-1);
484        oos.close();
485
486        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
487        assertEquals("Test 1: Incorrect unsigned byte written or read.",
488                255, ois.readUnsignedByte());
489
490        try {
491            ois.readUnsignedByte();
492            fail("Test 2: EOFException expected.");
493        } catch (EOFException e) {
494            // Expected.
495        }
496
497        ois.close();
498        try {
499            ois.readUnsignedByte();
500            fail("Test 3: IOException expected.");
501        } catch (IOException e) {
502            // Expected.
503        }
504    }
505
506    public void test_readUnsignedShort() throws IOException {
507        // Test for method int java.io.ObjectInputStream.readUnsignedShort()
508        oos.writeShort(-1);
509        oos.close();
510
511        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
512        assertEquals("Test 1: Incorrect unsigned short written or read.",
513                65535, ois.readUnsignedShort());
514
515        try {
516            ois.readUnsignedShort();
517            fail("Test 2: EOFException expected.");
518        } catch (EOFException e) {
519            // Expected.
520        }
521
522        ois.close();
523        try {
524            ois.readUnsignedShort();
525            fail("Test 3: IOException expected.");
526        } catch (IOException e) {
527            // Expected.
528        }
529    }
530
531    public void test_skipBytesI_IOException() throws IOException {
532        oos.writeObject(testString);
533        oos.close();
534
535        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
536        ois = new ObjectInputStream(sis);
537        sis.throwExceptionOnNextUse = true;
538        try {
539            ois.skipBytes(5);
540            fail("Test 1: IOException expected.");
541        } catch (IOException e) {
542            // Expected.
543        }
544        sis.throwExceptionOnNextUse = false;
545        ois.close();
546    }
547
548    public static class A implements Serializable {
549
550        private static final long serialVersionUID = 11L;
551
552        public String name = "name";
553    }
554
555    public static class B extends A {}
556
557    public static class C extends B {
558
559        private static final long serialVersionUID = 33L;
560    }
561
562    class BasicObjectInputStream extends ObjectInputStream {
563        public BasicObjectInputStream() throws IOException, SecurityException {
564            super();
565        }
566
567        public BasicObjectInputStream(InputStream input) throws IOException {
568            super(input);
569        }
570
571        public boolean enableResolveObject(boolean enable)
572                throws SecurityException {
573            return super.enableResolveObject(enable);
574        }
575
576        public Object readObjectOverride() throws ClassNotFoundException, IOException {
577            return super.readObjectOverride();
578        }
579
580        public void readStreamHeader() throws IOException {
581            readStreamHeaderCalled = true;
582            super.readStreamHeader();
583        }
584
585        public Class<?> resolveProxyClass(String[] interfaceNames)
586                throws IOException, ClassNotFoundException {
587            return super.resolveProxyClass(interfaceNames);
588        }
589    }
590
591    public static class ObjectInputStreamWithReadDesc extends
592            ObjectInputStream {
593        private Class returnClass;
594
595        public ObjectInputStreamWithReadDesc(InputStream is, Class returnClass)
596                throws IOException {
597            super(is);
598            this.returnClass = returnClass;
599        }
600
601        public ObjectStreamClass readClassDescriptor() throws IOException,
602                ClassNotFoundException {
603            return ObjectStreamClass.lookup(returnClass);
604
605        }
606    }
607
608    static class TestClassForSerialization implements Serializable {
609        private static final long serialVersionUID = 1L;
610    }
611
612    public void test_ConstructorLjava_io_InputStream() throws IOException {
613        oos.writeDouble(Double.MAX_VALUE);
614        oos.close();
615        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
616        ois.close();
617        oos.close();
618
619        try {
620            ois = new ObjectInputStream(new ByteArrayInputStream(new byte[90]));
621            fail("StreamCorruptedException expected");
622        } catch (StreamCorruptedException e) {
623            // Expected
624        }
625    }
626
627    /**
628     * {@link java.io.ObjectInputStream#resolveProxyClass(String[])}
629     */
630    public void test_resolveProxyClass() throws IOException,
631            ClassNotFoundException {
632        oos.writeBytes("HelloWorld");
633        oos.close();
634        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
635        MockObjectInputStream mockIn = new MockObjectInputStream(
636                new ByteArrayInputStream(bao.toByteArray()));
637        Class[] clazzs = { java.io.ObjectInputStream.class,
638                java.io.Reader.class };
639        for (int i = 0; i < clazzs.length; i++) {
640            Class clazz = clazzs[i];
641            Class[] interfaceNames = clazz.getInterfaces();
642            String[] interfaces = new String[interfaceNames.length];
643            int index = 0;
644            for (Class c : interfaceNames) {
645                interfaces[index] = c.getName();
646                index++;
647            }
648            Class<?> s = mockIn.resolveProxyClass(interfaces);
649
650            if (Proxy.isProxyClass(s)) {
651                Class[] implementedInterfaces = s.getInterfaces();
652                for (index = 0; index < implementedInterfaces.length; index++) {
653                    assertEquals(interfaceNames[index],
654                            implementedInterfaces[index]);
655                }
656            } else {
657                fail("Should return a proxy class that implements the interfaces named in a proxy class descriptor");
658            }
659        }
660        mockIn.close();
661    }
662
663    class MockObjectInputStream extends ObjectInputStream {
664
665        public MockObjectInputStream(InputStream input)
666                throws StreamCorruptedException, IOException {
667            super(input);
668        }
669
670        @Override
671        public Class<?> resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException {
672            return super.resolveProxyClass(interfaceNames);
673        }
674
675    }
676
677    public void test_available() throws IOException {
678        oos.writeBytes("HelloWorld");
679        oos.close();
680        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
681        assertEquals("Read incorrect bytes", 10, ois.available());
682        ois.close();
683    }
684
685    /**
686     * java.io.ObjectInputStream#defaultReadObject()
687     */
688    public void test_defaultReadObject() throws Exception {
689        // SM. This method may as well be private, as if called directly it
690        // throws an exception.
691        String s = "HelloWorld";
692        oos.writeObject(s);
693        oos.close();
694        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
695        try {
696            ois.defaultReadObject();
697            fail("NotActiveException expected");
698        } catch (NotActiveException e) {
699            // Desired behavior
700        } finally {
701            ois.close();
702        }
703    }
704
705    /**
706     * java.io.ObjectInputStream#read()
707     */
708    public void test_read() throws IOException {
709        oos.write('T');
710        oos.close();
711        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
712        assertEquals("Read incorrect byte value", 'T', ois.read());
713        ois.close();
714    }
715
716    /**
717     * java.io.ObjectInputStream#read(byte[], int, int)
718     */
719    public void test_read$BII() throws IOException {
720        byte[] buf = new byte[10];
721        oos.writeBytes("HelloWorld");
722        oos.close();
723        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
724        ois.read(buf, 0, 10);
725        ois.close();
726        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
727                10, "UTF-8"));
728    }
729
730    /**
731     * java.io.ObjectInputStream#readBoolean()
732     */
733    public void test_readBoolean() throws IOException {
734        oos.writeBoolean(true);
735        oos.close();
736        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
737        assertTrue("Read incorrect boolean value", ois.readBoolean());
738        ois.close();
739    }
740
741    /**
742     * java.io.ObjectInputStream#readByte()
743     */
744    public void test_readByte() throws IOException {
745        oos.writeByte(127);
746        oos.close();
747        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
748        assertEquals("Read incorrect byte value", 127, ois.readByte());
749        ois.close();
750    }
751
752    /**
753     * java.io.ObjectInputStream#readChar()
754     */
755    public void test_readChar() throws IOException {
756        oos.writeChar('T');
757        oos.close();
758        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
759        assertEquals("Read incorrect char value", 'T', ois.readChar());
760        ois.close();
761    }
762
763    /**
764     * java.io.ObjectInputStream#readDouble()
765     */
766    public void test_readDouble() throws IOException {
767        oos.writeDouble(Double.MAX_VALUE);
768        oos.close();
769        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
770        assertTrue("Read incorrect double value",
771                ois.readDouble() == Double.MAX_VALUE);
772        ois.close();
773    }
774
775    /**
776     * java.io.ObjectInputStream#readFields()
777     */
778    public void test_readFields() throws Exception {
779
780        SerializableTestHelper sth;
781
782        /*
783         * "SerializableTestHelper" is an object created for these tests with
784         * two fields (Strings) and simple implementations of readObject and
785         * writeObject which simply read and write the first field but not the
786         * second
787         */
788
789        oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
790        oos.flush();
791        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
792        sth = (SerializableTestHelper) (ois.readObject());
793        assertEquals("readFields / writeFields failed--first field not set",
794                "Gabba", sth.getText1());
795        assertNull(
796                "readFields / writeFields failed--second field should not have been set",
797                sth.getText2());
798    }
799
800    /**
801     * java.io.ObjectInputStream#readFloat()
802     */
803    public void test_readFloat() throws IOException {
804        oos.writeFloat(Float.MAX_VALUE);
805        oos.close();
806        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
807        assertTrue("Read incorrect float value",
808                ois.readFloat() == Float.MAX_VALUE);
809        ois.close();
810    }
811
812    /**
813     * java.io.ObjectInputStream#readInt()
814     */
815    public void test_readInt() throws IOException {
816        oos.writeInt(Integer.MAX_VALUE);
817        oos.close();
818        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
819        assertTrue("Read incorrect int value",
820                ois.readInt() == Integer.MAX_VALUE);
821        ois.close();
822    }
823
824    /**
825     * java.io.ObjectInputStream#readLine()
826     */
827    @SuppressWarnings("deprecation")
828    public void test_readLine() throws IOException {
829        oos.writeBytes("HelloWorld\nSecondLine");
830        oos.close();
831        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
832        ois.readLine();
833        assertEquals("Read incorrect string value", "SecondLine", ois
834                .readLine());
835        ois.close();
836    }
837
838    /**
839     * java.io.ObjectInputStream#readLong()
840     */
841    public void test_readLong() throws IOException {
842        oos.writeLong(Long.MAX_VALUE);
843        oos.close();
844        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
845        assertTrue("Read incorrect long value",
846                ois.readLong() == Long.MAX_VALUE);
847        ois.close();
848    }
849
850    /**
851     * java.io.ObjectInputStream#readObject()
852     */
853    public void test_readObject() throws Exception {
854        String s = "HelloWorld";
855        oos.writeObject(s);
856        oos.close();
857        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
858        assertEquals("Read incorrect Object value", s, ois.readObject());
859        ois.close();
860
861        // Regression for HARMONY-91
862        // dynamically create serialization byte array for the next hierarchy:
863        // - class A implements Serializable
864        // - class C extends A
865
866        byte[] cName = C.class.getName().getBytes("UTF-8");
867        byte[] aName = A.class.getName().getBytes("UTF-8");
868
869        ByteArrayOutputStream out = new ByteArrayOutputStream();
870
871        byte[] begStream = new byte[] { (byte) 0xac, (byte) 0xed, // STREAM_MAGIC
872                (byte) 0x00, (byte) 0x05, // STREAM_VERSION
873                (byte) 0x73, // TC_OBJECT
874                (byte) 0x72, // TC_CLASSDESC
875                (byte) 0x00, // only first byte for C class name length
876        };
877
878        out.write(begStream, 0, begStream.length);
879        out.write(cName.length); // second byte for C class name length
880        out.write(cName, 0, cName.length); // C class name
881
882        byte[] midStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
883                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
884                (byte) 0x21, // serialVersionUID = 33L
885                (byte) 0x02, // flags
886                (byte) 0x00, (byte) 0x00, // fields : none
887                (byte) 0x78, // TC_ENDBLOCKDATA
888                (byte) 0x72, // Super class for C: TC_CLASSDESC for A class
889                (byte) 0x00, // only first byte for A class name length
890        };
891
892        out.write(midStream, 0, midStream.length);
893        out.write(aName.length); // second byte for A class name length
894        out.write(aName, 0, aName.length); // A class name
895
896        byte[] endStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
897                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
898                (byte) 0x0b, // serialVersionUID = 11L
899                (byte) 0x02, // flags
900                (byte) 0x00, (byte) 0x01, // fields
901
902                (byte) 0x4c, // field description: type L (object)
903                (byte) 0x00, (byte) 0x04, // length
904                // field = 'name'
905                (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65,
906
907                (byte) 0x74, // className1: TC_STRING
908                (byte) 0x00, (byte) 0x12, // length
909                //
910                (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
911                (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
912                (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53,
913                (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e,
914                (byte) 0x67, (byte) 0x3b,
915
916                (byte) 0x78, // TC_ENDBLOCKDATA
917                (byte) 0x70, // NULL super class for A class
918
919                // classdata
920                (byte) 0x74, // TC_STRING
921                (byte) 0x00, (byte) 0x04, // length
922                (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, // value
923        };
924
925        out.write(endStream, 0, endStream.length);
926        out.flush();
927
928        // read created serial. form
929        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
930                out.toByteArray()));
931        Object o = ois.readObject();
932        assertEquals(C.class, o.getClass());
933
934		// Regression for HARMONY-846
935        assertNull(new ObjectInputStream() {}.readObject());
936    }
937
938    /**
939     * java.io.ObjectInputStream#readObject()
940     */
941    public void test_readObjectCorrupt() throws IOException, ClassNotFoundException {
942        byte[] bytes = { 00, 00, 00, 0x64, 0x43, 0x48, (byte) 0xFD, 0x71, 00,
943                00, 0x0B, (byte) 0xB8, 0x4D, 0x65 };
944        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
945        try {
946            ObjectInputStream in = new ObjectInputStream(bin);
947            in.readObject();
948            fail("Unexpected read of corrupted stream");
949        } catch (StreamCorruptedException e) {
950            // Expected
951        }
952    }
953
954    /**
955     * java.io.ObjectInputStream#readShort()
956     */
957    public void test_readShort() throws IOException {
958        oos.writeShort(Short.MAX_VALUE);
959        oos.close();
960        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
961        assertTrue("Read incorrect short value",
962                ois.readShort() == Short.MAX_VALUE);
963        ois.close();
964    }
965
966    /**
967     * java.io.ObjectInputStream#readUTF()
968     */
969    public void test_readUTF() throws IOException {
970        oos.writeUTF("HelloWorld");
971        oos.close();
972        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
973        assertEquals("Read incorrect utf value", "HelloWorld", ois.readUTF());
974        ois.close();
975    }
976
977    /**
978     * java.io.ObjectInputStream#skipBytes(int)
979     */
980    public void test_skipBytesI() throws IOException {
981        byte[] buf = new byte[10];
982        oos.writeBytes("HelloWorld");
983        oos.close();
984        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
985        ois.skipBytes(5);
986        ois.read(buf, 0, 5);
987        ois.close();
988        assertEquals("Skipped incorrect bytes", "World", new String(buf, 0, 5, "UTF-8"));
989
990        // Regression for HARMONY-844
991        try {
992            new ObjectInputStream() {
993            }.skipBytes(0);
994            fail("NullPointerException expected");
995        } catch (NullPointerException e) {
996        }
997    }
998
999    // Regression Test for JIRA 2192
1000    public void test_readObject_withPrimitiveClass() throws Exception {
1001        File file = File.createTempFile("ObjectInputStreamTest", ".ser");
1002        Test test = new Test();
1003        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
1004                file));
1005        out.writeObject(test);
1006        out.close();
1007
1008        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
1009        Test another = (Test) in.readObject();
1010        in.close();
1011        assertEquals(test, another);
1012    }
1013
1014    //Regression Test for JIRA-2249
1015    public static class ObjectOutputStreamWithWriteDesc extends
1016            ObjectOutputStream {
1017        public ObjectOutputStreamWithWriteDesc(OutputStream os)
1018                throws IOException {
1019            super(os);
1020        }
1021
1022        @Override
1023        public void writeClassDescriptor(ObjectStreamClass desc)
1024                throws IOException {
1025        }
1026    }
1027
1028    // Regression Test for JIRA-2340
1029    public static class ObjectOutputStreamWithWriteDesc1 extends
1030            ObjectOutputStream {
1031        public ObjectOutputStreamWithWriteDesc1(OutputStream os)
1032                throws IOException {
1033            super(os);
1034        }
1035
1036        @Override
1037        public void writeClassDescriptor(ObjectStreamClass desc)
1038                throws IOException {
1039            super.writeClassDescriptor(desc);
1040        }
1041    }
1042
1043    public static class ObjectInputStreamWithReadDesc1 extends
1044            ObjectInputStream {
1045
1046        public ObjectInputStreamWithReadDesc1(InputStream is)
1047                throws IOException {
1048            super(is);
1049        }
1050
1051        @Override
1052        public ObjectStreamClass readClassDescriptor() throws IOException,
1053                ClassNotFoundException {
1054            return super.readClassDescriptor();
1055        }
1056    }
1057
1058    // Regression test for Harmony-1921
1059    public static class ObjectInputStreamWithResolve extends ObjectInputStream {
1060        public ObjectInputStreamWithResolve(InputStream in) throws IOException {
1061            super(in);
1062        }
1063
1064        @Override
1065        @SuppressWarnings("unchecked")
1066        protected Class resolveClass(ObjectStreamClass desc)
1067                throws IOException, ClassNotFoundException {
1068            if (desc.getName().equals(
1069                    "org.apache.harmony.luni.tests.pkg1.TestClass")) {
1070                return org.apache.harmony.luni.tests.pkg2.TestClass.class;
1071            }
1072            return super.resolveClass(desc);
1073        }
1074    }
1075
1076    public void test_resolveClass() throws Exception {
1077        org.apache.harmony.luni.tests.pkg1.TestClass to1 = new org.apache.harmony.luni.tests.pkg1.TestClass();
1078        to1.i = 555;
1079        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1080        ObjectOutputStream oos = new ObjectOutputStream(baos);
1081        oos.writeObject(to1);
1082        oos.flush();
1083        byte[] bytes = baos.toByteArray();
1084        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1085        ObjectInputStream ois = new ObjectInputStreamWithResolve(bais);
1086        org.apache.harmony.luni.tests.pkg2.TestClass to2 = (org.apache.harmony.luni.tests.pkg2.TestClass) ois
1087                .readObject();
1088
1089        if (to2.i != to1.i) {
1090            fail("Wrong object read. Expected val: " + to1.i + ", got: "
1091                    + to2.i);
1092        }
1093    }
1094
1095    static class ObjectInputStreamWithResolveObject extends ObjectInputStream {
1096
1097        public static Integer intObj = Integer.valueOf(1000);
1098
1099        public ObjectInputStreamWithResolveObject(InputStream in) throws IOException {
1100            super(in);
1101            enableResolveObject(true);
1102        }
1103
1104        @Override
1105        protected Object resolveObject(Object obj) throws IOException {
1106            if (obj instanceof Integer) {
1107                obj = intObj;
1108            }
1109            return super.resolveObject(obj);
1110        }
1111    }
1112
1113    /**
1114     * java.io.ObjectInputStream#resolveObject(Object)
1115     */
1116    public void test_resolveObjectLjava_lang_Object() throws Exception {
1117        // Write an Integer object into memory
1118        Integer original = new Integer(10);
1119        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1120        ObjectOutputStream oos = new ObjectOutputStream(baos);
1121        oos.writeObject(original);
1122        oos.flush();
1123        oos.close();
1124
1125        // Read the object from memory
1126        byte[] bytes = baos.toByteArray();
1127        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1128        ObjectInputStreamWithResolveObject ois =
1129                new ObjectInputStreamWithResolveObject(bais);
1130        Integer actual = (Integer) ois.readObject();
1131        ois.close();
1132
1133        // object should be resolved from 10 to 1000
1134        assertEquals(ObjectInputStreamWithResolveObject.intObj, actual);
1135    }
1136
1137    public void test_readClassDescriptor() throws IOException,
1138            ClassNotFoundException {
1139
1140        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1141        ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1(
1142                baos);
1143        ObjectStreamClass desc = ObjectStreamClass
1144                .lookup(TestClassForSerialization.class);
1145        oos.writeClassDescriptor(desc);
1146        oos.close();
1147
1148        byte[] bytes = baos.toByteArray();
1149        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1150        ObjectInputStreamWithReadDesc1 ois = new ObjectInputStreamWithReadDesc1(
1151                bais);
1152        Object obj = ois.readClassDescriptor();
1153        ois.close();
1154        assertEquals(desc.getClass(), obj.getClass());
1155
1156        //eof
1157        bais = new ByteArrayInputStream(bytes);
1158        ExceptionalBufferedInputStream bis = new ExceptionalBufferedInputStream(
1159                bais);
1160        ois = new ObjectInputStreamWithReadDesc1(bis);
1161
1162        bis.setEOF(true);
1163
1164        try {
1165            obj = ois.readClassDescriptor();
1166        } catch (IOException e) {
1167            //e.printStackTrace();
1168        } finally {
1169            ois.close();
1170        }
1171
1172        //throw exception
1173        bais = new ByteArrayInputStream(bytes);
1174        bis = new ExceptionalBufferedInputStream(bais);
1175        ois = new ObjectInputStreamWithReadDesc1(bis);
1176
1177        bis.setException(new IOException());
1178
1179        try {
1180            obj = ois.readClassDescriptor();
1181        } catch (IOException e) {
1182            //e.printStackTrace();
1183        } finally {
1184            ois.close();
1185        }
1186
1187        //corrupt
1188        bais = new ByteArrayInputStream(bytes);
1189        bis = new ExceptionalBufferedInputStream(bais);
1190        ois = new ObjectInputStreamWithReadDesc1(bis);
1191
1192        bis.setCorrupt(true);
1193
1194        try {
1195            obj = ois.readClassDescriptor();
1196        } catch (IOException e) {
1197            //e.printStackTrace();
1198        } finally {
1199            ois.close();
1200        }
1201    }
1202
1203    static class ExceptionalBufferedInputStream extends BufferedInputStream {
1204        private boolean eof = false;
1205        private IOException exception = null;
1206        private boolean corrupt = false;
1207
1208        public ExceptionalBufferedInputStream(InputStream in) {
1209            super(in);
1210        }
1211
1212        @Override
1213        public int read() throws IOException {
1214            if (exception != null) {
1215                throw exception;
1216            }
1217
1218            if (eof) {
1219                return -1;
1220            }
1221
1222            if (corrupt) {
1223                return 0;
1224            }
1225            return super.read();
1226        }
1227
1228        public void setEOF(boolean eof) {
1229            this.eof = eof;
1230        }
1231
1232        public void setException(IOException exception) {
1233            this.exception = exception;
1234        }
1235
1236        public void setCorrupt(boolean corrupt) {
1237            this.corrupt = corrupt;
1238        }
1239    }
1240
1241    public static class ObjectIutputStreamWithReadDesc2 extends
1242            ObjectInputStream {
1243        private Class returnClass;
1244
1245        public ObjectIutputStreamWithReadDesc2(InputStream is, Class returnClass)
1246                throws IOException {
1247            super(is);
1248            this.returnClass = returnClass;
1249        }
1250
1251        @Override
1252        public ObjectStreamClass readClassDescriptor() throws IOException,
1253                ClassNotFoundException {
1254            ObjectStreamClass osc = super.readClassDescriptor();
1255
1256            if (osc.getName().equals(returnClass.getName())) {
1257                return ObjectStreamClass.lookup(returnClass);
1258            }
1259            return osc;
1260        }
1261    }
1262
1263    /*
1264     * Testing classDescriptor replacement with the value generated by
1265     * ObjectStreamClass.lookup() method.
1266     * Regression test for HARMONY-4638
1267     */
1268    public void test_readClassDescriptor_1() throws IOException, ClassNotFoundException {
1269        A a = new A();
1270        a.name = "It's a test";
1271        PipedOutputStream pout = new PipedOutputStream();
1272        PipedInputStream pin = new PipedInputStream(pout);
1273        ObjectOutputStream out = new ObjectOutputStream(pout);
1274        ObjectInputStream in = new ObjectIutputStreamWithReadDesc2(pin, A.class);
1275
1276        // test single object
1277        out.writeObject(a);
1278        A a1 = (A) in.readObject();
1279        assertEquals("Single case: incorrectly read the field of A", a.name, a1.name);
1280
1281        // test cyclic reference
1282        HashMap m = new HashMap();
1283        a = new A();
1284        a.name = "It's a test 0";
1285        a1 = new A();
1286        a1.name = "It's a test 1";
1287        m.put("0", a);
1288        m.put("1", a1);
1289        out.writeObject(m);
1290        HashMap m1 = (HashMap) in.readObject();
1291        assertEquals("Incorrectly read the field of A", a.name, ((A) m1.get("0")).name);
1292        assertEquals("Incorrectly read the field of A1", a1.name, ((A) m1.get("1")).name);
1293    }
1294
1295    public void test_registerValidation() throws Exception {
1296        // Regression Test for Harmony-2402
1297        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1298        new ObjectOutputStream(baos);
1299        ObjectInputStream ois = new ObjectInputStream(
1300                new ByteArrayInputStream(baos.toByteArray()));
1301
1302        try {
1303            ois.registerValidation(null, 256);
1304            fail("NotActiveException should be thrown");
1305        } catch (NotActiveException nae) {
1306            // expected
1307        }
1308
1309        // Regression Test for Harmony-3916
1310        baos = new ByteArrayOutputStream();
1311        ObjectOutputStream oos = new ObjectOutputStream(baos);
1312        oos.writeObject(new RegisterValidationClass());
1313        oos.close();
1314        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
1315        ObjectInputStream fis = new ObjectInputStream(bais);
1316        // should not throw NotActiveException
1317        fis.readObject();
1318    }
1319
1320    private static class RegisterValidationClass implements Serializable {
1321        @SuppressWarnings("unused")
1322        private A a = new A();
1323        private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
1324            stream.defaultReadObject();
1325            stream.registerValidation(new MockObjectInputValidation(), 0);
1326        }
1327    }
1328
1329    private static class MockObjectInputValidation implements ObjectInputValidation {
1330        public void validateObject() throws InvalidObjectException {
1331
1332        }
1333    }
1334
1335    //Regression Test for HARMONY-3726
1336    public void test_readObject_array() throws Exception {
1337        final String resourcePrefix = "serialization/org/apache/harmony/luni/tests/java/io";
1338        ObjectInputStream oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
1339                resourcePrefix + "/test_array_strings.ser"));
1340        org.apache.harmony.luni.tests.java.io.TestArray testArray = (TestArray) oin.readObject();
1341        String[] strings = new String[] { "AAA", "BBB" };
1342        assertTrue(java.util.Arrays.equals(strings, testArray.array));
1343
1344        oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
1345                resourcePrefix + "/test_array_integers.ser"));
1346        testArray = (TestArray) oin.readObject();
1347        Integer[] integers = new Integer[] { 10, 20 };
1348        assertTrue(java.util.Arrays.equals(integers, testArray.array));
1349    }
1350
1351    public static class TestExtObject implements Externalizable {
1352        public void writeExternal(ObjectOutput out) throws IOException {
1353            out.writeInt(10);
1354        }
1355
1356        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
1357            in.readInt();
1358        }
1359    }
1360
1361    static class TestObjectOutputStream extends ObjectOutputStream {
1362        private ObjectStreamClass[] objs;
1363        private int pos = 0;
1364
1365        public TestObjectOutputStream(OutputStream out, ObjectStreamClass[] objs) throws IOException {
1366            super(out);
1367            this.objs = objs;
1368        }
1369
1370        @Override
1371        protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException {
1372            objs[pos++] = osc;
1373        }
1374    }
1375
1376    static class TestObjectInputStream extends ObjectInputStream {
1377        private ObjectStreamClass[] objs;
1378        private int pos = 0;
1379
1380        public TestObjectInputStream(InputStream in, ObjectStreamClass[] objs) throws IOException {
1381            super(in);
1382            this.objs = objs;
1383        }
1384
1385        @Override
1386        protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
1387            return objs[pos++];
1388        }
1389    }
1390
1391    // Regression test for HARMONY-4996
1392    public void test_readObject_replacedClassDescriptor() throws Exception {
1393        ObjectStreamClass[] objs = new ObjectStreamClass[1000];
1394        PipedOutputStream pout = new PipedOutputStream();
1395        PipedInputStream pin = new PipedInputStream(pout);
1396        ObjectOutputStream oout = new TestObjectOutputStream(pout, objs);
1397        oout.writeObject(new TestExtObject());
1398        oout.writeObject("test");
1399        oout.close();
1400        ObjectInputStream oin = new TestObjectInputStream(pin, objs);
1401        oin.readObject();
1402        oin.readObject();
1403    }
1404
1405    public void test_readObject_replacedClassField() throws Exception {
1406        ByteArrayOutputStream out = new ByteArrayOutputStream();
1407        ObjectOutputStream oos = new ObjectOutputStream(out);
1408        FieldReplacementTestClass obj = new FieldReplacementTestClass(1234);
1409        oos.writeObject(obj);
1410        out.flush();
1411        out.close();
1412
1413        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
1414        ObjectInputStream ois = new ObjectInputStream(in);
1415
1416        try {
1417            FieldReplacementTestClass result =
1418                    (FieldReplacementTestClass) ois.readObject();
1419            fail("should throw ClassCastException");
1420        } catch (ClassCastException e) {
1421            // expected
1422        }
1423        ois.close();
1424    }
1425
1426    /**
1427     * Sets up the fixture, for example, open a network connection. This method
1428     * is called before a test is executed.
1429     */
1430    @Override
1431    protected void setUp() throws Exception {
1432        super.setUp();
1433        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1434    }
1435
1436    public static class FieldReplacementTestClass implements Serializable {
1437        private FieldClass c;
1438
1439        public FieldReplacementTestClass(int i) {
1440            super();
1441            c = new FieldClass(i);
1442        }
1443    }
1444
1445    public static class FieldClass implements Serializable {
1446        private int i;
1447
1448        public FieldClass(int i) {
1449            super();
1450            this.i = i;
1451        }
1452
1453        protected Object writeReplace() throws ObjectStreamException {
1454            return new ReplacementFieldClass(i);
1455        }
1456    }
1457
1458    public static class ReplacementFieldClass implements Serializable {
1459        private int i;
1460
1461        public ReplacementFieldClass(int i) {
1462            super();
1463            this.i = i;
1464        }
1465    }
1466}
1467
1468class TestArray implements Serializable {
1469    private static final long serialVersionUID = 1L;
1470
1471    public Object[] array;
1472
1473    public TestArray(Object[] array) {
1474        this.array = array;
1475    }
1476}
1477
1478class Test implements Serializable {
1479    private static final long serialVersionUID = 1L;
1480
1481    Class<?> classes[] = new Class[] { byte.class, short.class, int.class,
1482            long.class, boolean.class, char.class, float.class, double.class };
1483
1484    @Override
1485    public boolean equals(Object o) {
1486        if (!(o instanceof Test)) {
1487            return false;
1488        }
1489        return Arrays.equals(classes, ((Test) o).classes);
1490    }
1491}
1492