Developing Custom Management Utilities with JMX
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
The following sections describe how to access WebLogic Server MBeans from a JMX client:
If your JMX client runs in its own JVM (that is, a JVM that is not a WebLogic Server instance), include the following JAR file in the client's classpath:
where WL_HOME
is the directory in which you installed WebLogic Server.
This JAR contains BEA's implementation of the HTTP and IIOP protocols and its proprietary T3 protocol. With BEA's implementation, JMX clients send login credentials with their connection request and the WebLogic Server security framework authenticates the clients. Only authenticated clients can access MBeans that are registered in a WebLogic Server MBean server.
Note: While BEA recommends that you use its implementation of the HTTP and IIOP protocols or its proprietary T3 protocol, JMX clients can use the IIOP protocol that is defined in the standard JDK. See Remote Connections Using Only JDK Classes on page 4-7.
Each WebLogic Server domain includes three types of MBean servers, each of which provides access to different MBean hierarchies. See MBean Servers.
To connect to a WebLogic MBean server:
javax.management.remote.JMXServiceURL
object.Pass the following parameter values to the constructor (see JMXServiceURL
in the J2SE 5.0 API Specification):
t3
, t3s
, http
, https
, iiop
, iiops
/jndi/
and be followed by one of the JNDI names described in Table 4-1.javax.management.remote.JMXConnector
object. This object contains methods that JMX clients use to connect to MBean servers.The constructor method for JMXConnector
is: javax.management.remote.JMXConnectorFactory.
connector(JMXServiceURL serviceURL
, Map<String,?>
environment
)
Pass the following parameter values to the constructor (see JMXConnectorFactory
in the J2SE 5.0 API Specification):
javax.naming.Context.SECURITY_CREDENTIALS,
admin-user-password
javax.management.remote.JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote"
The weblogic.management.remote
package defines the protocols that can be used to connect to the WebLogic MBean servers. Remote JMX clients must include the classes in this package on their classpath. See Set Up the Classpath for Remote Clients.
JMXConnector.getMBeanServerConnection()
method.The method returns an object of type javax.management.MBeanServerConnection
.
The MBeanServerConnection
object is your connection to the WebLogic MBean server. You can use it for local and remote connections. See MBeanServerConnection
in the J2SE 5.0 API Specification.
Note the following about the code in Listing 4-1:
connection
and connector
, to represent the connection to the MBean server. The initConnection()
method, which assigns the value to the connection
and connector
variables, should be called only once per class instance to establish a single connection that can be reused within the class. initConnection()
method takes the username and password (along with the server's listen address and listen port) as arguments that are passed when the class is instantiated. BEA recommends this approach because it prevents your code from containing unencrypted user credentials. The String
objects that contain the arguments will be destroyed and removed from memory by the JVM's garbage collection routine.JMXConnector.close()
to close the connection to the MBean server. (See JMXConnector
in the J2SE 5.0 API Specification.)Listing 4-1 Connecting to the Domain Runtime MBean Server
public class MyConnection {
private static MBeanServerConnection connection;
private static JMXConnector connector;
private static final ObjectName service;
/*
* Initialize connection to the Domain Runtime MBean Server.
*/
public static void initConnection(String hostname, String portString,
String username, String password) throws IOException,
MalformedURLException {
String protocol = "t3";
Integer portInteger = Integer.valueOf(portString);
int port = portInteger.intValue();
String jndiroot = "/jndi/";
String mserver = "weblogic.management.mbeanservers.domainruntime";
JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,
jndiroot + mserver);
Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
"weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);
connection = connector.getMBeanServerConnection();
}
public static void main(String[] args) throws Exception {
String hostname = args[0];
String portString = args[1];
String username = args[2];
String password = args[3];
MyConnection c= new MyConnection();
initConnection(hostname, portString, username, password);
...
connector.close();
}
}
A WebLogic Server domain maintains three types of MBean servers, each of which fulfills a specific function. Access MBeans through the MBean server that supports the task you are trying to complete:
Monitoring through a Runtime MBean Server requires less memory and network traffic than monitoring through the Domain Runtime MBean Server. (WebLogic Server does not initialize the Domain Runtime MBean Server until a client requests a connection to it.)
In most cases, all server instances in the domain have the same set of configuration data and it therefore does not matter whether you monitor the Runtime MBean Server on the Administration Server or on a Managed Server. However, if you make a change that a server cannot consume until it is restarted, the server will no longer accept any changes and its configuration data could become outdated. In this case, monitoring this server's Runtime MBean Server indicates only the configuration for the specific server instance. To understand the process of changing a WebLogic Server domain and activating the changes, see Managing Configuration Changes in Understanding Domain Configuration.
If you register a JMX listener and filter with an MBean in the Domain Runtime MBean server, the JMX filter runs in the same JVM as the MBean it monitors. For example, if you register a filter with an MBean on a Managed Server, the filter runs on the Managed Server and forwards only messages that satisfy the filter criteria to the listener.
In general, code that uses the Domain Runtime MBean Server is easier to maintain and is more secure for the following reasons:
The trade off for directing all JMX requests through the Domain Runtime MBean Server is a slight degradation in performance due to network latency and increased memory usage. Connecting directly to each Managed Servers's Runtime MBean Server to read MBean values eliminates the network hop that the Domain Runtime MBean Server makes to retrieve a value from a Managed Server. However, for most network topologies and performance requirements, the simplified code maintenance and enhanced security that the Domain Runtime MBean Server enables is preferable.
Figure 4-1 Domain Runtime MBean Server versus Runtime MBean Server
BEA recommends that you use WebLogic Server classes to connect from remote JMX clients. However, it is possible for remote JMX clients to connect to a WebLogic Server JMX agent using only the classes in the JDK. To do so:
See Enable and Configure IIOP in Administration Console Online Help.
String hostname = "
WLS-host
"
int port = WLS-port
String protocol = "rmi";
String jndiroot= new String("/jndi/iiop://" + hostname + ":" +
port + "/");
String mserver = "MBean-server-JNDI-name
";
JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,
jndiroot + mserver);
Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
where WLS-host
and WLS-port
are the listen address and listen port of a WebLogic Server instance and MBean-server-JNDI-name
is one of the values listed in Table 4-1.
Note that the hash table you create does not include the name of a protocol package. By leaving this value as null, the JMX client uses the protocol definitions from the com.sun.jmx.remote.protocol
package, which is in the JDK.
Local clients can access a WebLogic Server instance's Runtime MBean Server through the JNDI tree instead of constructing a JMXServiceURL
object. Only the Runtime MBean Server registers itself in the JNDI tree.
When accessed from JNDI, the Runtime MBean Server returns its javax.management.MBeanServer
interface. This interface contains all of the methods in the MBeanServerConnection
interface plus additional methods such as registerMBean()
, which local process can use to register custom MBeans. (See MBeanServer
in the J2SE 5.0 API Specification.)
If the classes for the JMX client are located at the top level of an enterprise application (that is, if they are deployed from the application's APP-INF
directory), then the JNDI name for the Runtime MBean Server is:java:comp/jmx/runtime
If the classes for the JMX client are located in a J2EE module, such as an EJB or Web application, then the JNDI name for the Runtime MBeanServer is:java:comp/env/jmx/runtime
For example:InitialContext ctx = new InitialContext();
server = (MBeanServer)ctx.lookup("java:comp/env/jmx/runtime");
WebLogic Server organizes its MBeans in a hierarchical data model. (See WebLogic Server MBean Data Model.) In this model, all parent MBeans include attributes that contain the object names of their children. You use the child's object name in standard JMX APIs to get or set values of the child MBean's attributes or invoke its methods.
To navigate the WebLogic Server MBean hierarchy:
See the previous section, Make Remote Connections to an MBean Server.
Initiating the connection returns an object of type javax.management.MBeanServerConnection
.
MBeanServerConnection
.getAttribute(ObjectName
object-name
,
String
attribute
)
method where:object-name
is the object name of the service MBean that is registered in the MBean server. (See Service MBeans.)Table 2-3 describes the type of service MBeans that are available in each type of MBean server.
attribute
is the name of a service MBean attribute that contains the root MBean.To determine an MBean's location in an MBean hierarchy, refer to the MBean's description in WebLogic Server MBean Reference. For each MBean, the WebLogic Server MBean Reference lists the parent MBean that contains the current MBean's factory methods. For an MBean whose factory methods are not public, the WebLogic Server MBean Reference lists other MBeans from which you can access the current MBean.
The code example in Listing 4-2 connects to the Domain Runtime MBean Server and uses the DomainRuntimeServiceMBean
to get the object name for each ServerRuntimeMBean
in the domain. Then it retrieves and prints the value of each server's ServerRuntimeMBean
Name
and State
attributes.
Note the following about the code in Listing 4-2:
connection
and connector
global variables, the class assigns the object name for the WebLogic Server service MBean to a global variable. Methods within the class will use this object name frequently, and once it is defined it does not need to change.printServerRuntimes()
method gets the value of the DomainRuntimeServiceMBean
ServerRuntimes
attribute, which contains an array of all ServerRuntimeMBean
instances in the domain. (See DomainRuntimeServiceMBean
in WebLogic Server MBean Reference.)Listing 4-2 Example: Print the Name and State of Servers
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
public class PrintServerState {
private static MBeanServerConnection connection;
private static JMXConnector connector;
private static final ObjectName service;
// Initializing the object name for DomainRuntimeServiceMBean
// so it can be used throughout the class.
static {
try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.
mbeanservers.domainruntime.DomainRuntimeServiceMBean");
}catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());
}
}
/*
* Initialize connection to the Domain Runtime MBean Server
*/
public static void initConnection(String hostname, String portString,
String username, String password) throws IOException,
MalformedURLException {
String protocol = "t3";
Integer portInteger = Integer.valueOf(portString);
int port = portInteger.intValue();
String jndiroot = "/jndi/";
String mserver = "weblogic.management.mbeanservers.domainruntime";
JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname,
port, jndiroot + mserver);
Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
"weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);
connection = connector.getMBeanServerConnection();
}
/*
* Print an array of ServerRuntimeMBeans.
* This MBean is the root of the runtime MBean hierarchy, and
* each server in the domain hosts its own instance.
*/
public static ObjectName[] getServerRuntimes() throws Exception {
return (ObjectName[]) connection.getAttribute(service,
"ServerRuntimes");
}
/*
* Iterate through ServerRuntimeMBeans and get the name and state
*/
public void printNameAndState() throws Exception {
ObjectName[] serverRT = getServerRuntimes();
System.out.println("got server runtimes");
int length = (int) serverRT.length;
for (int i = 0; i < length; i++) {
String name = (String) connection.getAttribute(serverRT[i],
"Name");
String state = (String) connection.getAttribute(serverRT[i],
"State");
System.out.println("Server name: " + name + ". Server state: "
+ state);
}
}
public static void main(String[] args) throws Exception {
String hostname = args[0];
String portString = args[1];
String username = args[2];
String password = args[3];
PrintServerState s = new PrintServerState();
initConnection(hostname, portString, username, password);
s.printNameAndState();
connector.close();
}
}
Each servlet in a Web application provides instance of ServletRuntimeMBean
which contains information about the servlet's runtime state. (See ServletRuntimeMBean
in WebLogic Server MBean Reference.)
In the WebLogic Server data model, the path to a ServletRuntimeMBean
is as follows:
The code in Listing 4-3 navigates the hierarchy described in the previous paragraphs and gets values of ServletRuntimeMBean
attributes.
Listing 4-3 Monitoring Servlets
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
public class MonitorServlets {
private static MBeanServerConnection connection;
private static JMXConnector connector;
private static final ObjectName service;
// Initializing the object name for DomainRuntimeServiceMBean
// so it can be used throughout the class.
static {
try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanser
vers.domainruntime.DomainRuntimeServiceMBean");
}catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());
}
}
/*
* Initialize connection to the Domain Runtime MBean Server
*/
public static void initConnection(String hostname, String portString,
String username, String password) throws IOException,
MalformedURLException {
String protocol = "t3";
Integer portInteger = Integer.valueOf(portString);
int port = portInteger.intValue();
String jndiroot = "/jndi/";
String mserver = "weblogic.management.mbeanservers.domainruntime";
JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname,
port, jndiroot + mserver);
Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
"weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);
connection = connector.getMBeanServerConnection();
}
/*
* Get an array of ServerRuntimeMBeans
*/
public static ObjectName[] getServerRuntimes() throws Exception {
return (ObjectName[]) connection.getAttribute(service,
"ServerRuntimes");
}
/*
* Get an array of WebApplicationComponentRuntimeMBeans
*/
public void getServletData() throws Exception {
ObjectName[] serverRT = getServerRuntimes();
int length = (int) serverRT.length;
for (int i = 0; i < length; i++) {
ObjectName[] appRT =
(ObjectName[]) connection.getAttribute(serverRT[i],
"ApplicationRuntimes");
int appLength = (int) appRT.length;
for (int x = 0; x < appLength; x++) {
System.out.println("Application name: " +
(String)connection.getAttribute(appRT[x], "Name"));
ObjectName[] compRT =
(ObjectName[]) connection.getAttribute(appRT[x],
"ComponentRuntimes");
int compLength = (int) compRT.length;
for (int y = 0; y < compLength; y++) {
System.out.println(" Component name: " +
(String)connection.getAttribute(compRT[y], "Name"));
String componentType =
(String) connection.getAttribute(compRT[y], "Type");
System.out.println(componentType.toString());
if (componentType.toString().equals("WebAppComponentRuntime")){
ObjectName[] servletRTs = (ObjectName[])
connection.getAttribute(compRT[y], "Servlets");
int servletLength = (int) servletRTs.length;
for (int z = 0; z < servletLength; z++) {
System.out.println(" Servlet name: " +
(String)connection.getAttribute(servletRTs[z],
"Name"));
System.out.println(" Servlet context path: " +
(String)connection.getAttribute(servletRTs[z],
"ContextPath"));
System.out.println(" Invocation Total Count : " +
(Object)connection.getAttribute(servletRTs[z],
"InvocationTotalCount"));
}
}
}
}
}
}
public static void main(String[] args) throws Exception {
String hostname = args[0];
String portString = args[1];
String username = args[2];
String password = args[3];
MonitorServlets s = new MonitorServlets();
initConnection(hostname, portString, username, password);
s.getServletData();
connector.close();
}
}
![]() ![]() |
![]() |
![]() |