1 /*
2  * Copyright 2002-2008 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.orm.hibernate3;
18 
19 import java.lang.reflect.AccessibleObject;
20 import java.lang.reflect.Method;
21 import java.sql.SQLException;
22 
23 import junit.framework.TestCase;
24 import org.aopalliance.intercept.Interceptor;
25 import org.aopalliance.intercept.Invocation;
26 import org.aopalliance.intercept.MethodInvocation;
27 import org.easymock.MockControl;
28 import org.hibernate.FlushMode;
29 import org.hibernate.HibernateException;
30 import org.hibernate.SessionFactory;
31 import org.hibernate.classic.Session;
32 import org.hibernate.exception.ConstraintViolationException;
33 
34 import org.springframework.beans.factory.BeanFactory;
35 import org.springframework.dao.DataIntegrityViolationException;
36 import org.springframework.transaction.support.TransactionSynchronizationManager;
37 
38 /**
39  * @author Juergen Hoeller
40  * @since 05.03.2005
41  */
42 public class HibernateInterceptorTests extends TestCase {
43 
testInterceptorWithNewSession()44 	public void testInterceptorWithNewSession() throws HibernateException {
45 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
46 		SessionFactory sf = (SessionFactory) sfControl.getMock();
47 		MockControl sessionControl = MockControl.createControl(Session.class);
48 		Session session = (Session) sessionControl.getMock();
49 		sf.openSession();
50 		sfControl.setReturnValue(session, 1);
51 		session.getSessionFactory();
52 		sessionControl.setReturnValue(sf);
53 		session.flush();
54 		sessionControl.setVoidCallable(1);
55 		session.close();
56 		sessionControl.setReturnValue(null, 1);
57 		sfControl.replay();
58 		sessionControl.replay();
59 
60 		HibernateInterceptor interceptor = new HibernateInterceptor();
61 		interceptor.setSessionFactory(sf);
62 		try {
63 			interceptor.invoke(new TestInvocation(sf));
64 		}
65 		catch (Throwable t) {
66 			fail("Should not have thrown Throwable: " + t.getMessage());
67 		}
68 
69 		sfControl.verify();
70 		sessionControl.verify();
71 	}
72 
testInterceptorWithNewSessionAndFlushNever()73 	public void testInterceptorWithNewSessionAndFlushNever() throws HibernateException {
74 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
75 		SessionFactory sf = (SessionFactory) sfControl.getMock();
76 		MockControl sessionControl = MockControl.createControl(Session.class);
77 		Session session = (Session) sessionControl.getMock();
78 		sf.openSession();
79 		sfControl.setReturnValue(session, 1);
80 		session.getSessionFactory();
81 		sessionControl.setReturnValue(sf);
82 		session.setFlushMode(FlushMode.MANUAL);
83 		sessionControl.setVoidCallable(1);
84 		session.close();
85 			sessionControl.setReturnValue(null, 1);
86 		sfControl.replay();
87 		sessionControl.replay();
88 
89 		HibernateInterceptor interceptor = new HibernateInterceptor();
90 		interceptor.setFlushModeName("FLUSH_NEVER");
91 		interceptor.setSessionFactory(sf);
92 		try {
93 			interceptor.invoke(new TestInvocation(sf));
94 		}
95 		catch (Throwable t) {
96 			fail("Should not have thrown Throwable: " + t.getMessage());
97 		}
98 
99 		sfControl.verify();
100 		sessionControl.verify();
101 	}
102 
testInterceptorWithNewSessionAndFilter()103 	public void testInterceptorWithNewSessionAndFilter() throws HibernateException {
104 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
105 		SessionFactory sf = (SessionFactory) sfControl.getMock();
106 		MockControl sessionControl = MockControl.createControl(Session.class);
107 		Session session = (Session) sessionControl.getMock();
108 		sf.openSession();
109 		sfControl.setReturnValue(session, 1);
110 		session.getSessionFactory();
111 		sessionControl.setReturnValue(sf);
112 		session.enableFilter("myFilter");
113 		sessionControl.setReturnValue(null, 1);
114 		session.flush();
115 		sessionControl.setVoidCallable(1);
116 		session.close();
117 		sessionControl.setReturnValue(null, 1);
118 		sfControl.replay();
119 		sessionControl.replay();
120 
121 		HibernateInterceptor interceptor = new HibernateInterceptor();
122 		interceptor.setSessionFactory(sf);
123 		interceptor.setFilterName("myFilter");
124 		try {
125 			interceptor.invoke(new TestInvocation(sf));
126 		}
127 		catch (Throwable t) {
128 			fail("Should not have thrown Throwable: " + t.getMessage());
129 		}
130 
131 		sfControl.verify();
132 		sessionControl.verify();
133 	}
134 
testInterceptorWithThreadBound()135 	public void testInterceptorWithThreadBound() {
136 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
137 		SessionFactory sf = (SessionFactory) sfControl.getMock();
138 		MockControl sessionControl = MockControl.createControl(Session.class);
139 		Session session = (Session) sessionControl.getMock();
140 		session.getSessionFactory();
141 		sessionControl.setReturnValue(sf, 1);
142 		session.isOpen();
143 		sessionControl.setReturnValue(true, 1);
144 		sfControl.replay();
145 		sessionControl.replay();
146 
147 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
148 		HibernateInterceptor interceptor = new HibernateInterceptor();
149 		interceptor.setSessionFactory(sf);
150 		try {
151 			interceptor.invoke(new TestInvocation(sf));
152 		}
153 		catch (Throwable t) {
154 			fail("Should not have thrown Throwable: " + t.getMessage());
155 		}
156 		finally {
157 			TransactionSynchronizationManager.unbindResource(sf);
158 		}
159 
160 		sfControl.verify();
161 		sessionControl.verify();
162 	}
163 
testInterceptorWithThreadBoundAndFlushEager()164 	public void testInterceptorWithThreadBoundAndFlushEager() throws HibernateException {
165 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
166 		SessionFactory sf = (SessionFactory) sfControl.getMock();
167 		MockControl sessionControl = MockControl.createControl(Session.class);
168 		Session session = (Session) sessionControl.getMock();
169 		session.getSessionFactory();
170 		sessionControl.setReturnValue(sf, 1);
171 		session.isOpen();
172 		sessionControl.setReturnValue(true, 1);
173 		session.getFlushMode();
174 		sessionControl.setReturnValue(FlushMode.AUTO, 1);
175 		session.flush();
176 		sessionControl.setVoidCallable(1);
177 		sfControl.replay();
178 		sessionControl.replay();
179 
180 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
181 		HibernateInterceptor interceptor = new HibernateInterceptor();
182 		interceptor.setFlushMode(HibernateInterceptor.FLUSH_EAGER);
183 		interceptor.setSessionFactory(sf);
184 		try {
185 			interceptor.invoke(new TestInvocation(sf));
186 		}
187 		catch (Throwable t) {
188 			fail("Should not have thrown Throwable: " + t.getMessage());
189 		}
190 		finally {
191 			TransactionSynchronizationManager.unbindResource(sf);
192 		}
193 
194 		sfControl.verify();
195 		sessionControl.verify();
196 	}
197 
testInterceptorWithThreadBoundAndFlushEagerSwitch()198 	public void testInterceptorWithThreadBoundAndFlushEagerSwitch() throws HibernateException {
199 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
200 		SessionFactory sf = (SessionFactory) sfControl.getMock();
201 		MockControl sessionControl = MockControl.createControl(Session.class);
202 		Session session = (Session) sessionControl.getMock();
203 		session.getSessionFactory();
204 		sessionControl.setReturnValue(sf, 1);
205 		session.isOpen();
206 		sessionControl.setReturnValue(true, 1);
207 		session.getFlushMode();
208 		sessionControl.setReturnValue(FlushMode.NEVER, 1);
209 		session.setFlushMode(FlushMode.AUTO);
210 		sessionControl.setVoidCallable(1);
211 		session.flush();
212 		sessionControl.setVoidCallable(1);
213 		session.setFlushMode(FlushMode.NEVER);
214 		sessionControl.setVoidCallable(1);
215 		sfControl.replay();
216 		sessionControl.replay();
217 
218 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
219 		HibernateInterceptor interceptor = new HibernateInterceptor();
220 		interceptor.setFlushMode(HibernateInterceptor.FLUSH_EAGER);
221 		interceptor.setSessionFactory(sf);
222 		try {
223 			interceptor.invoke(new TestInvocation(sf));
224 		}
225 		catch (Throwable t) {
226 			fail("Should not have thrown Throwable: " + t.getMessage());
227 		}
228 		finally {
229 			TransactionSynchronizationManager.unbindResource(sf);
230 		}
231 
232 		sfControl.verify();
233 		sessionControl.verify();
234 	}
235 
testInterceptorWithThreadBoundAndFlushCommit()236 	public void testInterceptorWithThreadBoundAndFlushCommit() {
237 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
238 		SessionFactory sf = (SessionFactory) sfControl.getMock();
239 		MockControl sessionControl = MockControl.createControl(Session.class);
240 		Session session = (Session) sessionControl.getMock();
241 		session.getSessionFactory();
242 		sessionControl.setReturnValue(sf, 1);
243 		session.isOpen();
244 		sessionControl.setReturnValue(true, 1);
245 		session.getFlushMode();
246 		sessionControl.setReturnValue(FlushMode.AUTO, 1);
247 		session.setFlushMode(FlushMode.COMMIT);
248 		sessionControl.setVoidCallable(1);
249 		session.setFlushMode(FlushMode.AUTO);
250 		sessionControl.setVoidCallable(1);
251 		sfControl.replay();
252 		sessionControl.replay();
253 
254 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
255 		HibernateInterceptor interceptor = new HibernateInterceptor();
256 		interceptor.setSessionFactory(sf);
257 		interceptor.setFlushMode(HibernateInterceptor.FLUSH_COMMIT);
258 		try {
259 			interceptor.invoke(new TestInvocation(sf));
260 		}
261 		catch (Throwable t) {
262 			fail("Should not have thrown Throwable: " + t.getMessage());
263 		}
264 		finally {
265 			TransactionSynchronizationManager.unbindResource(sf);
266 		}
267 
268 		sfControl.verify();
269 		sessionControl.verify();
270 	}
271 
testInterceptorWithThreadBoundAndFlushAlways()272 	public void testInterceptorWithThreadBoundAndFlushAlways() {
273 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
274 		SessionFactory sf = (SessionFactory) sfControl.getMock();
275 		MockControl sessionControl = MockControl.createControl(Session.class);
276 		Session session = (Session) sessionControl.getMock();
277 		session.getSessionFactory();
278 		sessionControl.setReturnValue(sf, 1);
279 		session.isOpen();
280 		sessionControl.setReturnValue(true, 1);
281 		session.getFlushMode();
282 		sessionControl.setReturnValue(FlushMode.AUTO, 1);
283 		session.setFlushMode(FlushMode.ALWAYS);
284 		sessionControl.setVoidCallable(1);
285 		session.setFlushMode(FlushMode.AUTO);
286 		sessionControl.setVoidCallable(1);
287 		sfControl.replay();
288 		sessionControl.replay();
289 
290 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
291 		HibernateInterceptor interceptor = new HibernateInterceptor();
292 		interceptor.setSessionFactory(sf);
293 		interceptor.setFlushMode(HibernateInterceptor.FLUSH_ALWAYS);
294 		try {
295 			interceptor.invoke(new TestInvocation(sf));
296 		}
297 		catch (Throwable t) {
298 			fail("Should not have thrown Throwable: " + t.getMessage());
299 		}
300 		finally {
301 			TransactionSynchronizationManager.unbindResource(sf);
302 		}
303 
304 		sfControl.verify();
305 		sessionControl.verify();
306 	}
307 
testInterceptorWithThreadBoundAndFilter()308 	public void testInterceptorWithThreadBoundAndFilter() {
309 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
310 		SessionFactory sf = (SessionFactory) sfControl.getMock();
311 		MockControl sessionControl = MockControl.createControl(Session.class);
312 		Session session = (Session) sessionControl.getMock();
313 		session.getSessionFactory();
314 		sessionControl.setReturnValue(sf, 1);
315 		session.isOpen();
316 		sessionControl.setReturnValue(true, 1);
317 		session.enableFilter("myFilter");
318 		sessionControl.setReturnValue(null, 1);
319 		session.disableFilter("myFilter");
320 		sessionControl.setVoidCallable(1);
321 		sfControl.replay();
322 		sessionControl.replay();
323 
324 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
325 		HibernateInterceptor interceptor = new HibernateInterceptor();
326 		interceptor.setSessionFactory(sf);
327 		interceptor.setFilterName("myFilter");
328 		try {
329 			interceptor.invoke(new TestInvocation(sf));
330 		}
331 		catch (Throwable t) {
332 			fail("Should not have thrown Throwable: " + t.getMessage());
333 		}
334 		finally {
335 			TransactionSynchronizationManager.unbindResource(sf);
336 		}
337 
338 		sfControl.verify();
339 		sessionControl.verify();
340 	}
341 
testInterceptorWithThreadBoundAndFilters()342 	public void testInterceptorWithThreadBoundAndFilters() {
343 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
344 		SessionFactory sf = (SessionFactory) sfControl.getMock();
345 		MockControl sessionControl = MockControl.createControl(Session.class);
346 		Session session = (Session) sessionControl.getMock();
347 		session.getSessionFactory();
348 		sessionControl.setReturnValue(sf, 1);
349 		session.isOpen();
350 		sessionControl.setReturnValue(true, 1);
351 		session.enableFilter("myFilter");
352 		sessionControl.setReturnValue(null, 1);
353 		session.enableFilter("yourFilter");
354 		sessionControl.setReturnValue(null, 1);
355 		session.disableFilter("myFilter");
356 		sessionControl.setVoidCallable(1);
357 		session.disableFilter("yourFilter");
358 		sessionControl.setVoidCallable(1);
359 		sfControl.replay();
360 		sessionControl.replay();
361 
362 		TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
363 		HibernateInterceptor interceptor = new HibernateInterceptor();
364 		interceptor.setSessionFactory(sf);
365 		interceptor.setFilterNames(new String[] {"myFilter", "yourFilter"});
366 		try {
367 			interceptor.invoke(new TestInvocation(sf));
368 		}
369 		catch (Throwable t) {
370 			fail("Should not have thrown Throwable: " + t.getMessage());
371 		}
372 		finally {
373 			TransactionSynchronizationManager.unbindResource(sf);
374 		}
375 
376 		sfControl.verify();
377 		sessionControl.verify();
378 	}
379 
testInterceptorWithFlushFailure()380 	public void testInterceptorWithFlushFailure() throws Throwable {
381 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
382 		SessionFactory sf = (SessionFactory) sfControl.getMock();
383 		MockControl sessionControl = MockControl.createControl(Session.class);
384 		Session session = (Session) sessionControl.getMock();
385 		sf.openSession();
386 		sfControl.setReturnValue(session, 1);
387 		session.getSessionFactory();
388 		sessionControl.setReturnValue(sf, 1);
389 		SQLException sqlEx = new SQLException("argh", "27");
390 		session.flush();
391 		ConstraintViolationException jdbcEx = new ConstraintViolationException("", sqlEx, null);
392 		sessionControl.setThrowable(jdbcEx, 1);
393 		session.close();
394 		sessionControl.setReturnValue(null, 1);
395 		sfControl.replay();
396 		sessionControl.replay();
397 
398 		HibernateInterceptor interceptor = new HibernateInterceptor();
399 		interceptor.setSessionFactory(sf);
400 		try {
401 			interceptor.invoke(new TestInvocation(sf));
402 			fail("Should have thrown DataIntegrityViolationException");
403 		}
404 		catch (DataIntegrityViolationException ex) {
405 			// expected
406 			assertEquals(jdbcEx, ex.getCause());
407 		}
408 
409 		sfControl.verify();
410 		sessionControl.verify();
411 	}
412 
testInterceptorWithThreadBoundEmptyHolder()413 	public void testInterceptorWithThreadBoundEmptyHolder() {
414 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
415 		SessionFactory sf = (SessionFactory) sfControl.getMock();
416 		MockControl sessionControl = MockControl.createControl(Session.class);
417 		Session session = (Session) sessionControl.getMock();
418 		sf.openSession();
419 		sfControl.setReturnValue(session, 1);
420 		session.getSessionFactory();
421 		sessionControl.setReturnValue(sf, 1);
422 		session.flush();
423 		sessionControl.setVoidCallable(1);
424 		session.close();
425 		sessionControl.setReturnValue(null, 1);
426 		sfControl.replay();
427 		sessionControl.replay();
428 
429 		SessionHolder holder = new SessionHolder("key", session);
430 		holder.removeSession("key");
431 		TransactionSynchronizationManager.bindResource(sf, holder);
432 		HibernateInterceptor interceptor = new HibernateInterceptor();
433 		interceptor.setSessionFactory(sf);
434 		try {
435 			interceptor.invoke(new TestInvocation(sf));
436 		}
437 		catch (Throwable t) {
438 			fail("Should not have thrown Throwable: " + t.getMessage());
439 		}
440 
441 		sfControl.verify();
442 		sessionControl.verify();
443 	}
444 
testInterceptorWithEntityInterceptor()445 	public void testInterceptorWithEntityInterceptor() throws HibernateException {
446 		MockControl interceptorControl = MockControl.createControl(org.hibernate.Interceptor.class);
447 		org.hibernate.Interceptor entityInterceptor = (org.hibernate.Interceptor) interceptorControl.getMock();
448 		interceptorControl.replay();
449 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
450 		SessionFactory sf = (SessionFactory) sfControl.getMock();
451 		MockControl sessionControl = MockControl.createControl(Session.class);
452 		Session session = (Session) sessionControl.getMock();
453 		sf.openSession(entityInterceptor);
454 		sfControl.setReturnValue(session, 1);
455 		session.getSessionFactory();
456 		sessionControl.setReturnValue(sf, 1);
457 		session.flush();
458 		sessionControl.setVoidCallable(1);
459 		session.close();
460 		sessionControl.setReturnValue(null, 1);
461 		sfControl.replay();
462 		sessionControl.replay();
463 
464 		HibernateInterceptor interceptor = new HibernateInterceptor();
465 		interceptor.setSessionFactory(sf);
466 		interceptor.setEntityInterceptor(entityInterceptor);
467 		try {
468 			interceptor.invoke(new TestInvocation(sf));
469 		}
470 		catch (Throwable t) {
471 			fail("Should not have thrown Throwable: " + t.getMessage());
472 		}
473 
474 		interceptorControl.verify();
475 		sfControl.verify();
476 		sessionControl.verify();
477 	}
478 
testInterceptorWithEntityInterceptorBeanName()479 	public void testInterceptorWithEntityInterceptorBeanName() throws HibernateException {
480 		MockControl interceptorControl = MockControl.createControl(org.hibernate.Interceptor.class);
481 		org.hibernate.Interceptor entityInterceptor = (org.hibernate.Interceptor) interceptorControl.getMock();
482 		interceptorControl.replay();
483 		MockControl interceptor2Control = MockControl.createControl(org.hibernate.Interceptor.class);
484 		org.hibernate.Interceptor entityInterceptor2 = (org.hibernate.Interceptor) interceptor2Control.getMock();
485 		interceptor2Control.replay();
486 
487 		MockControl sfControl = MockControl.createControl(SessionFactory.class);
488 		SessionFactory sf = (SessionFactory) sfControl.getMock();
489 		MockControl sessionControl = MockControl.createControl(Session.class);
490 		Session session = (Session) sessionControl.getMock();
491 		sf.openSession(entityInterceptor);
492 		sfControl.setReturnValue(session, 1);
493 		sf.openSession(entityInterceptor2);
494 		sfControl.setReturnValue(session, 1);
495 		session.getSessionFactory();
496 		sessionControl.setReturnValue(sf, 2);
497 		session.flush();
498 		sessionControl.setVoidCallable(2);
499 		session.close();
500 		sessionControl.setReturnValue(null, 2);
501 		sfControl.replay();
502 		sessionControl.replay();
503 
504 		MockControl beanFactoryControl = MockControl.createControl(BeanFactory.class);
505 		BeanFactory beanFactory = (BeanFactory) beanFactoryControl.getMock();
506 		beanFactory.getBean("entityInterceptor", org.hibernate.Interceptor.class);
507 		beanFactoryControl.setReturnValue(entityInterceptor, 1);
508 		beanFactory.getBean("entityInterceptor", org.hibernate.Interceptor.class);
509 		beanFactoryControl.setReturnValue(entityInterceptor2, 1);
510 		beanFactoryControl.replay();
511 
512 		HibernateInterceptor interceptor = new HibernateInterceptor();
513 		interceptor.setSessionFactory(sf);
514 		interceptor.setEntityInterceptorBeanName("entityInterceptor");
515 		interceptor.setBeanFactory(beanFactory);
516 		for (int i = 0; i < 2; i++) {
517 			try {
518 				interceptor.invoke(new TestInvocation(sf));
519 			}
520 			catch (Throwable t) {
521 				fail("Should not have thrown Throwable: " + t.getMessage());
522 			}
523 		}
524 
525 		interceptorControl.verify();
526 		interceptor2Control.verify();
527 		sfControl.verify();
528 		sessionControl.verify();
529 	}
530 
tearDown()531 	protected void tearDown() {
532 		assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
533 		assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
534 	}
535 
536 
537 	private static class TestInvocation implements MethodInvocation {
538 
539 		private SessionFactory sessionFactory;
540 
TestInvocation(SessionFactory sessionFactory)541 		public TestInvocation(SessionFactory sessionFactory) {
542 			this.sessionFactory = sessionFactory;
543 		}
544 
proceed()545 		public Object proceed() throws Throwable {
546 			if (!TransactionSynchronizationManager.hasResource(this.sessionFactory)) {
547 				throw new IllegalStateException("Session not bound");
548 			}
549 			return null;
550 		}
551 
getCurrentInterceptorIndex()552 		public int getCurrentInterceptorIndex() {
553 			return 0;
554 		}
555 
getNumberOfInterceptors()556 		public int getNumberOfInterceptors() {
557 			return 0;
558 		}
559 
getInterceptor(int i)560 		public Interceptor getInterceptor(int i) {
561 			return null;
562 		}
563 
getMethod()564 		public Method getMethod() {
565 			return null;
566 		}
567 
getStaticPart()568 		public AccessibleObject getStaticPart() {
569 			return null;
570 		}
571 
getArgument(int i)572 		public Object getArgument(int i) {
573 			return null;
574 		}
575 
getArguments()576 		public Object[] getArguments() {
577 			return null;
578 		}
579 
setArgument(int i, Object handler)580 		public void setArgument(int i, Object handler) {
581 		}
582 
getArgumentCount()583 		public int getArgumentCount() {
584 			return 0;
585 		}
586 
getThis()587 		public Object getThis() {
588 			return null;
589 		}
590 
getProxy()591 		public Object getProxy() {
592 			return null;
593 		}
594 
cloneInstance()595 		public Invocation cloneInstance() {
596 			return null;
597 		}
598 
release()599 		public void release() {
600 		}
601 	}
602 
603 }
604