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() throws an IOException
412        // if there is an input stream.
413        bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
414        try {
415            bois.readObjectOverride();
416            fail("Test 2: IOException expected.");
417        } catch (IOException e) {}
418
419        bois.close();
420    }
421
422    public void test_readObjectMissingClasses() throws Exception {
423        SerializationTest.verifySelf(new A1(), new SerializableAssert() {
424            public void assertDeserialized(Serializable initial,
425                    Serializable deserialized) {
426                assertEquals(5, ((A1) deserialized).b1.i);
427            }
428        });
429    }
430
431    public void test_readStreamHeader() throws IOException {
432        String testString = "Lorem ipsum";
433        BasicObjectInputStream bois;
434        short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
435        short version = java.io.ObjectStreamConstants.STREAM_VERSION;
436        byte[] buffer = new byte[20];
437
438        // Initialize the buffer with the correct header for object streams
439        fillStreamHeader(buffer);
440        System.arraycopy(testString.getBytes(), 0, buffer, 4, testString.length());
441
442        // Test 1: readStreamHeader should not throw a StreamCorruptedException.
443        // It should get called by the ObjectInputStream constructor.
444        try {
445            readStreamHeaderCalled = false;
446            bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
447            bois.close();
448        } catch (StreamCorruptedException e) {
449            fail("Test 1: Unexpected StreamCorruptedException.");
450        }
451        assertTrue("Test 1: readStreamHeader() has not been called.",
452                    readStreamHeaderCalled);
453
454        // Test 2: Make the stream magic number invalid and check that
455        // readStreamHeader() throws an exception.
456        buffer[0] = (byte)magic;
457        buffer[1] = (byte)(magic >> 8);
458        try {
459            readStreamHeaderCalled = false;
460            bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
461            fail("Test 2: StreamCorruptedException expected.");
462            bois.close();
463        } catch (StreamCorruptedException e) {
464        }
465        assertTrue("Test 2: readStreamHeader() has not been called.",
466                    readStreamHeaderCalled);
467
468        // Test 3: Make the stream version invalid and check that
469        // readStreamHeader() throws an exception.
470        buffer[0] = (byte)(magic >> 8);
471        buffer[1] = (byte)magic;
472        buffer[2] = (byte)(version);
473        buffer[3] = (byte)(version >> 8);
474        try {
475            readStreamHeaderCalled = false;
476            bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
477            fail("Test 3: StreamCorruptedException expected.");
478            bois.close();
479        } catch (StreamCorruptedException e) {
480        }
481        assertTrue("Test 3: readStreamHeader() has not been called.",
482                    readStreamHeaderCalled);
483    }
484
485    public void test_readUnsignedByte() throws IOException {
486        oos.writeByte(-1);
487        oos.close();
488
489        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
490        assertEquals("Test 1: Incorrect unsigned byte written or read.",
491                255, ois.readUnsignedByte());
492
493        try {
494            ois.readUnsignedByte();
495            fail("Test 2: EOFException expected.");
496        } catch (EOFException e) {
497            // Expected.
498        }
499
500        ois.close();
501        try {
502            ois.readUnsignedByte();
503            fail("Test 3: IOException expected.");
504        } catch (IOException e) {
505            // Expected.
506        }
507    }
508
509    public void test_readUnsignedShort() throws IOException {
510        // Test for method int java.io.ObjectInputStream.readUnsignedShort()
511        oos.writeShort(-1);
512        oos.close();
513
514        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
515        assertEquals("Test 1: Incorrect unsigned short written or read.",
516                65535, ois.readUnsignedShort());
517
518        try {
519            ois.readUnsignedShort();
520            fail("Test 2: EOFException expected.");
521        } catch (EOFException e) {
522            // Expected.
523        }
524
525        ois.close();
526        try {
527            ois.readUnsignedShort();
528            fail("Test 3: IOException expected.");
529        } catch (IOException e) {
530            // Expected.
531        }
532    }
533
534    public void test_skipBytesI_IOException() throws IOException {
535        oos.writeObject(testString);
536        oos.close();
537
538        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
539        ois = new ObjectInputStream(sis);
540        sis.throwExceptionOnNextUse = true;
541        try {
542            ois.skipBytes(5);
543            fail("Test 1: IOException expected.");
544        } catch (IOException e) {
545            // Expected.
546        }
547        sis.throwExceptionOnNextUse = false;
548        ois.close();
549    }
550
551    public static class A implements Serializable {
552
553        private static final long serialVersionUID = 11L;
554
555        public String name = "name";
556    }
557
558    public static class B extends A {}
559
560    public static class C extends B {
561
562        private static final long serialVersionUID = 33L;
563    }
564
565    class BasicObjectInputStream extends ObjectInputStream {
566        public BasicObjectInputStream() throws IOException, SecurityException {
567            super();
568        }
569
570        public BasicObjectInputStream(InputStream input) throws IOException {
571            super(input);
572        }
573
574        public boolean enableResolveObject(boolean enable)
575                throws SecurityException {
576            return super.enableResolveObject(enable);
577        }
578
579        public Object readObjectOverride() throws ClassNotFoundException, IOException {
580            return super.readObjectOverride();
581        }
582
583        public void readStreamHeader() throws IOException {
584            readStreamHeaderCalled = true;
585            super.readStreamHeader();
586        }
587
588        public Class<?> resolveProxyClass(String[] interfaceNames)
589                throws IOException, ClassNotFoundException {
590            return super.resolveProxyClass(interfaceNames);
591        }
592    }
593
594    public static class ObjectInputStreamWithReadDesc extends
595            ObjectInputStream {
596        private Class returnClass;
597
598        public ObjectInputStreamWithReadDesc(InputStream is, Class returnClass)
599                throws IOException {
600            super(is);
601            this.returnClass = returnClass;
602        }
603
604        public ObjectStreamClass readClassDescriptor() throws IOException,
605                ClassNotFoundException {
606            return ObjectStreamClass.lookup(returnClass);
607
608        }
609    }
610
611    static class TestClassForSerialization implements Serializable {
612        private static final long serialVersionUID = 1L;
613    }
614
615    public void test_ConstructorLjava_io_InputStream() throws IOException {
616        oos.writeDouble(Double.MAX_VALUE);
617        oos.close();
618        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
619        ois.close();
620        oos.close();
621
622        try {
623            ois = new ObjectInputStream(new ByteArrayInputStream(new byte[90]));
624            fail("StreamCorruptedException expected");
625        } catch (StreamCorruptedException e) {
626            // Expected
627        }
628    }
629
630    /**
631     * {@link java.io.ObjectInputStream#resolveProxyClass(String[])}
632     */
633    public void test_resolveProxyClass() throws IOException,
634            ClassNotFoundException {
635        oos.writeBytes("HelloWorld");
636        oos.close();
637        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
638        MockObjectInputStream mockIn = new MockObjectInputStream(
639                new ByteArrayInputStream(bao.toByteArray()));
640        Class[] clazzs = { java.io.ObjectInputStream.class,
641                java.io.Reader.class };
642        for (int i = 0; i < clazzs.length; i++) {
643            Class clazz = clazzs[i];
644            Class[] interfaceNames = clazz.getInterfaces();
645            String[] interfaces = new String[interfaceNames.length];
646            int index = 0;
647            for (Class c : interfaceNames) {
648                interfaces[index] = c.getName();
649                index++;
650            }
651            Class<?> s = mockIn.resolveProxyClass(interfaces);
652
653            if (Proxy.isProxyClass(s)) {
654                Class[] implementedInterfaces = s.getInterfaces();
655                for (index = 0; index < implementedInterfaces.length; index++) {
656                    assertEquals(interfaceNames[index],
657                            implementedInterfaces[index]);
658                }
659            } else {
660                fail("Should return a proxy class that implements the interfaces named in a proxy class descriptor");
661            }
662        }
663        mockIn.close();
664    }
665
666    class MockObjectInputStream extends ObjectInputStream {
667
668        public MockObjectInputStream(InputStream input)
669                throws StreamCorruptedException, IOException {
670            super(input);
671        }
672
673        @Override
674        public Class<?> resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException {
675            return super.resolveProxyClass(interfaceNames);
676        }
677
678    }
679
680    public void test_available() throws IOException {
681        oos.writeBytes("HelloWorld");
682        oos.close();
683        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
684        assertEquals("Read incorrect bytes", 10, ois.available());
685        ois.close();
686    }
687
688    /**
689     * java.io.ObjectInputStream#defaultReadObject()
690     */
691    public void test_defaultReadObject() throws Exception {
692        // SM. This method may as well be private, as if called directly it
693        // throws an exception.
694        String s = "HelloWorld";
695        oos.writeObject(s);
696        oos.close();
697        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
698        try {
699            ois.defaultReadObject();
700            fail("NotActiveException expected");
701        } catch (NotActiveException e) {
702            // Desired behavior
703        } finally {
704            ois.close();
705        }
706    }
707
708    /**
709     * java.io.ObjectInputStream#read()
710     */
711    public void test_read() throws IOException {
712        oos.write('T');
713        oos.close();
714        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
715        assertEquals("Read incorrect byte value", 'T', ois.read());
716        ois.close();
717    }
718
719    /**
720     * java.io.ObjectInputStream#read(byte[], int, int)
721     */
722    public void test_read$BII() throws IOException {
723        byte[] buf = new byte[10];
724        oos.writeBytes("HelloWorld");
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, "UTF-8"));
731    }
732
733    /**
734     * java.io.ObjectInputStream#readBoolean()
735     */
736    public void test_readBoolean() throws IOException {
737        oos.writeBoolean(true);
738        oos.close();
739        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
740        assertTrue("Read incorrect boolean value", ois.readBoolean());
741        ois.close();
742    }
743
744    /**
745     * java.io.ObjectInputStream#readByte()
746     */
747    public void test_readByte() throws IOException {
748        oos.writeByte(127);
749        oos.close();
750        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
751        assertEquals("Read incorrect byte value", 127, ois.readByte());
752        ois.close();
753    }
754
755    /**
756     * java.io.ObjectInputStream#readChar()
757     */
758    public void test_readChar() throws IOException {
759        oos.writeChar('T');
760        oos.close();
761        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
762        assertEquals("Read incorrect char value", 'T', ois.readChar());
763        ois.close();
764    }
765
766    /**
767     * java.io.ObjectInputStream#readDouble()
768     */
769    public void test_readDouble() throws IOException {
770        oos.writeDouble(Double.MAX_VALUE);
771        oos.close();
772        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
773        assertTrue("Read incorrect double value",
774                ois.readDouble() == Double.MAX_VALUE);
775        ois.close();
776    }
777
778    /**
779     * java.io.ObjectInputStream#readFields()
780     */
781    public void test_readFields() throws Exception {
782
783        SerializableTestHelper sth;
784
785        /*
786         * "SerializableTestHelper" is an object created for these tests with
787         * two fields (Strings) and simple implementations of readObject and
788         * writeObject which simply read and write the first field but not the
789         * second
790         */
791
792        oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
793        oos.flush();
794        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
795        sth = (SerializableTestHelper) (ois.readObject());
796        assertEquals("readFields / writeFields failed--first field not set",
797                "Gabba", sth.getText1());
798        assertNull(
799                "readFields / writeFields failed--second field should not have been set",
800                sth.getText2());
801    }
802
803    /**
804     * java.io.ObjectInputStream#readFloat()
805     */
806    public void test_readFloat() throws IOException {
807        oos.writeFloat(Float.MAX_VALUE);
808        oos.close();
809        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
810        assertTrue("Read incorrect float value",
811                ois.readFloat() == Float.MAX_VALUE);
812        ois.close();
813    }
814
815    /**
816     * java.io.ObjectInputStream#readInt()
817     */
818    public void test_readInt() throws IOException {
819        oos.writeInt(Integer.MAX_VALUE);
820        oos.close();
821        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
822        assertTrue("Read incorrect int value",
823                ois.readInt() == Integer.MAX_VALUE);
824        ois.close();
825    }
826
827    /**
828     * java.io.ObjectInputStream#readLine()
829     */
830    @SuppressWarnings("deprecation")
831    public void test_readLine() throws IOException {
832        oos.writeBytes("HelloWorld\nSecondLine");
833        oos.close();
834        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
835        ois.readLine();
836        assertEquals("Read incorrect string value", "SecondLine", ois
837                .readLine());
838        ois.close();
839    }
840
841    /**
842     * java.io.ObjectInputStream#readLong()
843     */
844    public void test_readLong() throws IOException {
845        oos.writeLong(Long.MAX_VALUE);
846        oos.close();
847        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
848        assertTrue("Read incorrect long value",
849                ois.readLong() == Long.MAX_VALUE);
850        ois.close();
851    }
852
853    /**
854     * java.io.ObjectInputStream#readObject()
855     */
856    public void test_readObject() throws Exception {
857        String s = "HelloWorld";
858        oos.writeObject(s);
859        oos.close();
860        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
861        assertEquals("Read incorrect Object value", s, ois.readObject());
862        ois.close();
863
864        // Regression for HARMONY-91
865        // dynamically create serialization byte array for the next hierarchy:
866        // - class A implements Serializable
867        // - class C extends A
868
869        byte[] cName = C.class.getName().getBytes("UTF-8");
870        byte[] aName = A.class.getName().getBytes("UTF-8");
871
872        ByteArrayOutputStream out = new ByteArrayOutputStream();
873
874        byte[] begStream = new byte[] { (byte) 0xac, (byte) 0xed, // STREAM_MAGIC
875                (byte) 0x00, (byte) 0x05, // STREAM_VERSION
876                (byte) 0x73, // TC_OBJECT
877                (byte) 0x72, // TC_CLASSDESC
878                (byte) 0x00, // only first byte for C class name length
879        };
880
881        out.write(begStream, 0, begStream.length);
882        out.write(cName.length); // second byte for C class name length
883        out.write(cName, 0, cName.length); // C class name
884
885        byte[] midStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
886                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
887                (byte) 0x21, // serialVersionUID = 33L
888                (byte) 0x02, // flags
889                (byte) 0x00, (byte) 0x00, // fields : none
890                (byte) 0x78, // TC_ENDBLOCKDATA
891                (byte) 0x72, // Super class for C: TC_CLASSDESC for A class
892                (byte) 0x00, // only first byte for A class name length
893        };
894
895        out.write(midStream, 0, midStream.length);
896        out.write(aName.length); // second byte for A class name length
897        out.write(aName, 0, aName.length); // A class name
898
899        byte[] endStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
900                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
901                (byte) 0x0b, // serialVersionUID = 11L
902                (byte) 0x02, // flags
903                (byte) 0x00, (byte) 0x01, // fields
904
905                (byte) 0x4c, // field description: type L (object)
906                (byte) 0x00, (byte) 0x04, // length
907                // field = 'name'
908                (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65,
909
910                (byte) 0x74, // className1: TC_STRING
911                (byte) 0x00, (byte) 0x12, // length
912                //
913                (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
914                (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
915                (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53,
916                (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e,
917                (byte) 0x67, (byte) 0x3b,
918
919                (byte) 0x78, // TC_ENDBLOCKDATA
920                (byte) 0x70, // NULL super class for A class
921
922                // classdata
923                (byte) 0x74, // TC_STRING
924                (byte) 0x00, (byte) 0x04, // length
925                (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, // value
926        };
927
928        out.write(endStream, 0, endStream.length);
929        out.flush();
930
931        // read created serial. form
932        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
933                out.toByteArray()));
934        Object o = ois.readObject();
935        assertEquals(C.class, o.getClass());
936
937		// Regression for HARMONY-846
938        assertNull(new ObjectInputStream() {}.readObject());
939    }
940
941    /**
942     * java.io.ObjectInputStream#readObject()
943     */
944    public void test_readObjectCorrupt() throws IOException, ClassNotFoundException {
945        byte[] bytes = { 00, 00, 00, 0x64, 0x43, 0x48, (byte) 0xFD, 0x71, 00,
946                00, 0x0B, (byte) 0xB8, 0x4D, 0x65 };
947        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
948        try {
949            ObjectInputStream in = new ObjectInputStream(bin);
950            in.readObject();
951            fail("Unexpected read of corrupted stream");
952        } catch (StreamCorruptedException e) {
953            // Expected
954        }
955    }
956
957    /**
958     * java.io.ObjectInputStream#readShort()
959     */
960    public void test_readShort() throws IOException {
961        oos.writeShort(Short.MAX_VALUE);
962        oos.close();
963        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
964        assertTrue("Read incorrect short value",
965                ois.readShort() == Short.MAX_VALUE);
966        ois.close();
967    }
968
969    /**
970     * java.io.ObjectInputStream#readUTF()
971     */
972    public void test_readUTF() throws IOException {
973        oos.writeUTF("HelloWorld");
974        oos.close();
975        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
976        assertEquals("Read incorrect utf value", "HelloWorld", ois.readUTF());
977        ois.close();
978    }
979
980    /**
981     * java.io.ObjectInputStream#skipBytes(int)
982     */
983    public void test_skipBytesI() throws IOException {
984        byte[] buf = new byte[10];
985        oos.writeBytes("HelloWorld");
986        oos.close();
987        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
988        ois.skipBytes(5);
989        ois.read(buf, 0, 5);
990        ois.close();
991        assertEquals("Skipped incorrect bytes", "World", new String(buf, 0, 5, "UTF-8"));
992
993        // Regression for HARMONY-844
994        try {
995            new ObjectInputStream() {
996            }.skipBytes(0);
997            fail("NullPointerException expected");
998        } catch (NullPointerException e) {
999        }
1000    }
1001
1002    // Regression Test for JIRA 2192
1003    public void test_readObject_withPrimitiveClass() throws Exception {
1004        File file = File.createTempFile("ObjectInputStreamTest", ".ser");
1005        Test test = new Test();
1006        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
1007                file));
1008        out.writeObject(test);
1009        out.close();
1010
1011        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
1012        Test another = (Test) in.readObject();
1013        in.close();
1014        assertEquals(test, another);
1015    }
1016
1017    //Regression Test for JIRA-2249
1018    public static class ObjectOutputStreamWithWriteDesc extends
1019            ObjectOutputStream {
1020        public ObjectOutputStreamWithWriteDesc(OutputStream os)
1021                throws IOException {
1022            super(os);
1023        }
1024
1025        @Override
1026        public void writeClassDescriptor(ObjectStreamClass desc)
1027                throws IOException {
1028        }
1029    }
1030
1031    // Regression Test for JIRA-2340
1032    public static class ObjectOutputStreamWithWriteDesc1 extends
1033            ObjectOutputStream {
1034        public ObjectOutputStreamWithWriteDesc1(OutputStream os)
1035                throws IOException {
1036            super(os);
1037        }
1038
1039        @Override
1040        public void writeClassDescriptor(ObjectStreamClass desc)
1041                throws IOException {
1042            super.writeClassDescriptor(desc);
1043        }
1044    }
1045
1046    public static class ObjectInputStreamWithReadDesc1 extends
1047            ObjectInputStream {
1048
1049        public ObjectInputStreamWithReadDesc1(InputStream is)
1050                throws IOException {
1051            super(is);
1052        }
1053
1054        @Override
1055        public ObjectStreamClass readClassDescriptor() throws IOException,
1056                ClassNotFoundException {
1057            return super.readClassDescriptor();
1058        }
1059    }
1060
1061    // Regression test for Harmony-1921
1062    public static class ObjectInputStreamWithResolve extends ObjectInputStream {
1063        public ObjectInputStreamWithResolve(InputStream in) throws IOException {
1064            super(in);
1065        }
1066
1067        @Override
1068        @SuppressWarnings("unchecked")
1069        protected Class resolveClass(ObjectStreamClass desc)
1070                throws IOException, ClassNotFoundException {
1071            if (desc.getName().equals(
1072                    "org.apache.harmony.luni.tests.pkg1.TestClass")) {
1073                return org.apache.harmony.luni.tests.pkg2.TestClass.class;
1074            }
1075            return super.resolveClass(desc);
1076        }
1077    }
1078
1079    public void test_resolveClass() throws Exception {
1080        org.apache.harmony.luni.tests.pkg1.TestClass to1 = new org.apache.harmony.luni.tests.pkg1.TestClass();
1081        to1.i = 555;
1082        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1083        ObjectOutputStream oos = new ObjectOutputStream(baos);
1084        oos.writeObject(to1);
1085        oos.flush();
1086        byte[] bytes = baos.toByteArray();
1087        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1088        ObjectInputStream ois = new ObjectInputStreamWithResolve(bais);
1089        org.apache.harmony.luni.tests.pkg2.TestClass to2 = (org.apache.harmony.luni.tests.pkg2.TestClass) ois
1090                .readObject();
1091
1092        if (to2.i != to1.i) {
1093            fail("Wrong object read. Expected val: " + to1.i + ", got: "
1094                    + to2.i);
1095        }
1096    }
1097
1098    static class ObjectInputStreamWithResolveObject extends ObjectInputStream {
1099
1100        public static Integer intObj = Integer.valueOf(1000);
1101
1102        public ObjectInputStreamWithResolveObject(InputStream in) throws IOException {
1103            super(in);
1104            enableResolveObject(true);
1105        }
1106
1107        @Override
1108        protected Object resolveObject(Object obj) throws IOException {
1109            if (obj instanceof Integer) {
1110                obj = intObj;
1111            }
1112            return super.resolveObject(obj);
1113        }
1114    }
1115
1116    /**
1117     * java.io.ObjectInputStream#resolveObject(Object)
1118     */
1119    public void test_resolveObjectLjava_lang_Object() throws Exception {
1120        // Write an Integer object into memory
1121        Integer original = new Integer(10);
1122        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1123        ObjectOutputStream oos = new ObjectOutputStream(baos);
1124        oos.writeObject(original);
1125        oos.flush();
1126        oos.close();
1127
1128        // Read the object from memory
1129        byte[] bytes = baos.toByteArray();
1130        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1131        ObjectInputStreamWithResolveObject ois =
1132                new ObjectInputStreamWithResolveObject(bais);
1133        Integer actual = (Integer) ois.readObject();
1134        ois.close();
1135
1136        // object should be resolved from 10 to 1000
1137        assertEquals(ObjectInputStreamWithResolveObject.intObj, actual);
1138    }
1139
1140    public void test_readClassDescriptor() throws IOException,
1141            ClassNotFoundException {
1142
1143        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1144        ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1(
1145                baos);
1146        ObjectStreamClass desc = ObjectStreamClass
1147                .lookup(TestClassForSerialization.class);
1148        oos.writeClassDescriptor(desc);
1149        oos.close();
1150
1151        byte[] bytes = baos.toByteArray();
1152        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1153        ObjectInputStreamWithReadDesc1 ois = new ObjectInputStreamWithReadDesc1(
1154                bais);
1155        Object obj = ois.readClassDescriptor();
1156        ois.close();
1157        assertEquals(desc.getClass(), obj.getClass());
1158
1159        //eof
1160        bais = new ByteArrayInputStream(bytes);
1161        ExceptionalBufferedInputStream bis = new ExceptionalBufferedInputStream(
1162                bais);
1163        ois = new ObjectInputStreamWithReadDesc1(bis);
1164
1165        bis.setEOF(true);
1166
1167        try {
1168            obj = ois.readClassDescriptor();
1169        } catch (IOException e) {
1170            //e.printStackTrace();
1171        } finally {
1172            ois.close();
1173        }
1174
1175        //throw exception
1176        bais = new ByteArrayInputStream(bytes);
1177        bis = new ExceptionalBufferedInputStream(bais);
1178        ois = new ObjectInputStreamWithReadDesc1(bis);
1179
1180        bis.setException(new IOException());
1181
1182        try {
1183            obj = ois.readClassDescriptor();
1184        } catch (IOException e) {
1185            //e.printStackTrace();
1186        } finally {
1187            ois.close();
1188        }
1189
1190        //corrupt
1191        bais = new ByteArrayInputStream(bytes);
1192        bis = new ExceptionalBufferedInputStream(bais);
1193        ois = new ObjectInputStreamWithReadDesc1(bis);
1194
1195        bis.setCorrupt(true);
1196
1197        try {
1198            obj = ois.readClassDescriptor();
1199        } catch (IOException e) {
1200            //e.printStackTrace();
1201        } finally {
1202            ois.close();
1203        }
1204    }
1205
1206    static class ExceptionalBufferedInputStream extends BufferedInputStream {
1207        private boolean eof = false;
1208        private IOException exception = null;
1209        private boolean corrupt = false;
1210
1211        public ExceptionalBufferedInputStream(InputStream in) {
1212            super(in);
1213        }
1214
1215        @Override
1216        public int read() throws IOException {
1217            if (exception != null) {
1218                throw exception;
1219            }
1220
1221            if (eof) {
1222                return -1;
1223            }
1224
1225            if (corrupt) {
1226                return 0;
1227            }
1228            return super.read();
1229        }
1230
1231        public void setEOF(boolean eof) {
1232            this.eof = eof;
1233        }
1234
1235        public void setException(IOException exception) {
1236            this.exception = exception;
1237        }
1238
1239        public void setCorrupt(boolean corrupt) {
1240            this.corrupt = corrupt;
1241        }
1242    }
1243
1244    public static class ObjectIutputStreamWithReadDesc2 extends
1245            ObjectInputStream {
1246        private Class returnClass;
1247
1248        public ObjectIutputStreamWithReadDesc2(InputStream is, Class returnClass)
1249                throws IOException {
1250            super(is);
1251            this.returnClass = returnClass;
1252        }
1253
1254        @Override
1255        public ObjectStreamClass readClassDescriptor() throws IOException,
1256                ClassNotFoundException {
1257            ObjectStreamClass osc = super.readClassDescriptor();
1258
1259            if (osc.getName().equals(returnClass.getName())) {
1260                return ObjectStreamClass.lookup(returnClass);
1261            }
1262            return osc;
1263        }
1264    }
1265
1266    /*
1267     * Testing classDescriptor replacement with the value generated by
1268     * ObjectStreamClass.lookup() method.
1269     * Regression test for HARMONY-4638
1270     */
1271    public void test_readClassDescriptor_1() throws IOException, ClassNotFoundException {
1272        A a = new A();
1273        a.name = "It's a test";
1274        PipedOutputStream pout = new PipedOutputStream();
1275        PipedInputStream pin = new PipedInputStream(pout);
1276        ObjectOutputStream out = new ObjectOutputStream(pout);
1277        ObjectInputStream in = new ObjectIutputStreamWithReadDesc2(pin, A.class);
1278
1279        // test single object
1280        out.writeObject(a);
1281        A a1 = (A) in.readObject();
1282        assertEquals("Single case: incorrectly read the field of A", a.name, a1.name);
1283
1284        // test cyclic reference
1285        HashMap m = new HashMap();
1286        a = new A();
1287        a.name = "It's a test 0";
1288        a1 = new A();
1289        a1.name = "It's a test 1";
1290        m.put("0", a);
1291        m.put("1", a1);
1292        out.writeObject(m);
1293        HashMap m1 = (HashMap) in.readObject();
1294        assertEquals("Incorrectly read the field of A", a.name, ((A) m1.get("0")).name);
1295        assertEquals("Incorrectly read the field of A1", a1.name, ((A) m1.get("1")).name);
1296    }
1297
1298    public void test_registerValidation() throws Exception {
1299        // Regression Test for Harmony-2402
1300        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1301        new ObjectOutputStream(baos);
1302        ObjectInputStream ois = new ObjectInputStream(
1303                new ByteArrayInputStream(baos.toByteArray()));
1304
1305        try {
1306            ois.registerValidation(null, 256);
1307            fail("NotActiveException should be thrown");
1308        } catch (NotActiveException nae) {
1309            // expected
1310        }
1311
1312        // Regression Test for Harmony-3916
1313        baos = new ByteArrayOutputStream();
1314        ObjectOutputStream oos = new ObjectOutputStream(baos);
1315        oos.writeObject(new RegisterValidationClass());
1316        oos.close();
1317        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
1318        ObjectInputStream fis = new ObjectInputStream(bais);
1319        // should not throw NotActiveException
1320        fis.readObject();
1321    }
1322
1323    private static class RegisterValidationClass implements Serializable {
1324        @SuppressWarnings("unused")
1325        private A a = new A();
1326        private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
1327            stream.defaultReadObject();
1328            stream.registerValidation(new MockObjectInputValidation(), 0);
1329        }
1330    }
1331
1332    private static class MockObjectInputValidation implements ObjectInputValidation {
1333        public void validateObject() throws InvalidObjectException {
1334
1335        }
1336    }
1337
1338    //Regression Test for HARMONY-3726
1339    public void test_readObject_array() throws Exception {
1340        final String resourcePrefix = "serialization/org/apache/harmony/luni/tests/java/io";
1341        ObjectInputStream oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
1342                resourcePrefix + "/test_array_strings.ser"));
1343        org.apache.harmony.luni.tests.java.io.TestArray testArray = (TestArray) oin.readObject();
1344        String[] strings = new String[] { "AAA", "BBB" };
1345        assertTrue(java.util.Arrays.equals(strings, testArray.array));
1346
1347        oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
1348                resourcePrefix + "/test_array_integers.ser"));
1349        testArray = (TestArray) oin.readObject();
1350        Integer[] integers = new Integer[] { 10, 20 };
1351        assertTrue(java.util.Arrays.equals(integers, testArray.array));
1352    }
1353
1354    public static class TestExtObject implements Externalizable {
1355        public void writeExternal(ObjectOutput out) throws IOException {
1356            out.writeInt(10);
1357        }
1358
1359        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
1360            in.readInt();
1361        }
1362    }
1363
1364    static class TestObjectOutputStream extends ObjectOutputStream {
1365        private ObjectStreamClass[] objs;
1366        private int pos = 0;
1367
1368        public TestObjectOutputStream(OutputStream out, ObjectStreamClass[] objs) throws IOException {
1369            super(out);
1370            this.objs = objs;
1371        }
1372
1373        @Override
1374        protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException {
1375            objs[pos++] = osc;
1376        }
1377    }
1378
1379    static class TestObjectInputStream extends ObjectInputStream {
1380        private ObjectStreamClass[] objs;
1381        private int pos = 0;
1382
1383        public TestObjectInputStream(InputStream in, ObjectStreamClass[] objs) throws IOException {
1384            super(in);
1385            this.objs = objs;
1386        }
1387
1388        @Override
1389        protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
1390            return objs[pos++];
1391        }
1392    }
1393
1394    // Regression test for HARMONY-4996
1395    public void test_readObject_replacedClassDescriptor() throws Exception {
1396        ObjectStreamClass[] objs = new ObjectStreamClass[1000];
1397        PipedOutputStream pout = new PipedOutputStream();
1398        PipedInputStream pin = new PipedInputStream(pout);
1399        ObjectOutputStream oout = new TestObjectOutputStream(pout, objs);
1400        oout.writeObject(new TestExtObject());
1401        oout.writeObject("test");
1402        oout.close();
1403        ObjectInputStream oin = new TestObjectInputStream(pin, objs);
1404        oin.readObject();
1405        oin.readObject();
1406    }
1407
1408    public void test_readObject_replacedClassField() throws Exception {
1409        ByteArrayOutputStream out = new ByteArrayOutputStream();
1410        ObjectOutputStream oos = new ObjectOutputStream(out);
1411        FieldReplacementTestClass obj = new FieldReplacementTestClass(1234);
1412        oos.writeObject(obj);
1413        out.flush();
1414        out.close();
1415
1416        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
1417        ObjectInputStream ois = new ObjectInputStream(in);
1418
1419        try {
1420            FieldReplacementTestClass result =
1421                    (FieldReplacementTestClass) ois.readObject();
1422            fail("should throw ClassCastException");
1423        } catch (ClassCastException e) {
1424            // expected
1425        }
1426        ois.close();
1427    }
1428
1429    /**
1430     * Sets up the fixture, for example, open a network connection. This method
1431     * is called before a test is executed.
1432     */
1433    @Override
1434    protected void setUp() throws Exception {
1435        super.setUp();
1436        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
1437    }
1438
1439    public static class FieldReplacementTestClass implements Serializable {
1440        private FieldClass c;
1441
1442        public FieldReplacementTestClass(int i) {
1443            super();
1444            c = new FieldClass(i);
1445        }
1446    }
1447
1448    public static class FieldClass implements Serializable {
1449        private int i;
1450
1451        public FieldClass(int i) {
1452            super();
1453            this.i = i;
1454        }
1455
1456        protected Object writeReplace() throws ObjectStreamException {
1457            return new ReplacementFieldClass(i);
1458        }
1459    }
1460
1461    public static class ReplacementFieldClass implements Serializable {
1462        private int i;
1463
1464        public ReplacementFieldClass(int i) {
1465            super();
1466            this.i = i;
1467        }
1468    }
1469}
1470
1471class TestArray implements Serializable {
1472    private static final long serialVersionUID = 1L;
1473
1474    public Object[] array;
1475
1476    public TestArray(Object[] array) {
1477        this.array = array;
1478    }
1479}
1480
1481class Test implements Serializable {
1482    private static final long serialVersionUID = 1L;
1483
1484    Class<?> classes[] = new Class[] { byte.class, short.class, int.class,
1485            long.class, boolean.class, char.class, float.class, double.class };
1486
1487    @Override
1488    public boolean equals(Object o) {
1489        if (!(o instanceof Test)) {
1490            return false;
1491        }
1492        return Arrays.equals(classes, ((Test) o).classes);
1493    }
1494}
1495