169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage test.javassist.proxy; 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.util.proxy.*; 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport junit.framework.TestCase; 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.*; 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.lang.reflect.Constructor; 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.lang.reflect.InvocationTargetException; 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.lang.reflect.Method; 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Test to ensure that serialization and deserialization of javassist proxies via 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * {@link javassist.util.proxy.ProxyObjectOutputStream} and @link javassist.util.proxy.ProxyObjectInputStream} 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * reuses classes located in the proxy cache. This tests the fixes provided for JASSIST-42 and JASSIST-97. 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ProxySerializationTest extends TestCase 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal{ 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void testSerialization() 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProxyFactory factory = new ProxyFactory(); 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setSuperclass(TestClass.class); 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setInterfaces(new Class[] {TestInterface.class}); 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setUseWriteReplace(true); 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class proxyClass = factory.createClass(new TestFilter()); 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MethodHandler handler = new TestHandler(); 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // first try serialization using writeReplace 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name = "proxytest_1"; 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Constructor constructor = proxyClass.getConstructor(new Class[] {String.class}); 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TestClass proxy = (TestClass)constructor.newInstance(new Object[] {name}); 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ((ProxyObject)proxy).setHandler(handler); 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArrayOutputStream bos = new ByteArrayOutputStream(); 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectOutputStream out = new ObjectOutputStream(bos); 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeObject(proxy); 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.close(); 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] bytes = bos.toByteArray(); 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectInputStream in = new ObjectInputStream(bis); 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TestClass newProxy = (TestClass)in.readObject(); 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // inherited fields should not have been deserialized 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal assertTrue("new name should be null", newProxy.getName() == null); 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // since we are reading into the same JVM the new proxy should have the same class as the old proxy 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal assertTrue("classes should be equal", newProxy.getClass() == proxy.getClass()); 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } catch (Exception e) { 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.printStackTrace(); 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fail(); 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // second try serialization using proxy object output/input streams 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setUseWriteReplace(false); 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal proxyClass = factory.createClass(new TestFilter()); 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name = "proxytest_2"; 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Constructor constructor = proxyClass.getConstructor(new Class[] {String.class}); 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TestClass proxy = (TestClass)constructor.newInstance(new Object[] {name}); 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ((ProxyObject)proxy).setHandler(handler); 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArrayOutputStream bos = new ByteArrayOutputStream(); 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProxyObjectOutputStream out = new ProxyObjectOutputStream(bos); 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeObject(proxy); 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.close(); 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] bytes = bos.toByteArray(); 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProxyObjectInputStream in = new ProxyObjectInputStream(bis); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TestClass newProxy = (TestClass)in.readObject(); 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // inherited fields should have been deserialized 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal assertTrue("names should be equal", proxy.getName().equals(newProxy.getName())); 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // since we are reading into the same JVM the new proxy should have the same class as the old proxy 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal assertTrue("classes should still be equal", newProxy.getClass() == proxy.getClass()); 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } catch (Exception e) { 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.printStackTrace(); 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fail(); 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class TestFilter implements MethodFilter, Serializable 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean isHandled(Method m) { 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (m.getName().equals("getName")) { 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean equals(Object o) 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (o instanceof TestFilter) { 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // all test filters are equal 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int hashCode() 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return TestFilter.class.hashCode(); 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class TestHandler implements MethodHandler, Serializable 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return proceed.invoke(self, args); 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean equals(Object o) 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (o instanceof TestHandler) { 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // all test handlers are equal 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int hashCode() 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return TestHandler.class.hashCode(); 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class TestClass implements Serializable 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String name; 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TestClass() 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TestClass(String name) 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.name = name; 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getName() 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return name; 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static interface TestInterface 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getName(); 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 152