aboutsummaryrefslogtreecommitdiff
path: root/src/test/test/javassist/proxy/ProxySerializationTest.java
blob: 39d94f7ecb25e70def85073d7a0e4b55553232f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package test.javassist.proxy;

import javassist.util.proxy.*;
import junit.framework.TestCase;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Test to ensure that serialization and deserialization of javassist proxies via
 * {@link javassist.util.proxy.ProxyObjectOutputStream} and  @link javassist.util.proxy.ProxyObjectInputStream}
 * reuses classes located in the proxy cache. This tests the fixes provided for JASSIST-42 and JASSIST-97.
 */
@SuppressWarnings({"rawtypes","unchecked","unused","resource"})
public class ProxySerializationTest extends TestCase
{
    public void testSerialization()
    {
        ProxyFactory factory = new ProxyFactory();
        factory.setSuperclass(TestClass.class);
        factory.setInterfaces(new Class[] {TestInterface.class});

        factory.setUseWriteReplace(true);
        Class proxyClass = factory.createClass(new TestFilter());

        MethodHandler handler = new TestHandler();

        // first try serialization using writeReplace

        try {
            String name = "proxytest_1";
            Constructor constructor = proxyClass.getConstructor(new Class[] {String.class});
            TestClass proxy = (TestClass)constructor.newInstance(new Object[] {name});
            ((ProxyObject)proxy).setHandler(handler);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bos);
            out.writeObject(proxy);
            out.close();
            byte[] bytes = bos.toByteArray();
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream in = new ObjectInputStream(bis);
            TestClass newProxy = (TestClass)in.readObject();
            // inherited fields should not have been deserialized
            assertTrue("new name should be null", newProxy.getName() == null);
            // since we are reading into the same JVM the new proxy should have the same class as the old proxy
            assertTrue("classes should be equal", newProxy.getClass() == proxy.getClass());
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }

        // second try serialization using proxy object output/input streams

        factory.setUseWriteReplace(false);
        proxyClass = factory.createClass(new TestFilter());

        try {
            String name = "proxytest_2";
            Constructor constructor = proxyClass.getConstructor(new Class[] {String.class});
            TestClass proxy = (TestClass)constructor.newInstance(new Object[] {name});
            ((ProxyObject)proxy).setHandler(handler);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ProxyObjectOutputStream out = new ProxyObjectOutputStream(bos);
            out.writeObject(proxy);
            out.close();
            byte[] bytes = bos.toByteArray();
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ProxyObjectInputStream in = new ProxyObjectInputStream(bis);
            TestClass newProxy = (TestClass)in.readObject();
            // inherited fields should have been deserialized
            assertTrue("names should be equal", proxy.getName().equals(newProxy.getName()));
            // since we are reading into the same JVM the new proxy should have the same class as the old proxy
            assertTrue("classes should still be equal", newProxy.getClass() == proxy.getClass());
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    public static class TestFilter implements MethodFilter, Serializable
    {
        /** default serialVersionUID */
        private static final long serialVersionUID = 1L;

        public boolean isHandled(Method m) {
            if (m.getName().equals("getName")) {
                return true;
            }
            return false;
        }

        public boolean equals(Object o)
        {
            if (o instanceof TestFilter) {
                // all test filters are equal
                return true;
            }

            return false;
        }

        public int hashCode()
        {
            return TestFilter.class.hashCode();
        }
    }

    public static class TestHandler implements MethodHandler, Serializable
    {
        /** default serialVersionUID */
        private static final long serialVersionUID = 1L;

        public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
        {
            return proceed.invoke(self, args);
        }
        public boolean equals(Object o)
        {
            if (o instanceof TestHandler) {
                // all test handlers are equal
                return true;
            }

            return false;
        }

        public int hashCode()
        {
            return TestHandler.class.hashCode();
        }
    }

    public static class TestClass implements Serializable
    {
        /** default serialVersionUID */
        private static final long serialVersionUID = 1L;
        public String name;

        public TestClass()
        {
        }

        public TestClass(String name)
        {
            this.name = name;
        }

        public String getName()
        {
            return name;
        }
    }

    public static interface TestInterface
    {
        public String getName();
    }
}