|
|
|
|
You've heard about generics. You've heard about autoboxing. You've even heard us talking about "Other New Features" of Java 2 Standard Edition (J2SE) 5.0 a few months ago. Yet there are still features of the latest JDK that are under covered. The new monitoring and management features fall into this category.
J2SE 5.0 contains the following components that together provide the monitoring and management capabilities:
In this article, I will present the basic architecture of JMX and JMX Remote API, explain the terminologies of JMX, discuss the JMX support classes in J2SE 5.0, and demonstrate the usage of JConsole and other tools for monitoring and management in J2SE 5.0. We then take a look at the Platform MBeans and explore some of their capabilities.
JMX (JSR 3) and JMX Remote API (JSR 160) define a standard architecture for application and network management and monitoring in the Java programming language. The overall architecture is divided into three levels:
The instrumentation level of the JMX specification deals with writing Java classes for application resources or even external devices to make them manageable through JMX. The classes that we write in the instrumentation level are called Managed Beans, or MBeans. There are four kinds of MBeans that one can write: Standard MBeans, Dynamic MBeans, Model MBeans, and Open MBeans.
The agent level of the JMX specification defines interfaces for the standard MBeanServer and a set of standard services that are available in all standard compliant JMX implementations. The MBeanServer is a registry of MBeans. The standard services are themselves implemented as MBeans. The four services are Advanced Dynamic Loading (MLets), Monitoring, Timer Service and Relation Service. The MBeanServer and the standard services are collectively called the agent.
The distributed services level or manager level is defined in a separate JMX Remote API specification and rounds out the JMX architecture. It defines standard ways for accessing the MBeanServer running inside one JVM, the managed application, from either another JVM or another manager application, using JMX connectors and protocol adapters.
It is not the goal of this article to do a full presentation on JMX. Instead I will define some of the terms used in JMX. An important foundation of the J2SE 5.0 monitoring and management features is JMX and knowing these basic vocabularies helps in understanding these features.
Hello as a standard
MBean, one simply defines a HelloMBean interface
and modify Hello to implement
HelloMBean. The getters and setters of
HelloMBean determine the attributes of the MBean.
The other methods of HelloMBean determine the
operations of the MBean.
Hello as a dynamic
MBean, one makes Hello implement the
DynamicMBean interface. No naming convention is
involved. The DynamicMBean interface has a
getMBeanInfo method that returns a
MBeanInfo object that describes the attributes,
operations and notifications of the MBean. The
DynamicMBean interface also provides methods like
getAttribute, setAttribute,
getAttributes, setAttributes and
invoke. These methods allows the attributes and
operations of the MBean to be accessed in a dynamic fashion.
String,
Date, BigInteger,
BigDecimal, ObjectName,
CompositeData and TabularData.
CompositeData and TabularData allow
the formation of arbitrarily complex data types. The key
benefit of open MBeans is that no application specific classes
are needed to access the MBean. This become important when
the MBean is accessed from a remote JVM.
ModelMBean extends
DynamicMBean and other interfaces with the
setModelMBeanInfo and
setManagedResource methods. So a set of model
MBean instances can each be made to instrument a different
Java class with a different MBean interface.
MBeanServer interface is at the center of the
JMX architecture. It is a registry of MBeans. Everything
that is done with JMX is done through an
MBeanServer. There can be any number of
MBeanServers running simultaneously in a JVM,
each managing its own share of MBeans. In J2SE 5.0, one
particular MBeanServer, called the
PlatformMBeanServer, is special. Unlike other
MBeanServers which are created from
MBeanServerFactory,
PlatformMBeanServer is created from
ManagementFactory. There will be only one
instance of it in any JVM. Also, it has a set of platform
MBeans already registered.
ObjectName class represents a name of an
MBean inside any MBeanServer. Logically an
ObjectName consists of a domain name and a set of
property-value pairs:
[domainName]:property-value[,property=value]*.
ObjectNames are used in MBean registration with a
MBeanServer. They are also used for querying the
MBeanServer for MBeans.
MBeanServer, one
instantiates the MBean, constructs an ObjectName,
and calls the registerMBean method on the
MBeanServer. Once registered, the attributes and
operations are accessible from the MBeanServer
without directly accessing the MBean instance. This level of
decoupling is a key design goal of JMX.
MBeanServer for MBeans, one calls one
of its query methods passing in an ObjectName and
a QueryExp. When querying, the ObjectName may
contain wild card characters * and ?
in the domain name part, and the wild card character
* in the property-value pairs part. In the
property-value pair part, the * represents a
whole pair because a property-value pair is the smallest unit
for MBean queries.
MBeanServer interface contains
getAttribute, setAttribute,
getAttributes, and setAttributes
methods that are similar to the methods of the same names in
the DynamicMBean interface, but with an
additional ObjectName first parameter.
MBeanServer's invoke method is
similar to the invoke method of
DynamicMBean, but with an additional
ObjectName first parameter.
MBeanServer interface by first
specifying an ObjectName and then the interested
Notifications.
MBeanServerConnection interface is a
superinterface of MBeanServer. When a management
application connects to an MBeanServer in another
JVM, a MBeanServerConnection is what it gets
back. This interface has most of the methods of
MBeanServer. The few methods that are not
present, such as registerMBean, do not make sense
from a remote management application.
MBeanServer and started to listen
for connections, and a connector client, which is an RMI
client that the management application uses to get an
MBeanServerConnection.
J2SE 5.0 not only fully supports JMX and the JMX Remote API, but
also support the PlatformMBeanServer and a set of
platform MBeans that instrument the performance and resource
consumption of the HotSpot JVM itself.
The platform MBeans are also called MXBeans. They are open MBeans. What these MXBeans instrument is defined by JSR 174, "Requirements for the Monitoring and Management for the JVM." These MXBeans give the Java developer an unprecedented peek into the inner workings of the J2SE 5.0 JVM. Some of the information gleaned through the MXBeans may be useful in debugging and troubleshooting a Java application. Some may be useful for the day-to-day management of a Java application during normal operations.
Here's the list of Java packages that corresponds to the various JSRs:
javax.management[.*] is where JMX classes
live
javax.management.remote[.*] contain the JMX
Remote API
java.lang.management contains the platform
MBeanServer and the platform MBeans
(MXBeans)
Here's the list of platform MBeans that are supported by J2SE
5.0. They all belong to the java.lang.management
package, except LoggingMXBean which is in the
java.util.logging package:
The java.lang.management.ManagementFactory contains
factory method for getting these MXBeans. Once an instance is
obtained, one can interact with it directly without going
through the JMX mechanisms. This will be the preferred way to
interact with them from within the same JVM.
The java.lang.management.ManagementFactory also
contains factory method for getting the
PlatformMBeanServer. All of the MXBeans mentioned
above are already registered with the
PlatformMBeanServer. Java system properties exist
that can be used to manipulate the
PlatformMBeanServer, making it the easiest
MBeanServer to use. For example, you can use
java command line options to start the
PlatformMBeanServer with the JMX RMI connector
server already attached and started.
Aside from the MXBeans, one can also register application
specific MBeans with the PlatformMBeanServer,
making an application easily manageable.
The following is a very simple example that illustrates some
capabilities of the PlatformMBeanServer with a
standard MBean:
[weiqi@gao] $ cat HelloMBean.java
public interface HelloMBean {
String getGreeting();
void setGreeting(String greeting);
}
[weiqi@gao] $ cat Hello.java
import java.lang.management.*;
import javax.management.*;
public class Hello implements HelloMBean {
private String greeting;
public Hello() {
this.greeting = "Hello";
}
public Hello(String greeting) {
this.greeting = greeting;
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public static void main(String[] args) throws Exception {
Hello hello = new Hello();
ObjectName name = new ObjectName("hello:type=Hello");
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
mbeanServer.registerMBean(hello, name);
System.out.println(mbeanServer.getAttribute(name, "Greeting"));
for (Object o : mbeanServer.queryNames(new ObjectName("java*:*"), null)) {
System.out.println(o);
}
// Keep around so that we can examine this app from JConsole
Thread.sleep(Long.MAX_VALUE);
}
}
[weiqi@gao] $ java Hello
Hello
java.lang:type=Compilation
java.lang:type=MemoryManager,name=CodeCacheManager
java.lang:type=GarbageCollector,name=Copy
java.lang:type=MemoryPool,name=Perm Gen [shared-ro]
java.lang:type=MemoryPool,name=Eden Space
java.lang:type=Runtime
java.lang:type=ClassLoading
java.lang:type=MemoryPool,name=Survivor Space
java.lang:type=Threading
java.lang:type=GarbageCollector,name=MarkSweepCompact
java.util.logging:type=Logging
java.lang:type=OperatingSystem
java.lang:type=Memory
java.lang:type=MemoryPool,name=Code Cache
java.lang:type=MemoryPool,name=Perm Gen [shared-rw]
java.lang:type=MemoryPool,name=Tenured Gen
java.lang:type=MemoryPool,name=Perm Gen
In this example, we exercised MBean registration, MBean
attribute accessing, and MBean name querying. Notice that since
we performed the query with a wild card ObjectName of
java*:*, we get back an array of
ObjectNames whose domain name all start with
java. Although the JMX specification does not
mandate it, it is customary to use a Java package name as the
domain name of MBeans.
We will have occasion to use this program again in the next section where we talk about the monitoring and management tools that come with J2SE 5.0.
J2SE 5.0 includes several newly added command line tools and a GUI tool for monitoring and management of JVMs:
jps
jstat
jstatd
jconsole
All four tools are labeled "experimental" in the J2SE 5.0 documentation. Please keep this in mind as you explore their usage.
The first three, jps, jstat, and
jstatd grow out of the jvmstat
project that was freely available from Sun. They take advantage
of JVM instrumentations that began to be added since version
1.4.1. They are similar to the Unix ps tool, which
also offers remote operation possibilities.
The jps command is the easiest to use. Without any
command line options, it prints out local JVM ids (lvmids) and
the simple name of the Java class that started them:
[weiqi@gao] $ jps 27636 Jps 27628 Hello
The -l option causes jps the fully
qualified names to be printed:
[weiqi@gao] $ jps -l 27645 sun.tools.jps.Jps 27628 Hello
The -m option prints the arguments passed to the
main method. The -v option prints the arguments
passed to the JVM. The -V option prints the
arguments passed to the JVM flag files
(~/.hotspotrc).
[weiqi@gao] $ jps -l -m -v -V 27705 sun.tools.jps.Jps -l -m -v -V -Dapplication.home=/usr/lib/jvm/java-1.5.0-s un-1.5.0.01 -Xms8m 27628 Hello
The jps command can be used to inspect JVM
processes running on a remote machine provided an instance of
jstatd is running on the remote machine. To do
this you need to specify a host Id:
[weiqi@gao-2004] $ jstatd -J-Djava.security.policy=jstatd.all.policy
[weiqi@gao-2003] $ jps -l -m -v -V gao-2004 28822 sun.tools.jstatd.Jstatd -Dapplication.home=/usr/lib/jvm/java-1.5.0-sun-1.5 .0.01 -Xms8m -Djava.security.policy=jstatd.all.policy 28854 Hello
Here we first started jstatd on host gao-2004, and
then inspected the java processes running on gao-2004 from the
host gao-2003. The host name passed on the jps
command line is an abbreviated version of the URL
rmi://gao-2004:1099/JStatRemoteHost.
The above example also showed how to start the
jstatd daemon. By default it starts an RMI
registry that listens on port 1099 and binds itself to the
registry as JStatRemoteHost. A different port number can be
specified with the -p option, and a different name
can be specified with the -n option. It also
requires a policy file jstatd.all.policy in the
current directory:
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
The jstat command can be used to display
performance statistics of JVMs. The monitored JVMs can be local
(identified by the local JVM Id) or remote (identified by
lvmid@hostname or
rmi://lvmid@hostname:port/JStatObjectName if no
defaults are used.)
[weiqi@gao-2003 weiqi] $ jstat -gcutil 28822@gao-2004 1000 5 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 0.00 65.88 5.90 8.43 114 0.091 49 1.960 2.051 0.00 0.00 82.22 5.90 8.43 114 0.091 49 1.960 2.051 0.00 100.00 0.00 6.19 8.43 115 0.092 49 1.960 2.052 0.00 100.00 16.93 6.19 8.43 115 0.092 49 1.960 2.052 0.00 100.00 33.64 6.19 8.45 115 0.092 49 1.960 2.052
Here we monitored the JVM statistics of Java process with a lvmid of 28822 running on gao-2004 from gao-2003. We monitored the garbage collection statistics 5 times at 1000 millisecond intervals.
Jstat supports twelve output options like
-gcutil. One and only one output option must be
selected when invoking jstat. Otherwise
jstat prints a usage message and exits. Please
refer to the online documentation for further details.
JConsole differs from the other three tools in two ways: It is a GUI tool and it talks directly with the monitored JVM using JMX. In order for a JVM to be monitored by JConsole, it must be started with the appropriate properties.
To enable JConsole monitoring from the localhost only, start the
JVM with the -Dcom.sun.management.jmxremote command
line argument:
[weiqi@gao] $ java -Dcom.sun.management.jmxremote Hello
To enable JConsole monitoring from a remote machine, more properties need to be specified. The easiest and least secure way is the following:
[weiqi@gao] $ java -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management .jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false Hello
This allows JConsole connections from any other host through clear sockets without password authentication. You can enable password authentication or secure sockets or both by setting the respective properties to true (or not specifying at all).
To enable password authentication, you need to copy
$JAVA_HOME/jre/lib/management/jmxremote.password.template
to your home directory, rename it to
jmxremote.password, uncomment the last two lines
and use them as the username and password when you connect from
JConsole. It is also important to change the permission on the
file so that only its owner can read or write the file.
[weiqi@gao-2004] $ java -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.manag ement.jmxremote.password.file=/home/weiqi/jmxremote.password -Dcom.sun.managemen t.jmxremote.ssl=false Hello
Connecting to either a local JVM or are remote JVM from JConsole is done through the login screens:
Once connected, the JConsole main screen appears. It contains the following tabs: Summary, Memory, Threads, Classes, MBeans, and VM. Each tab contains summary tests or continuously updated charts representing the various statistics of the monitored JVM. The MBeans tab is reproduced below:
Did you see our Hello MBean and its attribute Greeting=Hello?
The platform MBean's also show up in the MBeans tab. It is worthwhile to explore their attributes, operations, and notifications to discover the rich information that they convey.
When you start the JVM with the
com.sun.management.jmxremote.port property set, the
PlatformMBeanServer is automatically started with
all the platform MBeans registered and the JMX RMI connector
server started.
JConsole is not the only program that can connect to this
connector server. Any J2SE 5.0 program can connect to this
PlatformMBeanServer by using the JMX RMI connector
client. The following simple program demonstrate how this is
done.
[weiqi@gao-2003] $ cat MyJMXClient.java
import java.util.*;
import javax.management.*;
import javax.management.remote.*;
import javax.management.remote.rmi.*;
public class MyJMXClient {
public static void main(String[] args) throws Exception {
HashMap env = new HashMap();
String[] credentials = new String[] {"controlRole", "R&D"};
env.put("jmx.remote.credentials", credentials);
JMXServiceURL url =
new JMXServiceURL("service:jmx:rmi:///jndi/rmi://gao-2004:9999/jmxrmi");
JMXConnector c = JMXConnectorFactory.connect(url, env);
MBeanServerConnection s = c.getMBeanServerConnection();
for (Object o : s.queryNames(new ObjectName("hello:*"), null)) {
System.out.println(s.getAttribute((ObjectName) o, "Greeting"));
}
}
}
[weiqi@gao-2003] $ java MyJMXClient
Hello
Now that we had a good understanding of the JMX architecture and how J2SE 5.0 supports it, it's time to take a look at each of the platform MBeans:
These platform MBeans can be accessed from the local JVM using
factory methods of ManagementFactory:
MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
They can also be accessed from remote management applications
using the MXBean proxy method of ManagementFactory:
MBeanServerConnection mbs = // get the connection RuntimeMXBean mbean = ManagementFactory.newPlatformMXBeanProxy( mbs, ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
Once you get the reference or proxy of a platform MBean, you can access its attributes, invoke its operations and listen to its notifications directly. In the rest of this section, I will simply list some of the most interesting attributes, operations and notifications of each platform MBean and let you use your imagination to figure out cool ways they can be weaved together to generate useful services for your applications.
The introduction of JMX, the JMX Remote API and the inclusion of the platform MBeanServer and the platform MBeans into J2SE 5.0 make it easier to build applications that are more manageable than ever before.
JVMs as well as applications running inside the JVMs can be monitored and managed either locally or remotely. Critical resources of applications can be instrumented and managed along side the JVM resources.
JConsole, custom management applications, third party JMX consoles and system management software packages that support JMX can be leveraged to manage multiple mission critical applications from a central location, thus making the operations of the applications more efficient and more responsive.
Object Computing, Inc (OCI) has been providing educational services to clients, industries and universities since 1993. We offer one of the most comprehensive distributed Object Oriented training curricula in the country. These curricula focus on the fundamentals of OO technology; with close to 40 workshops in OOAD, Java, XML, C++/CORBA and Unix/Linux.
For further information regarding OCI's Educational Services programs, please visit our Educational Services section on the web or contact us at training@ociweb.com.
|
|
|