001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package test.javax.management;
010:
011: import java.io.IOException;
012: import java.lang.reflect.UndeclaredThrowableException;
013: import javax.management.InstanceNotFoundException;
014: import javax.management.ListenerNotFoundException;
015: import javax.management.MBeanException;
016: import javax.management.MBeanNotificationInfo;
017: import javax.management.MBeanServer;
018: import javax.management.MBeanServerConnection;
019: import javax.management.MBeanServerInvocationHandler;
020: import javax.management.Notification;
021: import javax.management.NotificationBroadcaster;
022: import javax.management.NotificationBroadcasterSupport;
023: import javax.management.NotificationEmitter;
024: import javax.management.NotificationFilter;
025: import javax.management.NotificationListener;
026: import javax.management.ObjectName;
027: import javax.management.remote.JMXConnector;
028: import javax.management.remote.JMXConnectorFactory;
029: import javax.management.remote.JMXConnectorServer;
030: import javax.management.remote.JMXConnectorServerFactory;
031: import javax.management.remote.JMXServiceURL;
032: import javax.naming.NamingException;
033:
034: import test.MX4JTestCase;
035:
036: /**
037: * @version $Revision: 1.8 $
038: */
039: public class MBeanServerInvocationHandlerTest extends MX4JTestCase {
040: public MBeanServerInvocationHandlerTest(String s) {
041: super (s);
042: }
043:
044: public void testBadArguments() throws Exception {
045: MBeanServer server = newMBeanServer();
046: ObjectName name = new ObjectName("domain:key=value");
047:
048: try {
049: MBeanServerInvocationHandler.newProxyInstance(null, name,
050: LocalServiceMBean.class, false);
051: fail("MBeanServerConnection cannot be null");
052: } catch (IllegalArgumentException x) {
053: }
054:
055: try {
056: MBeanServerInvocationHandler.newProxyInstance(server, null,
057: LocalServiceMBean.class, false);
058: fail("ObjectName cannot be null");
059: } catch (IllegalArgumentException x) {
060: }
061:
062: try {
063: MBeanServerInvocationHandler.newProxyInstance(server, name,
064: null, false);
065: fail("Class cannot be null");
066: } catch (IllegalArgumentException x) {
067: }
068:
069: try {
070: MBeanServerInvocationHandler.newProxyInstance(server, name,
071: LocalService.class, false);
072: fail("Class must be an interface");
073: } catch (IllegalArgumentException x) {
074: }
075: }
076:
077: public void testMBeanNotAnEmitter() throws Exception {
078: MBeanServer server = newMBeanServer();
079: ObjectName name = new ObjectName("domain:key=value");
080: LocalService mbean = new LocalService();
081: server.registerMBean(mbean, name);
082:
083: NotificationEmitter emitter = (NotificationEmitter) MBeanServerInvocationHandler
084: .newProxyInstance(server, name,
085: LocalServiceMBean.class, true);
086:
087: try {
088: emitter.addNotificationListener(new TestListener(), null,
089: null);
090: fail("The MBean is not a NotificationEmitter");
091: } catch (IllegalArgumentException x) {
092: }
093: }
094:
095: public void testDeregisteredMBean() throws Exception {
096: MBeanServer server = newMBeanServer();
097: ObjectName name = new ObjectName("domain:key=value");
098: LocalService mbean = new LocalService();
099: server.registerMBean(mbean, name);
100:
101: // Check what the proxy throws if the ObjectName is removed from the server
102: LocalServiceMBean proxy = (LocalServiceMBean) MBeanServerInvocationHandler
103: .newProxyInstance(server, name,
104: LocalServiceMBean.class, false);
105: server.unregisterMBean(name);
106: try {
107: proxy.throwCheckedException();
108: fail();
109: } catch (NamingException x) {
110: fail("Expecting an InstanceNotFoundException");
111: } catch (UndeclaredThrowableException x) {
112: Throwable xx = x.getUndeclaredThrowable();
113: if (!(xx instanceof InstanceNotFoundException))
114: fail("Expecting an InstanceNotFoundException");
115: }
116: }
117:
118: public void testCheckedException() throws Exception {
119: MBeanServer server = newMBeanServer();
120: ObjectName name = new ObjectName("domain:key=value");
121: LocalService mbean = new LocalService();
122: server.registerMBean(mbean, name);
123:
124: LocalServiceMBean proxy = (LocalServiceMBean) MBeanServerInvocationHandler
125: .newProxyInstance(server, name,
126: LocalServiceMBean.class, false);
127: try {
128: proxy.throwCheckedException();
129: fail();
130: } catch (NamingException x) {
131: }
132: }
133:
134: public void testMBeanException() throws Exception {
135: MBeanServer server = newMBeanServer();
136: ObjectName name = new ObjectName("domain:key=value");
137: LocalService mbean = new LocalService();
138: server.registerMBean(mbean, name);
139:
140: LocalServiceMBean proxy = (LocalServiceMBean) MBeanServerInvocationHandler
141: .newProxyInstance(server, name,
142: LocalServiceMBean.class, false);
143: try {
144: proxy.throwMBeanException();
145: fail();
146: } catch (MBeanException x) {
147: }
148: }
149:
150: public void testRuntimeException() throws Exception {
151: MBeanServer server = newMBeanServer();
152: ObjectName name = new ObjectName("domain:key=value");
153: LocalService mbean = new LocalService();
154: server.registerMBean(mbean, name);
155:
156: LocalServiceMBean proxy = (LocalServiceMBean) MBeanServerInvocationHandler
157: .newProxyInstance(server, name,
158: LocalServiceMBean.class, false);
159: try {
160: proxy.throwNullPointerException();
161: fail();
162: } catch (NullPointerException x) {
163: }
164: }
165:
166: public void testError() throws Exception {
167: MBeanServer server = newMBeanServer();
168: ObjectName name = new ObjectName("domain:key=value");
169: LocalService mbean = new LocalService();
170: server.registerMBean(mbean, name);
171:
172: LocalServiceMBean proxy = (LocalServiceMBean) MBeanServerInvocationHandler
173: .newProxyInstance(server, name,
174: LocalServiceMBean.class, false);
175: try {
176: proxy.throwError();
177: fail();
178: } catch (Error x) {
179: }
180: }
181:
182: public void testNotificationBroadcasterProxy() throws Exception {
183: MBeanServer server = newMBeanServer();
184: ObjectName name = new ObjectName("domain:key=value");
185: LocalBroadcasterService mbean = new LocalBroadcasterService();
186: server.registerMBean(mbean, name);
187:
188: // The returned interface should be NotificationEmitter, even though the MBean only implements NotificationBroadcaster
189: NotificationEmitter proxy = (NotificationEmitter) MBeanServerInvocationHandler
190: .newProxyInstance(server, name,
191: NotificationBroadcaster.class, true);
192: assertNotNull(proxy);
193: }
194:
195: public void testAddNotificationListener() throws Exception {
196: MBeanServer server = newMBeanServer();
197: ObjectName name = new ObjectName("domain:key=value");
198: LocalEmitterService mbean = new LocalEmitterService();
199: server.registerMBean(mbean, name);
200:
201: NotificationEmitter proxy = (NotificationEmitter) MBeanServerInvocationHandler
202: .newProxyInstance(server, name,
203: NotificationEmitter.class, true);
204: TestListener listener = new TestListener();
205: proxy.addNotificationListener(listener, null, null);
206: mbean.test();
207: if (!listener.received)
208: fail();
209: }
210:
211: public void testGetNotificationInfo() throws Exception {
212: MBeanServer server = newMBeanServer();
213: ObjectName name = new ObjectName("domain:key=value");
214: LocalEmitterService mbean = new LocalEmitterService();
215: server.registerMBean(mbean, name);
216:
217: NotificationEmitter proxy = (NotificationEmitter) MBeanServerInvocationHandler
218: .newProxyInstance(server, name,
219: NotificationEmitter.class, true);
220: MBeanNotificationInfo[] infos = proxy.getNotificationInfo();
221: if (!infos[0].getDescription().equals(LocalEmitterService.DESC))
222: fail();
223: }
224:
225: public void testSimpleRemoveNotificationListener() throws Exception {
226: MBeanServer server = newMBeanServer();
227: ObjectName name = new ObjectName("domain:key=value");
228: LocalEmitterService mbean = new LocalEmitterService();
229: server.registerMBean(mbean, name);
230:
231: NotificationEmitter proxy = (NotificationEmitter) MBeanServerInvocationHandler
232: .newProxyInstance(server, name,
233: NotificationEmitter.class, true);
234: TestListener listener = new TestListener();
235: proxy.addNotificationListener(listener, null, null);
236: proxy.removeNotificationListener(listener);
237: mbean.test();
238: if (listener.received)
239: fail();
240: }
241:
242: public void testRemoveNotificationListener() throws Exception {
243: MBeanServer server = newMBeanServer();
244: ObjectName name = new ObjectName("domain:key=value");
245: LocalEmitterService mbean = new LocalEmitterService();
246: server.registerMBean(mbean, name);
247:
248: NotificationEmitter proxy = (NotificationEmitter) MBeanServerInvocationHandler
249: .newProxyInstance(server, name,
250: NotificationEmitter.class, true);
251: TestListener listener = new TestListener();
252: TestFilter filter = new TestFilter();
253: Object handback = new Object();
254: proxy.addNotificationListener(listener, filter, handback);
255: proxy.removeNotificationListener(listener, filter, handback);
256: mbean.test();
257: if (listener.received)
258: fail();
259: }
260:
261: public void testRemoveMultiNotificationListener() throws Exception {
262: MBeanServer server = newMBeanServer();
263: ObjectName name = new ObjectName("domain:key=value");
264: LocalEmitterService mbean = new LocalEmitterService();
265: server.registerMBean(mbean, name);
266:
267: NotificationEmitter proxy = (NotificationEmitter) MBeanServerInvocationHandler
268: .newProxyInstance(server, name,
269: NotificationEmitter.class, true);
270: TestListener listener1 = new TestListener();
271: TestFilter filter = new TestFilter();
272: Object handback = new Object();
273: proxy.addNotificationListener(listener1, filter, handback);
274:
275: TestListener listener2 = new TestListener();
276: proxy.addNotificationListener(listener2, null, null);
277:
278: mbean.test();
279: if (!listener1.received)
280: fail();
281: if (!listener2.received)
282: fail();
283:
284: try {
285: proxy.removeNotificationListener(listener2, filter,
286: handback);
287: fail("Listener is not registered");
288: } catch (ListenerNotFoundException x) {
289: }
290:
291: proxy.removeNotificationListener(listener2, null, null);
292: listener1.received = false;
293: listener2.received = false;
294:
295: mbean.test();
296: if (!listener1.received)
297: fail();
298: if (listener2.received)
299: fail();
300: }
301:
302: public void testRemoteExceptionWithRemoteInterface()
303: throws Exception {
304: MBeanServer server = newMBeanServer();
305: ObjectName name = new ObjectName("domain:key=value");
306: LocalService mbean = new LocalService();
307: server.registerMBean(mbean, name);
308:
309: JMXServiceURL url = new JMXServiceURL(
310: "service:jmx:rmi://localhost");
311: JMXConnectorServer cntorServer = JMXConnectorServerFactory
312: .newJMXConnectorServer(url, null, server);
313: cntorServer.start();
314: JMXConnector cntor = JMXConnectorFactory.connect(cntorServer
315: .getAddress());
316: MBeanServerConnection mbsc = cntor.getMBeanServerConnection();
317:
318: RemoteService remoteMBean = (RemoteService) MBeanServerInvocationHandler
319: .newProxyInstance(mbsc, name, RemoteService.class,
320: false);
321:
322: // Close everything to get IOException
323: cntor.close();
324: cntorServer.stop();
325:
326: try {
327: remoteMBean.throwCheckedException();
328: fail("Must not be able to connect");
329: } catch (IOException x) {
330: }
331: }
332:
333: public void testRemoteExceptionWithLocalInterface()
334: throws Exception {
335: MBeanServer server = newMBeanServer();
336: ObjectName name = new ObjectName("domain:key=value");
337: LocalService mbean = new LocalService();
338: server.registerMBean(mbean, name);
339:
340: JMXServiceURL url = new JMXServiceURL(
341: "service:jmx:rmi://localhost");
342: JMXConnectorServer cntorServer = JMXConnectorServerFactory
343: .newJMXConnectorServer(url, null, server);
344: cntorServer.start();
345: JMXConnector cntor = JMXConnectorFactory.connect(cntorServer
346: .getAddress());
347: MBeanServerConnection mbsc = cntor.getMBeanServerConnection();
348:
349: LocalServiceMBean remoteMBean = (LocalServiceMBean) MBeanServerInvocationHandler
350: .newProxyInstance(mbsc, name, LocalServiceMBean.class,
351: false);
352:
353: // Close everything to get IOException
354: cntor.close();
355: cntorServer.stop();
356:
357: // Now try the local interface
358: try {
359: remoteMBean.throwCheckedException();
360: fail("Must not be able to connect");
361: } catch (UndeclaredThrowableException x) {
362: Throwable xx = x.getUndeclaredThrowable();
363: if (!(xx instanceof IOException))
364: fail();
365: }
366: }
367:
368: public void testRemoteCheckedException() throws Exception {
369: MBeanServer server = newMBeanServer();
370: ObjectName name = new ObjectName("domain:key=value");
371: LocalService mbean = new LocalService();
372: server.registerMBean(mbean, name);
373:
374: JMXServiceURL url = new JMXServiceURL(
375: "service:jmx:rmi://localhost");
376: JMXConnectorServer cntorServer = JMXConnectorServerFactory
377: .newJMXConnectorServer(url, null, server);
378: cntorServer.start();
379: JMXConnector cntor = JMXConnectorFactory.connect(cntorServer
380: .getAddress());
381: MBeanServerConnection mbsc = cntor.getMBeanServerConnection();
382:
383: LocalServiceMBean remoteMBean = (LocalServiceMBean) MBeanServerInvocationHandler
384: .newProxyInstance(mbsc, name, LocalServiceMBean.class,
385: false);
386: try {
387: remoteMBean.throwCheckedException();
388: fail();
389: } catch (NamingException x) {
390: }
391: }
392:
393: public interface LocalServiceMBean {
394: public void throwCheckedException() throws NamingException;
395:
396: public void throwMBeanException() throws MBeanException;
397:
398: public void throwNullPointerException();
399:
400: public void throwError();
401: }
402:
403: public interface RemoteService {
404: public void throwCheckedException() throws NamingException,
405: IOException;
406:
407: public void throwMBeanException() throws MBeanException,
408: IOException;
409:
410: public void throwNullPointerException() throws IOException;
411:
412: public void throwError() throws IOException;
413: }
414:
415: public class LocalService implements LocalServiceMBean {
416: public void throwCheckedException() throws NamingException {
417: throw new NamingException();
418: }
419:
420: public void throwMBeanException() throws MBeanException {
421: throw new MBeanException(new Exception());
422: }
423:
424: public void throwNullPointerException() {
425: throw new NullPointerException();
426: }
427:
428: public void throwError() {
429: throw new Error();
430: }
431: }
432:
433: public class LocalBroadcasterService extends LocalService implements
434: NotificationBroadcaster {
435: private NotificationBroadcasterSupport support = new NotificationBroadcasterSupport();
436: static final String TYPE = "test.notification";
437: static final String DESC = "Test Notification";
438: private long sequence;
439:
440: /**
441: * @see javax.management.NotificationBroadcaster#addNotificationListener(NotificationListener, NotificationFilter, Object)
442: */
443: public void addNotificationListener(
444: NotificationListener listener,
445: NotificationFilter filter, Object handback)
446: throws IllegalArgumentException {
447: support.addNotificationListener(listener, filter, handback);
448: }
449:
450: /**
451: * @see javax.management.NotificationBroadcaster#getNotificationInfo()
452: */
453: public MBeanNotificationInfo[] getNotificationInfo() {
454: return new MBeanNotificationInfo[] { new MBeanNotificationInfo(
455: new String[] { TYPE },
456: Notification.class.getName(), DESC), };
457: }
458:
459: /**
460: * @see javax.management.NotificationBroadcaster#removeNotificationListener(NotificationListener)
461: */
462: public void removeNotificationListener(
463: NotificationListener listener)
464: throws ListenerNotFoundException {
465: support.removeNotificationListener(listener);
466: }
467:
468: public void test() {
469: Notification notification = new Notification(TYPE, this ,
470: ++sequence, System.currentTimeMillis(), DESC);
471: support.sendNotification(notification);
472: }
473: }
474:
475: public class LocalEmitterService extends LocalService implements
476: NotificationEmitter {
477: private NotificationBroadcasterSupport support = new NotificationBroadcasterSupport();
478: static final String TYPE = "test.notification";
479: static final String DESC = "Test Notification";
480: private long sequence;
481:
482: public void addNotificationListener(
483: NotificationListener listener,
484: NotificationFilter filter, Object handback)
485: throws IllegalArgumentException {
486: support.addNotificationListener(listener, filter, handback);
487: }
488:
489: public MBeanNotificationInfo[] getNotificationInfo() {
490: return new MBeanNotificationInfo[] { new MBeanNotificationInfo(
491: new String[] { TYPE },
492: Notification.class.getName(), DESC), };
493: }
494:
495: public void removeNotificationListener(
496: NotificationListener listener)
497: throws ListenerNotFoundException {
498: support.removeNotificationListener(listener);
499: }
500:
501: public void removeNotificationListener(
502: NotificationListener listener,
503: NotificationFilter filter, Object handback)
504: throws ListenerNotFoundException {
505: support.removeNotificationListener(listener, filter,
506: handback);
507: }
508:
509: public void test() {
510: Notification notification = new Notification(TYPE, this ,
511: ++sequence, System.currentTimeMillis(), DESC);
512: support.sendNotification(notification);
513: }
514: }
515:
516: public class TestListener implements NotificationListener {
517: boolean received = false;
518:
519: public void handleNotification(Notification notification,
520: Object handback) {
521: received = true;
522: }
523: }
524:
525: public class TestFilter implements NotificationFilter {
526: public boolean isNotificationEnabled(Notification notification) {
527: return notification.getType().equals(
528: LocalEmitterService.TYPE);
529: }
530: }
531: }
|