1
2
3
4
5
6
7
8
9
10 package org.mule.module.management.agent;
11
12 import org.mule.AbstractAgent;
13 import org.mule.api.MuleException;
14 import org.mule.api.MuleRuntimeException;
15 import org.mule.api.context.notification.MuleContextNotificationListener;
16 import org.mule.api.lifecycle.InitialisationException;
17 import org.mule.api.model.Model;
18 import org.mule.api.service.Service;
19 import org.mule.api.transport.Connector;
20 import org.mule.api.transport.MessageReceiver;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.construct.AbstractFlowConstruct;
23 import org.mule.context.notification.MuleContextNotification;
24 import org.mule.context.notification.NotificationException;
25 import org.mule.management.stats.FlowConstructStatistics;
26 import org.mule.module.management.i18n.ManagementMessages;
27 import org.mule.module.management.mbean.ApplicationService;
28 import org.mule.module.management.mbean.ConnectorService;
29 import org.mule.module.management.mbean.ConnectorServiceMBean;
30 import org.mule.module.management.mbean.EndpointService;
31 import org.mule.module.management.mbean.EndpointServiceMBean;
32 import org.mule.module.management.mbean.FlowConstructService;
33 import org.mule.module.management.mbean.FlowConstructServiceMBean;
34 import org.mule.module.management.mbean.ModelService;
35 import org.mule.module.management.mbean.ModelServiceMBean;
36 import org.mule.module.management.mbean.MuleConfigurationService;
37 import org.mule.module.management.mbean.MuleConfigurationServiceMBean;
38 import org.mule.module.management.mbean.MuleService;
39 import org.mule.module.management.mbean.MuleServiceMBean;
40 import org.mule.module.management.mbean.ServiceService;
41 import org.mule.module.management.mbean.ServiceServiceMBean;
42 import org.mule.module.management.mbean.StatisticsService;
43 import org.mule.module.management.mbean.StatisticsServiceMBean;
44 import org.mule.module.management.support.AutoDiscoveryJmxSupportFactory;
45 import org.mule.module.management.support.JmxSupport;
46 import org.mule.module.management.support.JmxSupportFactory;
47 import org.mule.module.management.support.SimplePasswordJmxAuthenticator;
48 import org.mule.transport.AbstractConnector;
49 import org.mule.util.StringUtils;
50
51 import java.lang.management.ManagementFactory;
52 import java.net.URI;
53 import java.rmi.RemoteException;
54 import java.rmi.registry.LocateRegistry;
55 import java.rmi.registry.Registry;
56 import java.rmi.server.ExportException;
57 import java.util.Collections;
58 import java.util.HashMap;
59 import java.util.Map;
60 import java.util.Set;
61 import java.util.concurrent.atomic.AtomicBoolean;
62
63 import javax.management.InstanceAlreadyExistsException;
64 import javax.management.MBeanRegistrationException;
65 import javax.management.MBeanServer;
66 import javax.management.MBeanServerFactory;
67 import javax.management.MalformedObjectNameException;
68 import javax.management.NotCompliantMBeanException;
69 import javax.management.ObjectName;
70 import javax.management.remote.JMXConnectorServer;
71 import javax.management.remote.JMXConnectorServerFactory;
72 import javax.management.remote.JMXServiceURL;
73 import javax.management.remote.rmi.RMIConnectorServer;
74
75 import org.apache.commons.logging.Log;
76 import org.apache.commons.logging.LogFactory;
77
78
79
80
81 public class JmxAgent extends AbstractAgent
82 {
83 public static final String NAME = "jmx-agent";
84
85 public static final String DEFAULT_REMOTING_URI = "service:jmx:rmi:///jndi/rmi://localhost:1099/server";
86
87
88 public static final Map<String, String> DEFAULT_CONNECTOR_SERVER_PROPERTIES;
89
90
91
92
93 public static final String DEFAULT_JMX_AUTHENTICATOR = SimplePasswordJmxAuthenticator.class.getName();
94
95
96
97
98 protected static final Log logger = LogFactory.getLog(JmxAgent.class);
99
100
101
102
103 protected boolean locateServer = true;
104
105 protected boolean containerMode = true;
106
107
108 private boolean createServer = false;
109 private String connectorServerUrl;
110 private MBeanServer mBeanServer;
111 private JMXConnectorServer connectorServer;
112 private Map<String, Object> connectorServerProperties = null;
113 private boolean enableStatistics = true;
114 private final AtomicBoolean serverCreated = new AtomicBoolean(false);
115 private final AtomicBoolean initialized = new AtomicBoolean(false);
116
117 private JmxSupportFactory jmxSupportFactory = AutoDiscoveryJmxSupportFactory.getInstance();
118 private JmxSupport jmxSupport = jmxSupportFactory.getJmxSupport();
119 private ConfigurableJMXAuthenticator jmxAuthenticator;
120
121
122 private Registry rmiRegistry;
123 private boolean createRmiRegistry = true;
124
125
126
127
128 private Map<String, String> credentials = new HashMap<String, String>();
129
130 static
131 {
132 Map<String, String> props = new HashMap<String, String>(1);
133 props.put(RMIConnectorServer.JNDI_REBIND_ATTRIBUTE, "true");
134 DEFAULT_CONNECTOR_SERVER_PROPERTIES = Collections.unmodifiableMap(props);
135 }
136
137 public JmxAgent()
138 {
139 super(NAME);
140 connectorServerProperties = new HashMap<String, Object>(DEFAULT_CONNECTOR_SERVER_PROPERTIES);
141 }
142
143 @Override
144 public String getDescription()
145 {
146 if (connectorServerUrl != null)
147 {
148 return name + ": " + connectorServerUrl;
149 }
150 else
151 {
152 return "JMX Agent";
153 }
154 }
155
156
157
158
159 public void initialise() throws InitialisationException
160 {
161 if (initialized.get())
162 {
163 return;
164 }
165
166 this.containerMode = muleContext.getConfiguration().isContainerMode();
167
168 try
169 {
170 Object agent = muleContext.getRegistry().lookupObject(this.getClass());
171
172 if (agent == this && this.initialized.get())
173 {
174 if (logger.isDebugEnabled())
175 {
176 logger.debug("Found an existing JMX agent in the registry, we're done here.");
177 }
178 return;
179 }
180 }
181 catch (Exception e)
182 {
183 throw new InitialisationException(e, this);
184 }
185
186
187 if (mBeanServer == null && createServer)
188 {
189
190 mBeanServer = MBeanServerFactory.createMBeanServer();
191 serverCreated.set(true);
192 }
193
194 if (mBeanServer == null && locateServer)
195 {
196 mBeanServer = ManagementFactory.getPlatformMBeanServer();
197 }
198
199 if (mBeanServer == null)
200 {
201 throw new InitialisationException(ManagementMessages.cannotLocateOrCreateServer(), this);
202 }
203
204 if (StringUtils.isBlank(muleContext.getConfiguration().getId()))
205 {
206
207 throw new IllegalArgumentException(
208 "Manager ID is mandatory when running with JmxAgent. Give your Mule configuration a valid ID.");
209 }
210
211 try
212 {
213
214 muleContext.registerListener(new MuleContextStartedListener());
215
216 muleContext.registerListener(new MuleContextStoppedListener());
217 }
218 catch (NotificationException e)
219 {
220 throw new InitialisationException(e, this);
221 }
222 initialized.compareAndSet(false, true);
223 }
224
225 protected void initRMI() throws Exception
226 {
227 String connectUri = (connectorServerUrl != null ? connectorServerUrl : StringUtils.EMPTY);
228 if (connectUri.contains("jmx:rmi"))
229 {
230 int i = connectUri.lastIndexOf("rmi://");
231 URI uri = new URI(connectUri.substring(i));
232 if (rmiRegistry == null)
233 {
234 try
235 {
236 if (isCreateRmiRegistry())
237 {
238 try
239 {
240 rmiRegistry = LocateRegistry.createRegistry(uri.getPort());
241 }
242 catch (ExportException e)
243 {
244 logger.info("Registry on " + uri + " already bound. Attempting to use that instead");
245 rmiRegistry = LocateRegistry.getRegistry(uri.getHost(), uri.getPort());
246 }
247 }
248 else
249 {
250 rmiRegistry = LocateRegistry.getRegistry(uri.getHost(), uri.getPort());
251 }
252 }
253 catch (RemoteException e)
254 {
255 throw new InitialisationException(e, this);
256 }
257 }
258 }
259 }
260
261 public void start() throws MuleException
262 {
263 try
264 {
265
266 initRMI();
267 if (connectorServerUrl == null)
268 {
269 return;
270 }
271
272 logger.info("Creating and starting JMX agent connector Server");
273 JMXServiceURL url = new JMXServiceURL(connectorServerUrl);
274 if (connectorServerProperties == null)
275 {
276 connectorServerProperties = new HashMap<String, Object>(DEFAULT_CONNECTOR_SERVER_PROPERTIES);
277 }
278 if (!credentials.isEmpty())
279 {
280 connectorServerProperties.put(JMXConnectorServer.AUTHENTICATOR,
281 this.getJmxAuthenticator());
282 }
283 connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url,
284 connectorServerProperties,
285 mBeanServer);
286 connectorServer.start();
287 }
288 catch (ExportException e)
289 {
290 throw new JmxManagementException(CoreMessages.failedToStart("Jmx Agent"), e);
291 }
292 catch (Exception e)
293 {
294 throw new JmxManagementException(CoreMessages.failedToStart("Jmx Agent"), e);
295 }
296 }
297
298 public void stop() throws MuleException
299 {
300 if (connectorServer != null)
301 {
302 try
303 {
304 connectorServer.stop();
305 }
306 catch (Exception e)
307 {
308 throw new JmxManagementException(CoreMessages.failedToStop("Jmx Connector"), e);
309 }
310 }
311 }
312
313
314
315
316 public void dispose()
317 {
318 unregisterMBeansIfNecessary();
319 if (serverCreated.get())
320 {
321 MBeanServerFactory.releaseMBeanServer(mBeanServer);
322 }
323 mBeanServer = null;
324 serverCreated.compareAndSet(true, false);
325 initialized.set(false);
326 }
327
328
329
330
331
332
333 protected void registerWrapperService() throws MuleException
334 {
335
336 final WrapperManagerAgent wmAgent = new WrapperManagerAgent();
337 if (muleContext.getRegistry().lookupAgent(wmAgent.getName()) == null)
338 {
339 muleContext.getRegistry().registerAgent(wmAgent);
340 }
341 }
342
343 protected void registerStatisticsService() throws NotCompliantMBeanException, MBeanRegistrationException,
344 InstanceAlreadyExistsException, MalformedObjectNameException
345 {
346 ObjectName on = jmxSupport.getObjectName(String.format("%s:%s", jmxSupport.getDomainName(muleContext, !containerMode), StatisticsServiceMBean.DEFAULT_JMX_NAME));
347 StatisticsService service = new StatisticsService();
348 service.setMuleContext(muleContext);
349 service.setEnabled(isEnableStatistics());
350 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, StatisticsServiceMBean.class, muleContext.getExecutionClassLoader());
351 logger.debug("Registering statistics with name: " + on);
352 mBeanServer.registerMBean(mBean, on);
353 }
354
355 protected void registerModelServices() throws NotCompliantMBeanException, MBeanRegistrationException,
356 InstanceAlreadyExistsException, MalformedObjectNameException
357 {
358 for (Model model : muleContext.getRegistry().lookupObjects(Model.class))
359 {
360 ModelServiceMBean service = new ModelService(model);
361 String rawName = service.getName() + "(" + service.getType() + ")";
362 String name = jmxSupport.escape(rawName);
363 final String jmxName = String.format("%s:%s%s", jmxSupport.getDomainName(muleContext, !containerMode), ModelServiceMBean.DEFAULT_JMX_NAME_PREFIX, name);
364 ObjectName on = jmxSupport.getObjectName(jmxName);
365 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, ModelServiceMBean.class, muleContext.getExecutionClassLoader());
366 logger.debug("Registering model with name: " + on);
367 mBeanServer.registerMBean(mBean, on);
368 }
369 }
370
371 protected void registerMuleService() throws NotCompliantMBeanException, MBeanRegistrationException,
372 InstanceAlreadyExistsException, MalformedObjectNameException
373 {
374 ObjectName on = jmxSupport.getObjectName(String.format("%s:%s", jmxSupport.getDomainName(muleContext, !containerMode), MuleServiceMBean.DEFAULT_JMX_NAME));
375 if (muleContext.getConfiguration().isContainerMode() && mBeanServer.isRegistered(on))
376 {
377
378 return;
379 }
380 MuleService service = new MuleService(muleContext);
381 ClassloaderSwitchingMBeanWrapper serviceMBean = new ClassloaderSwitchingMBeanWrapper(service, MuleServiceMBean.class, muleContext.getExecutionClassLoader());
382 logger.debug("Registering mule with name: " + on);
383 mBeanServer.registerMBean(serviceMBean, on);
384 }
385
386 protected void registerConfigurationService() throws NotCompliantMBeanException, MBeanRegistrationException,
387 InstanceAlreadyExistsException, MalformedObjectNameException
388 {
389 ObjectName on = jmxSupport.getObjectName(String.format("%s:%s", jmxSupport.getDomainName(muleContext, !containerMode), MuleConfigurationServiceMBean.DEFAULT_JMX_NAME));
390 MuleConfigurationServiceMBean service = new MuleConfigurationService(muleContext.getConfiguration());
391 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, MuleConfigurationServiceMBean.class, muleContext.getExecutionClassLoader());
392 logger.debug("Registering configuration with name: " + on);
393 mBeanServer.registerMBean(mBean, on);
394 }
395
396 protected void registerServiceServices() throws NotCompliantMBeanException, MBeanRegistrationException,
397 InstanceAlreadyExistsException, MalformedObjectNameException
398 {
399 for (Service service : muleContext.getRegistry().lookupObjects(Service.class))
400 {
401 final String rawName = service.getName();
402 final String escapedName = jmxSupport.escape(rawName);
403 final String jmxName = String.format("%s:%s%s",
404 jmxSupport.getDomainName(muleContext, !containerMode),
405 ServiceServiceMBean.DEFAULT_JMX_NAME_PREFIX, escapedName);
406 ObjectName on = jmxSupport.getObjectName(jmxName);
407
408 ServiceServiceMBean serviceMBean = new ServiceService(rawName, muleContext);
409 ClassloaderSwitchingMBeanWrapper wrapper = new ClassloaderSwitchingMBeanWrapper(serviceMBean, ServiceServiceMBean.class, muleContext.getExecutionClassLoader());
410
411 logger.debug("Registering service with name: " + on);
412 mBeanServer.registerMBean(wrapper, on);
413 }
414 }
415
416 protected void registerFlowConstructServices() throws NotCompliantMBeanException, MBeanRegistrationException,
417 InstanceAlreadyExistsException, MalformedObjectNameException
418 {
419 for (AbstractFlowConstruct flowConstruct : muleContext.getRegistry().lookupObjects(AbstractFlowConstruct.class))
420 {
421 final String rawName = flowConstruct.getName();
422 final String name = jmxSupport.escape(rawName);
423 final String jmxName = String.format("%s:type=%s,name=%s", jmxSupport.getDomainName(muleContext, !containerMode), flowConstruct.getConstructType(), name);
424 ObjectName on = jmxSupport.getObjectName(jmxName);
425 FlowConstructServiceMBean fcMBean = new FlowConstructService(flowConstruct.getConstructType(), rawName, muleContext, flowConstruct.getStatistics());
426 ClassloaderSwitchingMBeanWrapper wrapper = new ClassloaderSwitchingMBeanWrapper(fcMBean, FlowConstructServiceMBean.class, muleContext.getExecutionClassLoader());
427 logger.debug("Registering service with name: " + on);
428 mBeanServer.registerMBean(wrapper, on);
429 }
430 }
431
432 protected void registerApplicationServices() throws NotCompliantMBeanException, MBeanRegistrationException,
433 InstanceAlreadyExistsException, MalformedObjectNameException
434 {
435 FlowConstructStatistics appStats = muleContext.getStatistics().getApplicationStatistics();
436 if (appStats != null)
437 {
438 final String rawName = appStats.getName();
439 final String name = jmxSupport.escape(rawName);
440 final String jmxName = String.format("%s:type=%s,name=%s", jmxSupport.getDomainName(muleContext, !containerMode), appStats.getFlowConstructType(), name);
441 ObjectName on = jmxSupport.getObjectName(jmxName);
442 FlowConstructServiceMBean fcMBean = new ApplicationService(appStats.getFlowConstructType(), rawName, muleContext,appStats);
443 ClassloaderSwitchingMBeanWrapper wrapper = new ClassloaderSwitchingMBeanWrapper(fcMBean, FlowConstructServiceMBean.class, muleContext.getExecutionClassLoader());
444 logger.debug("Registering application statistics with name: " + on);
445 mBeanServer.registerMBean(wrapper, on);
446 }
447 }
448
449 protected void registerEndpointServices() throws NotCompliantMBeanException, MBeanRegistrationException,
450 InstanceAlreadyExistsException, MalformedObjectNameException
451 {
452 for (Connector connector : muleContext.getRegistry().lookupObjects(Connector.class))
453 {
454 if (connector instanceof AbstractConnector)
455 {
456 for (MessageReceiver messageReceiver : ((AbstractConnector) connector).getReceivers().values())
457 {
458 EndpointServiceMBean service = new EndpointService(messageReceiver);
459
460 String fullName = buildFullyQualifiedEndpointName(service, connector);
461 if (logger.isInfoEnabled())
462 {
463 logger.info("Attempting to register service with name: " + fullName);
464 }
465
466 ObjectName on = jmxSupport.getObjectName(fullName);
467 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, EndpointServiceMBean.class, muleContext.getExecutionClassLoader());
468 mBeanServer.registerMBean(mBean, on);
469 if (logger.isInfoEnabled())
470 {
471 logger.info("Registered Endpoint Service with name: " + on);
472 }
473 }
474 }
475 else
476 {
477 logger.warn("Connector: " + connector
478 + " is not an istance of AbstractConnector, cannot obtain Endpoint MBeans from it");
479 }
480 }
481 }
482
483 protected String buildFullyQualifiedEndpointName(EndpointServiceMBean mBean, Connector connector)
484 {
485 String rawName = jmxSupport.escape(mBean.getName());
486
487 StringBuilder fullName = new StringBuilder(128);
488 fullName.append(jmxSupport.getDomainName(muleContext, !containerMode));
489 fullName.append(":type=Endpoint,service=");
490 fullName.append(jmxSupport.escape(mBean.getComponentName()));
491 fullName.append(",connector=");
492 fullName.append(connector.getName());
493 fullName.append(",name=");
494 fullName.append(rawName);
495 return fullName.toString();
496 }
497
498 protected void registerConnectorServices() throws MalformedObjectNameException,
499 NotCompliantMBeanException, MBeanRegistrationException, InstanceAlreadyExistsException
500 {
501 for (Connector connector : muleContext.getRegistry().lookupObjects(Connector.class))
502 {
503 ConnectorServiceMBean service = new ConnectorService(connector);
504 final String rawName = service.getName();
505 final String name = jmxSupport.escape(rawName);
506 final String jmxName = String.format("%s:%s%s", jmxSupport.getDomainName(muleContext, !containerMode), ConnectorServiceMBean.DEFAULT_JMX_NAME_PREFIX, name);
507 if (logger.isDebugEnabled())
508 {
509 logger.debug("Attempting to register service with name: " + jmxName);
510 }
511 ObjectName oName = jmxSupport.getObjectName(jmxName);
512 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, ConnectorServiceMBean.class, muleContext.getExecutionClassLoader());
513 mBeanServer.registerMBean(mBean, oName);
514 logger.info("Registered Connector Service with name " + oName);
515 }
516 }
517
518 public boolean isCreateServer()
519 {
520 return createServer;
521 }
522
523 public void setCreateServer(boolean createServer)
524 {
525 this.createServer = createServer;
526 }
527
528 public boolean isLocateServer()
529 {
530 return locateServer;
531 }
532
533 public void setLocateServer(boolean locateServer)
534 {
535 this.locateServer = locateServer;
536 }
537
538 public String getConnectorServerUrl()
539 {
540 return connectorServerUrl;
541 }
542
543 public void setConnectorServerUrl(String connectorServerUrl)
544 {
545 this.connectorServerUrl = connectorServerUrl;
546 }
547
548 public boolean isEnableStatistics()
549 {
550 return enableStatistics;
551 }
552
553 public void setEnableStatistics(boolean enableStatistics)
554 {
555 this.enableStatistics = enableStatistics;
556 }
557
558 public MBeanServer getMBeanServer()
559 {
560 return mBeanServer;
561 }
562
563 public void setMBeanServer(MBeanServer mBeanServer)
564 {
565 this.mBeanServer = mBeanServer;
566 }
567
568 public Map<String, Object> getConnectorServerProperties()
569 {
570 return connectorServerProperties;
571 }
572
573
574
575
576
577
578
579
580 public void setConnectorServerProperties(Map<String, Object> connectorServerProperties)
581 {
582 this.connectorServerProperties = connectorServerProperties;
583 }
584
585 public JmxSupportFactory getJmxSupportFactory()
586 {
587 return jmxSupportFactory;
588 }
589
590 public void setJmxSupportFactory(JmxSupportFactory jmxSupportFactory)
591 {
592 this.jmxSupportFactory = jmxSupportFactory;
593 }
594
595
596
597
598
599
600
601 public void setCredentials(final Map<String, String> newCredentials)
602 {
603 this.credentials.clear();
604 if (newCredentials != null && !newCredentials.isEmpty())
605 {
606 this.credentials.putAll(newCredentials);
607 }
608 }
609
610 protected void unregisterMBeansIfNecessary()
611 {
612 unregisterMBeansIfNecessary(false);
613 }
614
615
616
617
618 protected void unregisterMBeansIfNecessary(boolean containerMode)
619 {
620 if (mBeanServer == null)
621 {
622 return;
623 }
624
625 try
626 {
627
628
629
630 final String domain = jmxSupport.getDomainName(muleContext, false);
631 ObjectName query = jmxSupport.getObjectName(domain + ":*");
632 Set<ObjectName> mbeans = mBeanServer.queryNames(query, null);
633 while (!mbeans.isEmpty())
634 {
635 ObjectName name = mbeans.iterator().next();
636 try
637 {
638 if (!(containerMode && MuleServiceMBean.DEFAULT_JMX_NAME.equals(name.getCanonicalKeyPropertyListString())))
639 {
640 mBeanServer.unregisterMBean(name);
641 }
642 }
643 catch (Exception e)
644 {
645 logger.warn(String.format("Failed to unregister MBean: %s. Error is: %s", name, e.getMessage()));
646 }
647
648
649
650 mbeans = mBeanServer.queryNames(query, null);
651
652 if (containerMode)
653 {
654
655 mbeans.remove(jmxSupport.getObjectName(String.format("%s:%s", domain, MuleServiceMBean.DEFAULT_JMX_NAME)));
656 }
657 }
658 }
659 catch (MalformedObjectNameException e)
660 {
661 logger.warn("Failed to create ObjectName query", e);
662 }
663 }
664
665 public Registry getRmiRegistry()
666 {
667 return rmiRegistry;
668 }
669
670 public void setRmiRegistry(Registry rmiRegistry)
671 {
672 this.rmiRegistry = rmiRegistry;
673 }
674
675 public boolean isCreateRmiRegistry()
676 {
677 return createRmiRegistry;
678 }
679
680 public void setCreateRmiRegistry(boolean createRmiRegistry)
681 {
682 this.createRmiRegistry = createRmiRegistry;
683 }
684
685 protected class MuleContextStartedListener implements MuleContextNotificationListener<MuleContextNotification>
686 {
687
688 public void onNotification(MuleContextNotification notification)
689 {
690 if (notification.getAction() == MuleContextNotification.CONTEXT_STARTED)
691 {
692 try
693 {
694 registerWrapperService();
695 registerStatisticsService();
696 registerMuleService();
697 registerConfigurationService();
698 registerModelServices();
699 registerServiceServices();
700 registerFlowConstructServices();
701 registerEndpointServices();
702 registerConnectorServices();
703 registerApplicationServices();
704 }
705 catch (Exception e)
706 {
707 throw new MuleRuntimeException(CoreMessages.objectFailedToInitialise("MBeans"), e);
708 }
709 }
710 }
711 }
712
713 protected class MuleContextStoppedListener implements MuleContextNotificationListener<MuleContextNotification>
714 {
715
716 public void onNotification(MuleContextNotification notification)
717 {
718 if (notification.getAction() == MuleContextNotification.CONTEXT_STOPPED)
719 {
720 boolean containerMode = notification.getMuleContext().getConfiguration().isContainerMode();
721 unregisterMBeansIfNecessary(containerMode);
722 }
723 }
724 }
725
726 public ConfigurableJMXAuthenticator getJmxAuthenticator()
727 {
728 if (this.jmxAuthenticator == null)
729 {
730 this.jmxAuthenticator = new SimplePasswordJmxAuthenticator();
731 this.jmxAuthenticator.configure(credentials);
732 }
733 return jmxAuthenticator;
734 }
735
736 public void setJmxAuthenticator(ConfigurableJMXAuthenticator jmxAuthenticator)
737 {
738 this.jmxAuthenticator = jmxAuthenticator;
739 }
740 }