001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
007:
008: import com.tc.object.bytecode.Manageable;
009: import com.tc.object.bytecode.ManagerUtil;
010: import com.tc.object.bytecode.TransparentAccess;
011: import com.tc.object.config.ConfigVisitor;
012: import com.tc.object.config.DSOClientConfigHelper;
013: import com.tc.object.config.TransparencyClassSpec;
014: import com.tc.object.loaders.IsolationClassLoader;
015: import com.tc.simulator.app.ApplicationConfig;
016: import com.tc.simulator.listener.ListenerProvider;
017: import com.tc.util.Assert;
018: import com.tctest.runner.AbstractTransparentApp;
019:
020: import java.io.Serializable;
021: import java.lang.reflect.Field;
022: import java.lang.reflect.InvocationHandler;
023: import java.lang.reflect.Method;
024: import java.lang.reflect.Proxy;
025: import java.net.URL;
026: import java.net.URLClassLoader;
027: import java.util.Collection;
028: import java.util.HashMap;
029: import java.util.Map;
030:
031: public class ProxyTestApp extends AbstractTransparentApp {
032: private final CyclicBarrier barrier;
033: private MyProxyInf1 proxyImpl;
034:
035: private DataRoot dataRoot = new DataRoot();
036: private Map mapRoot = new HashMap();
037:
038: public ProxyTestApp(String appId, ApplicationConfig cfg,
039: ListenerProvider listenerProvider) {
040: super (appId, cfg, listenerProvider);
041: this .barrier = new CyclicBarrier(getParticipantCount());
042: }
043:
044: public void run() {
045: try {
046: int index = barrier.barrier();
047:
048: proxyDSOInterfaces1(index);
049: proxyDSOInterfaces2(index);
050: proxySystemInterface(index);
051: validProxyTest(index);
052: subclassProxyTest(index);
053: differentLoaderTest(index);
054: multipleInterfacesProxyTest(index);
055: cloneTest(index);
056: innerCloneTest(index);
057: reflectionTest(index);
058:
059: } catch (Throwable t) {
060: notifyError(t);
061: }
062: }
063:
064: /**
065: * A simple test to create a proxy with DSO interfaces.
066: */
067: private void proxyDSOInterfaces1(int index) throws Throwable {
068: if (index == 0) {
069: MyInvocationHandler handler = new MyInvocationHandler();
070: Proxy myProxy = (Proxy) Proxy.newProxyInstance(this
071: .getClass().getClassLoader(), new Class[] {
072: Manageable.class, MyProxyInf1.class,
073: MyProxyInf2.class, TransparentAccess.class },
074: handler);
075: dataRoot.setMyProxy(myProxy);
076: }
077:
078: barrier.barrier();
079:
080: Class[] interfaces = dataRoot.getMyProxy().getClass()
081: .getInterfaces();
082: Assert.assertEquals(2, interfaces.length);
083: for (int i = 0; i < interfaces.length; i++) {
084: Assert.assertFalse(interfaces[i].equals(Manageable.class
085: .getName()));
086: Assert.assertFalse(interfaces[i]
087: .equals(TransparentAccess.class.getName()));
088: }
089:
090: barrier.barrier();
091: }
092:
093: private void proxyDSOInterfaces2(int index) throws Throwable {
094: if (index == 0) {
095: MyInvocationHandler handler = new MyInvocationHandler();
096: Object o = Proxy.newProxyInstance(this .getClass()
097: .getClassLoader(), new Class[] { Manageable.class,
098: TransparentAccess.class, Serializable.class },
099: handler);
100:
101: dataRoot.setMyProxy(o);
102: }
103:
104: barrier.barrier();
105:
106: Class[] interfaces = dataRoot.getMyProxy().getClass()
107: .getInterfaces();
108: Assert.assertEquals(1, interfaces.length);
109: Assert.assertEquals(Serializable.class.getName(), interfaces[0]
110: .getName());
111:
112: barrier.barrier();
113:
114: }
115:
116: private void reflectionTest(int index) throws Throwable {
117: if (index == 0) {
118: MyInvocationHandler handler = new MyInvocationHandler();
119: Proxy myProxy = (Proxy) Proxy.newProxyInstance(this
120: .getClass().getClassLoader(), new Class[] {
121: MyProxyInf1.class, MyProxyInf2.class }, handler);
122: ((MyProxyInf2) myProxy).setStringValue("Testing2");
123: dataRoot.setMyProxy(myProxy);
124: }
125:
126: barrier.barrier();
127:
128: Assert.assertEquals("Testing2", ((MyProxyInf2) dataRoot
129: .getMyProxy()).getStringValue());
130:
131: barrier.barrier();
132:
133: if (index == 1) {
134: MyInvocationHandler handler = new MyInvocationHandler();
135: Proxy myProxy = (Proxy) dataRoot.getMyProxy();
136: Field field = myProxy.getClass().getSuperclass()
137: .getDeclaredField("h"); // get the invocation handler field
138: // through reflection.
139: field.setAccessible(true);
140: synchronized (myProxy) {
141: field.set(myProxy, handler);
142: }
143: }
144:
145: barrier.barrier();
146:
147: Assert.assertNull(((MyProxyInf2) dataRoot.getMyProxy())
148: .getStringValue());
149:
150: barrier.barrier();
151:
152: if (index == 0) {
153: synchronized (dataRoot.getMyProxy()) {
154: ((MyProxyInf1) dataRoot.getMyProxy()).setValue(2002);
155: }
156: }
157:
158: barrier.barrier();
159:
160: Assert.assertEquals(2002, ((MyProxyInf1) dataRoot.getMyProxy())
161: .getValue());
162:
163: barrier.barrier();
164: }
165:
166: private void innerCloneTest(int index) throws Throwable {
167: if (index == 0) {
168: MyInvocationHandler handler = new MyInvocationHandler();
169: Proxy myProxy = (Proxy) Proxy.newProxyInstance(this
170: .getClass().getClassLoader(), new Class[] {
171: MyProxyInf1.class, MyProxyInf2.class }, handler);
172: ((MyProxyInf1) myProxy).setValue(2000);
173: ((MyProxyInf2) myProxy).setStringValue("Testing");
174:
175: synchronized (mapRoot) {
176: mapRoot.put("proxy", myProxy);
177: }
178:
179: Map clonedMap = null;
180: ManagerUtil.optimisticBegin();
181: clonedMap = (Map) ManagerUtil.deepCopy(mapRoot);
182: ManagerUtil.optimisticCommit();
183:
184: Assert.assertEquals(1, clonedMap.size());
185: Proxy clonedProxy = (Proxy) clonedMap.get("proxy");
186:
187: Assert.assertFalse(clonedProxy == myProxy);
188: Assert.assertEquals(2000, ((MyProxyInf1) clonedProxy)
189: .getValue());
190: Assert.assertEquals("Testing", ((MyProxyInf2) clonedProxy)
191: .getStringValue());
192: }
193:
194: barrier.barrier();
195: }
196:
197: private void cloneTest(int index) throws Throwable {
198: if (index == 0) {
199: MyInvocationHandler handler = new MyInvocationHandler();
200: Proxy myProxy = (Proxy) Proxy.newProxyInstance(this
201: .getClass().getClassLoader(), new Class[] {
202: MyProxyInf1.class, MyProxyInf2.class }, handler);
203: ((MyProxyInf1) myProxy).setValue(2000);
204: ((MyProxyInf2) myProxy).setStringValue("Testing");
205: dataRoot.setMyProxy(myProxy);
206: }
207:
208: barrier.barrier();
209:
210: Object copy = null;
211: ManagerUtil.optimisticBegin();
212: copy = ManagerUtil.deepCopy(dataRoot.getMyProxy());
213: ManagerUtil.optimisticCommit();
214:
215: Assert.assertTrue(copy instanceof Proxy);
216: Assert.assertTrue(copy instanceof MyProxyInf1);
217: Assert.assertTrue(copy instanceof MyProxyInf2);
218: Assert.assertFalse(copy == dataRoot.getMyProxy());
219:
220: barrier.barrier();
221: }
222:
223: private void multipleInterfacesProxyTest(int index)
224: throws Throwable {
225: if (index == 0) {
226: MyInvocationHandler handler = new MyInvocationHandler();
227: Proxy myProxy = (Proxy) Proxy.newProxyInstance(this
228: .getClass().getClassLoader(), new Class[] {
229: MyProxyInf1.class, MyProxyInf2.class }, handler);
230: ((MyProxyInf1) myProxy).setValue(2000);
231: ((MyProxyInf2) myProxy).setStringValue("Testing");
232: dataRoot.setMyProxy(myProxy);
233: }
234:
235: barrier.barrier();
236:
237: Assert.assertTrue(dataRoot.getMyProxy() instanceof MyProxyInf1);
238: Assert.assertTrue(dataRoot.getMyProxy() instanceof MyProxyInf2);
239:
240: Assert.assertEquals(2000, ((MyProxyInf1) dataRoot.getMyProxy())
241: .getValue());
242: Assert.assertEquals("Testing", ((MyProxyInf2) dataRoot
243: .getMyProxy()).getStringValue());
244:
245: barrier.barrier();
246: }
247:
248: private void differentLoaderTest(int index) throws Throwable {
249: if (index == 0) {
250: MyMapInvocationHandler handler = new MyMapInvocationHandler();
251:
252: Assert
253: .assertFalse(this .getClass().getClassLoader() == Map.class
254: .getClassLoader());
255:
256: Object myProxy = Proxy.newProxyInstance(this .getClass()
257: .getClassLoader(), new Class[] { Map.class },
258: handler);
259:
260: ((Map) myProxy).put("key1", "value1");
261: ((Map) myProxy).put("key2", "value2");
262:
263: dataRoot.setMyProxy(myProxy);
264:
265: }
266:
267: barrier.barrier();
268:
269: Assert.assertTrue(dataRoot.getMyProxy().getClass()
270: .getClassLoader() instanceof IsolationClassLoader);
271: Assert.assertEquals(2, ((Map) dataRoot.getMyProxy()).size());
272: Assert.assertEquals("value1", ((Map) dataRoot.getMyProxy())
273: .get("key1"));
274: Assert.assertEquals("value2", ((Map) dataRoot.getMyProxy())
275: .get("key2"));
276:
277: barrier.barrier();
278: }
279:
280: private void subclassProxyTest(int index) throws Throwable {
281: if (index == 0) {
282: MyInvocationHandler handler = new MyInvocationHandler();
283: MyProxyInf1 myProxy = new MySubProxy(handler);
284:
285: myProxy.setValue(137);
286: dataRoot.setMyProxy(myProxy);
287: }
288:
289: barrier.barrier();
290:
291: Assert.assertFalse(Proxy.isProxyClass(dataRoot.getMyProxy()
292: .getClass()));
293:
294: Assert.assertEquals(-1, ((MyProxyInf1) dataRoot.getMyProxy())
295: .getValue());
296:
297: barrier.barrier();
298: }
299:
300: private void proxySystemInterface(int index) throws Throwable {
301: if (index == 0) {
302: MyInvocationHandler handler = new MyInvocationHandler();
303: Collection colProxyImpl = (Collection) Proxy
304: .newProxyInstance(System.class.getClassLoader(),
305: new Class[] { Collection.class }, handler);
306: Assert.assertNull(colProxyImpl.getClass().getClassLoader());
307: }
308: barrier.barrier();
309: }
310:
311: private void validProxyTest(int index) throws Throwable {
312: if (index == 0) {
313: MyInvocationHandler handler = new MyInvocationHandler();
314: proxyImpl = (MyProxyInf1) Proxy.newProxyInstance(
315: MyProxyInf1.class.getClassLoader(),
316: new Class[] { MyProxyInf1.class }, handler);
317:
318: }
319:
320: barrier.barrier();
321:
322: if (index == 1) {
323: synchronized (proxyImpl) {
324: proxyImpl.setValue(123);
325: }
326: }
327:
328: barrier.barrier();
329:
330: Assert
331: .assertTrue(proxyImpl.getClass().getClassLoader() instanceof IsolationClassLoader);
332: Assert.assertEquals(123, proxyImpl.getValue());
333:
334: barrier.barrier();
335:
336: if (index == 0) {
337: MyInvocationHandler handler = new MyInvocationHandler();
338: MyProxyInf1 myProxy = (MyProxyInf1) Proxy.newProxyInstance(
339: MyProxyInf1.class.getClassLoader(),
340: new Class[] { MyProxyInf1.class }, handler);
341: myProxy.setValue(137);
342: dataRoot.setMyProxy(myProxy);
343: }
344:
345: barrier.barrier();
346:
347: Assert.assertEquals(137, ((MyProxyInf1) dataRoot.getMyProxy())
348: .getValue());
349:
350: barrier.barrier();
351:
352: if (index == 1) {
353: dataRoot.setMyProxy(proxyImpl);
354: }
355:
356: barrier.barrier();
357:
358: Assert.assertTrue(dataRoot.getMyProxy() == proxyImpl);
359: Assert.assertEquals(123, ((MyProxyInf1) dataRoot.getMyProxy())
360: .getValue());
361:
362: barrier.barrier();
363:
364: }
365:
366: public static void visitL1DSOConfig(ConfigVisitor visitor,
367: DSOClientConfigHelper config) {
368: TransparencyClassSpec spec = config
369: .getOrCreateSpec(CyclicBarrier.class.getName());
370: config.addWriteAutolock("* " + CyclicBarrier.class.getName()
371: + "*.*(..)");
372:
373: String testClass = ProxyTestApp.class.getName();
374: spec = config.getOrCreateSpec(testClass);
375: config.addIncludePattern(testClass + "$DataRoot");
376: config.addIncludePattern(testClass + "$MySubProxy");
377: config.addIncludePattern(testClass + "$MyInvocationHandler");
378: config.addIncludePattern(testClass + "$MyMapInvocationHandler");
379: String methodExpression = "* " + testClass + "*.*(..)";
380: config.addWriteAutolock(methodExpression);
381:
382: spec.addRoot("barrier", "barrier");
383: spec.addRoot("proxyImpl", "proxyImpl");
384: spec.addRoot("dataRoot", "dataRoot");
385: spec.addRoot("mapRoot", "mapRoot");
386: }
387:
388: private static class MySubProxy extends Proxy implements
389: MyProxyInf1 {
390: public MySubProxy(InvocationHandler h) {
391: super (h);
392: }
393:
394: public int getValue() {
395: return -1;
396: }
397:
398: public void setValue(int i) {
399: //
400: }
401: }
402:
403: public interface MyProxySuperIntf {
404: public void setSuperIntfValue();
405: }
406:
407: public interface MyProxyInf1 {
408: public int getValue();
409:
410: public void setValue(int i);
411: }
412:
413: public interface MyProxyInf2 extends MyProxySuperIntf {
414: public String getStringValue();
415:
416: public void setStringValue(String str);
417: }
418:
419: public static class MyInvocationHandler implements
420: InvocationHandler {
421: private Map values = new HashMap();
422: private Map stringValues = new HashMap();
423:
424: public Object invoke(Object proxy, Method method, Object[] args)
425: throws Throwable {
426: if (method.getName().equals("getValue")) {
427: return values.get(proxy);
428: } else if (method.getName().equals("setValue")) {
429: values.put(proxy, args[0]);
430: return null;
431: } else if (method.getName().equals("setStringValue")) {
432: stringValues.put(proxy, args[0]);
433: return null;
434: } else if (method.getName().equals("getStringValue")) {
435: return stringValues.get(proxy);
436: } else if (method.getName().equals("hashCode")) {
437: return new Integer(System.identityHashCode(proxy));
438: }
439: return null;
440: }
441: }
442:
443: private static class MyMapInvocationHandler implements
444: InvocationHandler {
445: private Map values = new HashMap();
446:
447: public Object invoke(Object proxy, Method method, Object[] args)
448: throws Throwable {
449: if (method.getName().equals("get")) {
450: return values.get(args[0]);
451: } else if (method.getName().equals("put")) {
452: values.put(args[0], args[1]);
453: return null;
454: } else if (method.getName().equals("size")) {
455: return new Integer(values.size());
456: } else if (method.getName().equals("hashCode")) {
457: return new Integer(System.identityHashCode(proxy));
458: }
459: return null;
460: }
461: }
462:
463: private static class DataRoot {
464: private Object myProxy;
465:
466: public DataRoot() {
467: super ();
468: }
469:
470: public Object getMyProxy() {
471: return myProxy;
472: }
473:
474: public synchronized void setMyProxy(Object myProxy) {
475: this .myProxy = myProxy;
476: }
477: }
478:
479: public static class MyProxyClassLoader extends URLClassLoader {
480: private static final ClassLoader SYSTEM_LOADER = ClassLoader
481: .getSystemClassLoader();
482:
483: public MyProxyClassLoader() {
484: super (getSystemURLS(), null);
485: }
486:
487: private static URL[] getSystemURLS() {
488: return ((URLClassLoader) SYSTEM_LOADER).getURLs();
489: }
490:
491: public Class loadClass(String name)
492: throws ClassNotFoundException {
493: return super.loadClass(name);
494: }
495:
496: }
497: }
|