JMX Defined
JMX is a way to view and manipulate the runtime state of your application. It's somewhat similar in concept to SNMP, if that helps. IMO, it's indispensable for monitoring and understanding server-type applications that might not have any other user interface besides writing to a log file.
The basic approach is to create an interface for the things you want to monitor, then have a class implement the interface, then register an instance of that class with the "MBeanServer" (which actually makes the stuff defined in the interface available to JMX monitoring apps like jconsole).
Here's a trivial -- but working -- example:
(I'm assuming Java 5 or better)
TestServerMBean.java
public interface TestServerMBean
{
public long getUptimeMillis();
public long getFooCount();
public void setFooCount(long val);
public void printStuff(String stuff);
}
TestServer.java:
import java.lang.management.ManagementFactory;
import java.util.concurrent.atomic.AtomicLong;
import javax.management.ObjectName;
// If jconsole doesn't see this app automatically, invoke the application with the following java flags, and connect
// 'remotely' via jconsole.
//
// -Dcom.sun.management.jmxremote
// -Dcom.sun.management.jmxremote.port=2222 (or whatever)
// -Dcom.sun.management.jmxremote.authenticate=false
// -Dcom.sun.management.jmxremote.ssl=false
public class TestServer implements TestServerMBean
{
private final AtomicLong m_counter = new AtomicLong(0L);
private final long m_startTimeMillis = System.currentTimeMillis();
public void run() throws InterruptedException {
while (true) {
m_counter.incrementAndGet();
Thread.sleep(5000);
}
}
public long getFooCount() {
return m_counter.get();
}
public void setFooCount(long val) {
m_counter.set(val);
}
public long getUptimeMillis() {
return System.currentTimeMillis() - m_startTimeMillis;
}
public void printStuff(String stuff) {
System.out.println(stuff);
}
public static void main(String[] args) throws Exception {
TestServer ts = new TestServer();
ManagementFactory.getPlatformMBeanServer().registerMBean(ts, new ObjectName("myapp:service=MyServer"));
ts.run();
}
}
Compile and run TestServer.class as usual, fire up jconsole
, connect to TestServer (it'll show up automatically, else see comments in code above), then look at the 'MBeans' tab, and you'll see our instance named myapp:service=MyServer
. You can view the current "uptime", and watch FooCounter
increment every 5 seconds. You can also set FooCounter to whatever (long) value you want, and invoke the printStuff
method with any String argument.
Obviously this is a ridiculous "server", but hopefully having a simple working example will help illustrate the overall concept: being able to peek into and manipulate a running app.
There are a lot of additional features and different types of MBeans, but just the vanilla JMX shown above goes a long way, IMO.
Here are some decent web resources:
- Oracle JMX Tutorial
- Java monitoring & management overview
- JMX in Action (available as an eBook)
In a nutshell JMX allows you to remotely invoke methods or view exposed data from the inside of a running JVM. A lot of applications use JMX to sort of attach a remote dashboard to their running JVMs in order to provide remote management.
For example, if you had an app server running on a machine, with JMX it would be possible to remotely view the exposed information about that server. It is also possible to code your own JMX MBeans which can expose any variables or methods inside your application. The exposed variables can then be "polled" remotely to test for certain conditions you would like to know about.
Another useful thing about JMX is that you can remotely change variables on the fly. For instance, if you have some sort of pool set up that has a maximum total amount, this maximum amount can be changed remotely without having to restart or change any configuration files on your application server.
jconsole
is provided by Sun with Java to be able to easily view your MBeans remotely without having to code your own client solution. You could also consume the MBeans with a custom solution which can give you excellent flexibility.
Also, there are already some monitoring software that come with JMX MBean monitoring built in. Zenoss and Applications Manager 8 do this, to name a couple.
Addition:
There is already a lot of software that takes advantage of JMX. Tomcat exposes information that is accessible via jconsole and so does JBoss Application Server.
Maybe JSR 262 is also worth to be mentioned here.
"JSR 262 defines a connector for the JMX Remote API that uses Web Services to make JMX instrumentation available remotely. Clients do not have to be Java applications, but can be."
It is very likely that JSR 262 will be part of the next Java version (Java 7).
There is a java.net project for a JMX WS connector which depends on WiseMan project. Wiseman is an Open Source Java implementation of WS-Management standard.