1 package test.javassist.proxy; 2 3 import javassist.util.proxy.*; 4 import junit.framework.TestCase; 5 6 import java.io.*; 7 import java.lang.reflect.Constructor; 8 import java.lang.reflect.InvocationTargetException; 9 import java.lang.reflect.Method; 10 11 /** 12 * Test to ensure that serialization and deserialization of javassist proxies via 13 * {@link javassist.util.proxy.ProxyObjectOutputStream} and @link javassist.util.proxy.ProxyObjectInputStream} 14 * reuses classes located in the proxy cache. This tests the fixes provided for JASSIST-42 and JASSIST-97. 15 */ 16 @SuppressWarnings({"rawtypes","unchecked","unused","resource"}) 17 public class ProxySerializationTest extends TestCase 18 { testSerialization()19 public void testSerialization() 20 { 21 ProxyFactory factory = new ProxyFactory(); 22 factory.setSuperclass(TestClass.class); 23 factory.setInterfaces(new Class[] {TestInterface.class}); 24 25 factory.setUseWriteReplace(true); 26 Class proxyClass = factory.createClass(new TestFilter()); 27 28 MethodHandler handler = new TestHandler(); 29 30 // first try serialization using writeReplace 31 32 try { 33 String name = "proxytest_1"; 34 Constructor constructor = proxyClass.getConstructor(new Class[] {String.class}); 35 TestClass proxy = (TestClass)constructor.newInstance(new Object[] {name}); 36 ((ProxyObject)proxy).setHandler(handler); 37 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 38 ObjectOutputStream out = new ObjectOutputStream(bos); 39 out.writeObject(proxy); 40 out.close(); 41 byte[] bytes = bos.toByteArray(); 42 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 43 ObjectInputStream in = new ObjectInputStream(bis); 44 TestClass newProxy = (TestClass)in.readObject(); 45 // inherited fields should not have been deserialized 46 assertTrue("new name should be null", newProxy.getName() == null); 47 // since we are reading into the same JVM the new proxy should have the same class as the old proxy 48 assertTrue("classes should be equal", newProxy.getClass() == proxy.getClass()); 49 } catch (Exception e) { 50 e.printStackTrace(); 51 fail(); 52 } 53 54 // second try serialization using proxy object output/input streams 55 56 factory.setUseWriteReplace(false); 57 proxyClass = factory.createClass(new TestFilter()); 58 59 try { 60 String name = "proxytest_2"; 61 Constructor constructor = proxyClass.getConstructor(new Class[] {String.class}); 62 TestClass proxy = (TestClass)constructor.newInstance(new Object[] {name}); 63 ((ProxyObject)proxy).setHandler(handler); 64 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 65 ProxyObjectOutputStream out = new ProxyObjectOutputStream(bos); 66 out.writeObject(proxy); 67 out.close(); 68 byte[] bytes = bos.toByteArray(); 69 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 70 ProxyObjectInputStream in = new ProxyObjectInputStream(bis); 71 TestClass newProxy = (TestClass)in.readObject(); 72 // inherited fields should have been deserialized 73 assertTrue("names should be equal", proxy.getName().equals(newProxy.getName())); 74 // since we are reading into the same JVM the new proxy should have the same class as the old proxy 75 assertTrue("classes should still be equal", newProxy.getClass() == proxy.getClass()); 76 } catch (Exception e) { 77 e.printStackTrace(); 78 fail(); 79 } 80 } 81 82 public static class TestFilter implements MethodFilter, Serializable 83 { 84 /** default serialVersionUID */ 85 private static final long serialVersionUID = 1L; 86 isHandled(Method m)87 public boolean isHandled(Method m) { 88 if (m.getName().equals("getName")) { 89 return true; 90 } 91 return false; 92 } 93 equals(Object o)94 public boolean equals(Object o) 95 { 96 if (o instanceof TestFilter) { 97 // all test filters are equal 98 return true; 99 } 100 101 return false; 102 } 103 hashCode()104 public int hashCode() 105 { 106 return TestFilter.class.hashCode(); 107 } 108 } 109 110 public static class TestHandler implements MethodHandler, Serializable 111 { 112 /** default serialVersionUID */ 113 private static final long serialVersionUID = 1L; 114 invoke(Object self, Method thisMethod, Method proceed, Object[] args)115 public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable 116 { 117 return proceed.invoke(self, args); 118 } equals(Object o)119 public boolean equals(Object o) 120 { 121 if (o instanceof TestHandler) { 122 // all test handlers are equal 123 return true; 124 } 125 126 return false; 127 } 128 hashCode()129 public int hashCode() 130 { 131 return TestHandler.class.hashCode(); 132 } 133 } 134 135 public static class TestClass implements Serializable 136 { 137 /** default serialVersionUID */ 138 private static final long serialVersionUID = 1L; 139 public String name; 140 TestClass()141 public TestClass() 142 { 143 } 144 TestClass(String name)145 public TestClass(String name) 146 { 147 this.name = name; 148 } 149 getName()150 public String getName() 151 { 152 return name; 153 } 154 } 155 156 public static interface TestInterface 157 { getName()158 public String getName(); 159 } 160 } 161