JMX Basics
JMX Management Beans are POJOs that live in a JMX Container. The JMX container provides standardized ways of accessing these POJOs so that various tools can be used to access the objects, get their status, etc. These POJOs are used to start, stop and configure various important application services such as JDBC connection pools, JMX services, and EJB deployers. In fact, all services in JBoss AS are initialized and configured using JMX management beans that are loaded in to the JMX container when JBoss starts.
Why make a custom JMX MBean?
Java Enterprise application developers often need services that run when the application starts up.
- Database migration - It's usually difficult to modify the database schema while the application is running, so it's often done using shell scripts or standalone Java programs. It also doesn't work if the code needs to run before the application is deployed.
- Timer service - While EJB3 timeouts will take care of the vast majority of applications, sometimes there is a need for very precise timing.
- Protocol services - Application servers such as JBoss handle HTTP and RMI, but occasionally another protocol is needed for example FTP or FIX.
Some technologies that developers often use to implement these kinds of features are:
- Startup Servlets - This is actually a very effective approach, but there can be problems in clustered deployments. For example, a database migration program should be launched only once when the cluster starts.
- Daemon JVMs - These are JVMs started outside the application server that perform some functions that the application server cannot handle. Often these JVMs are remote EJB clients that retrieve information from the application and process it asynchronously. In these cases a Message Driven EJB might be a simpler, and better choice. However if there are network protocols that must be implemented, this is a popular choice. The problems with this kind of architecture are:
- The JVM process needs to be managed separately, started and stopped along with the application server processes.
- Building in high availability - restarting the deamon on another machine if it fails is not built in.
- Remote communication with the app server is required.
Can Management Beans invoke EJBs?
The quick answer: No, not directly.
This is because JMX Management beans usually run in a separate class loader from the application so they don't have access to transfer objects and interfaces. You could try to put these in the outer class loader, but then this might cause problems when deploying the EAR.
Ideas about invoking EJBs, etc. from JMX
A simple solution to this would be to have a singleton in the outer class loader that forms a bridge between some objects instantiated by the application class loader and JMX MBeans. This singleton can contain proxy objects that forward simple JMX lifecycle methods to the implementation if it is registered.
- Singleton class, loaded into an outer class loader that both the JMX service and the EAR have in common. In JBoss, this is simply a jar in the server <tt>lib</tt> directory.
- The singleton contains a map of proxies, keyed by 'implementation name'. The key can serve as a way to instantiate the delegate implementation class.
- JMX Services can retrieve the proxy object from the singleton and pass on any lifecycle messages. If the implementation is not there yet, the resulting state will need to be remembered for later.
- A startup servlet in the application can invoke an initialization method on the singleton. The singleton can then instantiate all the implementation class names because the correct class loader is there.
- Each proxy will instantiate the implementation at this time, invoking JMX lifecycle methods to put the object in the state it would have been in had it been directly called by the JMX MBean in the first place.
I've started working on this idea in the YAJUL project sandbox.
- SVN viewer: http://yajul.svn.sourceforge.net/viewvc/yajul/trunk
- SVN url: https://yajul.svn.sourceforge.net/svnroot/yajul/trunk
JBoss JMX MBean Notes
Static JMX MBean
- Create an MBean interface
- The interface name should be of the form
MyServiceMBean, whereMyServiceis the name of the service. - The implementation class name should be of the form
MyService.
- The interface name should be of the form
- Refer to the JMX MBean using the
<mbean>element in a JBoss 'service.xml' file.
See Also
Making JMX beans with Annotations:
Examples of 'normal' JMX beans:
- http://wiki.jboss.org/wiki/Wiki.jsp?page=ExampleHelloWorldService
- http://wiki.jboss.org/wiki/Wiki.jsp?page=HowCanAnMBeanDependOnASessionBean - NOTE: What isn't covered here is the fact that the classes involved in the Session Bean interface must be visible to the JMX MBean. Easier said than done (just try putting your "ejb client" jars in the classpath on the server that is running the EJBs as well).