The first code shown here is the XML code that configures our Spring container.
<?xml version="1.0" encoding="UTF-8"?>
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="1099"/>
<property name="objectName" value="connector:name=rmi"/>
Note that nothing specific to publishing JMX Notifications is included in this XML configuration, though there are entries to handle remote JMX. The next source code listing shows a pretty normal Java class, but it does feature a Spring-specific interface (NotificationPublisherAware) that it implements a single method (setNotificationPublisher) for.
* Nothing in this class makes it explicitly a JMX MBean. Instead, Spring will
* expose this as an MBean. The Spring-specific NotificationPublisherAware
* interface is implemented by this class, which means that Spring will also
* allow this bean-turned-MBean to easily publish JMX notifications.
* @author Dustin
public class SomeJavaObject implements NotificationPublisherAware
private int notificationIndex = 0;
private NotificationPublisher notificationPublisher;
private String someValue = "Nada";
// empty default constructor
public String getSomeValue()
public void setSomeValue(final String aSomeValue)
buildNotification(this.someValue, aSomeValue) );
this.someValue = aSomeValue;
* Generate a Notification that will ultimately be published to interested
* @param aOldValue Value prior to setting of new value.
* @param aNewValue Value after setting of new value.
* @return Generated JMX Notification.
private Notification buildNotification(
final String aOldValue,
final String aNewValue )
final String notificationType = "dustin.jmx.spring.notification.example";
final String message = "Converting " + aOldValue + " to " + aNewValue;
final Notification notification =
new Notification( notificationType,
notification.setUserData("Blog Example #" + notificationIndex );
* This is the only method required to fully implement the
* NotificationPublisherAware interface. This method allows Spring to
* inject a NotificationPublisher into me.
* @param aPublisher The NotificationPublisher that Spring injects into me.
public void setNotificationPublisher(NotificationPublisher aPublisher)
this.notificationPublisher = aPublisher;
The above class is not an MBean by itself. Rather, Spring exposes it as an MBean because of our use of the MBeanExporter in the XML configuration. However, there were some JMX-specific classes in this class to enable Notifications. Also, as mentioned above, the Spring-specific
NotificationPublisherAwareinterface is also explicitly implemented by this class.
We need a main executable Java class to bootstrap the Spring container and to allow us the opportunity to interact and set someValue so that the JMX Notifications will occur. The source code for that class is shown next.
* Main executable designed to instantiate a Spring context and avoid exiting
* immediately so that a JMX client can listen to notifications sent from a
* Spring-exposed MBean Notification Publisher.
* This code sample requires Java SE 6 because it uses System.console() and
* @author Dustin
public class JmxSpringServerMain
* Main execution for JMX Spring Notification Publication example (server).
* @param args the command line arguments
public static void main(String aCommandLineArgs)
ConfigurableApplicationContext context =
SomeJavaObject obj = (SomeJavaObject) context.getBean("someObject");
final Console systemConsole = System.console();
if ( systemConsole != null )
final String terminateLoop = "exit";
String choice = null;
systemConsole.printf("Enter a choice: ");
choice = systemConsole.readLine();
if ( choice != null && !choice.isEmpty() )
while ( choice != null
&& !choice.equals(terminateLoop) );
"Please run this in an environment with a system console.");
The above class can be run to use the Spring container to expose SomeJavaObject as an MBean capable of sending JMX Notifications to local or remote clients. Note that Java SE 6 is required to run this example because of use of features specific to Java SE 6. When this main Java class is executed, the output will look something like the following screen snapshot (click on it to see larger version). I have entered some arbitrary values to demonstrate the JMX Notifications will be sent when we attach a JMX client later.
We can run JConsole to see if the JMX Notifications are being published. The following screen snapshot (click on it to see larger version) shows how JConsole appears when run alongside the application executed above. Note that I used Java SE 6's JConsole and that I had JConsole already running when executing the main Java application and that I had clicked on its "Subscribe" button in the MBeans Notifications section.
There are several interesting observations from this JConsole output. For one, JConsole nicely displays the timestamps I provided in the Notification as a long timestamp. Another interesting observation here is that the UserData column displays exactly the String I passed the Notification.setUserData(Object) method in the code. This only worked because I passed a String to this method that expects an Object. Had I not passed a String, I would have needed to pass a class that had a
toString()method overridden appropriately and was available to a remote JMX client to have this be a sensible value. Using a String was the easy way out for this example.
You may have noticed that I did not need to specify the "notificationPublisher" injected into the class that implements Spring's
NotificationPublisherAwareinterface. Spring apparently does this automatically without any need to explicitly specify/configure this injection. In fact, I lost more time than I care to admit trying to specify this Notification Publisher in the Spring XML configuration file because this is shown in the second edition of Spring in Action (page 483). This book is generally a nice introduction to Spring and has been very beneficial for me, but something must have changed in Spring since the writing of this section. Anyway, it seems that you should NOT explicitly configure the injection of ModelMBeanNotificationPublisher despite what is shown on page 483. By the way, if you omit that one XML snippet from this book's coverage of JMX Notifications with Spring, the remainder of the example seems to accurately describe JMX Notification Publishing via Spring.
The Spring documentation warns repeatedly that any natural JMX MBeans (objects that are MBeans before Spring exposes them as such) should NOT use Spring's JMX publication support and should instead use JMX Notification APIs directly.