I've published an activator template of how to integrate JMX into your Akka Actors. Using this method, you can look inside a running Akka application and see exactly what sort of state your actors are in. Thanks to Jamie Allen for the idea in his book, Effective Akka.
Start up Activator with the following options:
Then in another console, start up your JMX tool. In this example, we are using :
Using Java Mission Control, connect to the NettyServer application listed in the right tree view.
Go to "MBean Server" item in the tree view on the right.
Click on "MBean Browser" in the second tab at the bottom.
Open up the "jmxexample" tree folder, then "GreeterMXBean", then "/user/master". You'll see the attributes on the right.
Hit F5 a lot to refresh.
You should see this:
##Creating an MXBean with an External View Class
Exposing state through JMX is easy, as long as you play by the rules: always use an MXBean (which does not require JAR downloads over RMI), always think about thread safety when exposing internal variables, and always create a custom class that provides a view that the MXBean is happy with.
Here's a trait that exposes some state, GreetingHistory. As long as the trait ends in "MXBean", JMX is happy. It will display the properties defined in that trait.
Here's the JMX actor that implements the GreeterMXBean interface. Note that the only thing it does is receive a GreeterHistory case class, and then renders it. There is a catch, however: because the greetingHistory variable is accessed both through Akka and through a JMX thread, it must be declared as volatile so that memory access is atomic.
The actor which generates the GreetingHistory case class – the state that you want to expose – should be a parent of the JMX bean, and have a supervisor strategy that can handle JMX exceptions:
And finally, the raw GreetingHistory case class looks like this:
This is a fairly standard Scala case class, but JMX doesn't know what to do with it. From the Open MBean Data Types chapter of the [JMX Tutorial], the only acceptable values are:
Fortunately, it's easy to map from a case class to a view class. Here's how to display GreetingHistory using a view class for JMX, using ConstructorProperties and BeanProperties to produce a JavaBean in the format that JMX expects. Also note that Set is not visible through JMX, and JavaConverterscannot be used here to convert to java.util.Set, because it does not do a structural copy. Instead, a structural copy must be done to create a Java Set without the wrapper:
Creating In Place JMX views with CompositeDataView
Using a view class is the recommended way to display Scala data in JMX, as it's relatively simple to set up and can be packaged outside of the main class. However, it is possible to embed the JMX logic inside the case class itself, using an in place CompositeDataView.
This is messier than using a view, and does not really give you any more programmatic control. It does, however, minimize the number of types that need to be created.
Finally, the type which registers the JMX Actor with JMX is defined here:
The MXTypeName is defined by the implementing class, and the actor is defined with its path name and registered in the preStart method when the actor is instantiated.
Note that because this trait extends preStart and postStop, any actor implementing this trait needs to explicitly call super.preStart and super.postStop when overriding, to preserve this behavior.
There's a number of things that can be done with JMX, particularly if macros are involved. Actors are shown here because they are notoriously dynamic, but any part of your system can be similarly instrumented to expose their state in a running application.