Hi,

Jay SenSharma

Jay SenSharma

Here is a Simple Demonstration of Creating a Custom MBean, Resistering this MBean, and Writing a Stand alone Application which gets the Notification as sson as any attribute of that CustomMBean changes. This Notification is achieved using the weblogic.management.RemoteNotificationListener Listener. (Below Sample is tested on WLS10.3)

Step1). We are going to develop an EAR application in which we will use an ApplicationLifecycleListener to register our CustomMBean in the MBeanServer. So create an EAR App Directory somewhere in your filesystem.
Example: “C:MBeanTestApp”

Step2). Create the following Directory Structure

C:MBeanTestAppAPP-INFclasses
and
C:MBeanTestAppMETA-INF
and
C:MBeanTestAppMyWebAppWEB-INF

Step3). Please provide the Custom Mbean Interface “MyCustomMBean.java” inside “C:MBeanTestAppAPP-INFclasses” like following:

package mymbean;
import java.io.*;
public interface MyCustomMBean {
public String getSomething();
public void setSomething(String str) throws IOException;
}

Step4). Provide the implementation code for the above interface inside your CustomMBean “MyCustomMBeanImpl.java” inside “C:MBeanTestAppAPP-INFclasses” like following:

package mymbean;
import javax.management.*;
import weblogic.management.*;
import java.io.*;
public class MyCustomMBeanImpl extends StandardEmitterMBean implements MyCustomMBean
{
String something= "hello";
private static final MBeanNotificationInfo info =new MBeanNotificationInfo(
new String[] {javax.management.AttributeChangeNotification.ATTRIBUTE_CHANGE },AttributeChangeNotification.class.getName(),"Indicates that an attribute was changed");

public MyCustomMBeanImpl()
{
super(MyCustomMBean.class,new NotificationBroadcasterSupport(info));
System.out.println("t DEBUG: MyCustomMBeanImpl : MyCustomMBeanImpl Object Initialized.");
}

public String getSomething()
{
System.out.println("t DEBUG: MyCustomMBeanImpl : getSomething() called.");
return something;
}

public void setSomething(String str)throws IOException
{
System.out.println("t DEBUG: MyCustomMBeanImpl : setSomething(String "+str+") called.");
String oldValue = null;
something = str;
if(oldValue == null)
{
oldValue = getSomething();
}
else
{
oldValue = str;
}

AttributeChangeNotification acn =new AttributeChangeNotification(this, 0,System.currentTimeMillis(),"Atrribute something got changed","something","String",oldValue,str);
sendNotification(acn);
System.out.println("t DEBUG: MyCustomMBeanImpl : setSomething(String "+str+") called....sendNotification(acn) executed.");
}
}

Step5). Now we are going to provide the our ApplicationLifecycleListener sothat as soon as we deploy the application on the Server …it will automatically register our CustomMbean in the MBeanServer…using the preStart() …So please provide the following program “RegisterCustomMBeanListener.java” inside “C:MBeanTestAppAPP-INFclasses” like following:

package listeners;
import weblogic.application.*;
import weblogic.management.*;
import javax.management.*;
import java.io.*;
import javax.naming.*;
import mymbean.*;
public class RegisterCustomMBeanListener extends ApplicationLifecycleListener
{
// register the mbean when application starts.
public void postStart(weblogic.application.ApplicationLifecycleEvent p1)
{
try {
System.out.println("t DEBUG: RegisterCustomMBeanListener : postStart() called.");
ObjectName mymbean =new ObjectName("mycustommbean:Name=MyCustomMBean,Type=MyCustomMBean");
String classname = "mymbean.MyCustomMBean";
InitialContext ctx = new InitialContext();
MBeanServer server = (MBeanServer)ctx.lookup("java:comp/jmx/runtime");
MyCustomMBean mbean = new MyCustomMBeanImpl();
server.registerMBean(mbean, mymbean);
System.out.println("t DEBUG: RegisterCustomMBeanListener : postStart() ...server.registerMBean(mbean, mymbean) executed.");
}
catch (Exception e)
{
e.printStackTrace();
}
}

// unregister the mbean when the application stops.
public void preStop(weblogic.application.ApplicationLifecycleEvent p1)
{
InitialContext ctx;
try {
ObjectName mymbean =new ObjectName("mycustommbean:Name=MyCustomMBean,Type=MyCustomMBean");
ctx = new InitialContext();
MBeanServer server = (MBeanServer)ctx.lookup("java:comp/jmx/runtime");
server.unregisterMBean(mymbean);
System.out.println("t DEBUG: RegisterCustomMBeanListener : preStop() ...server.unregisterMBean(mymbean) executed.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Step6). Now open a Command Prompt and then compile the above three *.java programs….like following (after running the setWLSEnv.cmd):

Step7). Now provide a Simple “index.jsp” file inside “C:MBeanTestAppMyWebApp” location like following:

<html>
<head>
    <title>Test</title>
</head>
<body>
<h2> Hi ...Just testing the MBean Attribute Changes....(you can write anything here...or leave it empty as well)</h2>
</body>
</html>

Step8). Please provide a Simplest “web.xml” file inside “C:MBeanTestAppMyWebAppWEB-INF” directory:

<?xml version='1.0' encoding='UTF-8'?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

</web-app>

Step9). Provide the “application.xml” file inside “C:MBeanTestAppMETA-INF” as following :

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
<module>
<web>
<web-uri>MyWebApp</web-uri>
<context-root>MyWebApp</context-root>
</web>
</module>
</application>

Step10). Provide the “weblogic-application.xml” file inside “C:MBeanTestAppMETA-INF” as following :

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
<listener>
<listener-class>listeners.RegisterCustomMBeanListener</listener-class>
</listener>
</weblogic-application>

Step11). Deploy the “MBeanTestApp” EAR application in WebLogic Server…Running on Port 7001….because in our code we have hardcoded the Port in many places…so better u deploy this Application in a Server which is running on the Same Port 7001.

Step12). Now We are going to Write the Standalone Application to get the Notification …as soon as any Attribute value changes in the Custom MBean created and Registrerd by us:
So Create a Directory for putting all our Client artifacts in
“C:MBeanChangeNotificationClient”

Step13). Provide our own RemoteNotificationListener listener class “MyAttributeChangeListenerImpl.java” inside “C:MBeanChangeNotificationClient” as following:

package client;
import javax.management.*;
import weblogic.management.*;
import java.util.Date;
public class MyAttributeChangeListenerImpl implements RemoteNotificationListener
{
public void handleNotification(javax.management.Notification notification, Object handback)
{
System.out.println("nnt handleNotification(Notification notification, Object handback) () Called");

if(notification instanceof AttributeChangeNotification)
{
AttributeChangeNotification acn = (AttributeChangeNotification) notification;
System.out.println("MBean attribute " + acn.getAttributeName() + " of type " +
acn.getAttributeType() +" changed from " + acn.getOldValue() + " to " + acn.getNewValue());
System.out.println("ttObserved Attribute: "+ acn.getAttributeName());
System.out.println("ttAttribute Type: "+acn.getAttributeType());
System.out.println("ttMessage: "+acn.getMessage());
System.out.println("ttTimeStamp: "+new Date(acn.getTimeStamp()));
System.out.println("ttOld Value: " + acn.getOldValue());
System.out.println("ttNew Value: " + acn.getNewValue());
}
}
}

Step14). Now provide the “CustomMBeanClient.java” Main program … inside “C:MBeanChangeNotificationClient” location as following:

package client;
import java.io.IOException;
import java.util.HashMap;
import java.util.Set;

import javax.management.AttributeChangeNotificationFilter;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class CustomMBeanClient
{
private static JMXConnector jmxConnector;
private static MBeanServerConnection mbsc;

private static void queryCustom() throws Exception
{
Set mbeans = mbsc.queryNames(null, null);
for (Object objectName : mbeans)
{
if(objectName.toString(). startsWith("mycustommbean"))
{
System.out.println("ntMbean Name = "+objectName.toString());
ObjectName custom=new ObjectName(objectName.toString());
listenChangeNotification(custom);
}
}
}

private static void listenChangeNotification(ObjectName mbName)
{
MyAttributeChangeListenerImpl listener = new MyAttributeChangeListenerImpl();
try {
mbsc.addNotificationListener(mbName, listener, null, null);
System.out.println("n[myListener]: Listener registered with " +mbName);

synchronized(listener)
{
System.out.println("Waiting for notification....");
listener.wait();
}
}
catch (InstanceNotFoundException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}

public static void initRemoteConnection() throws Exception
{
JMXServiceURL serviceURL =new JMXServiceURL("service:jmx:t3://localhost:7001/jndi/weblogic.management.mbeanservers.domainruntime");
System.out.println("Connecting to : " +serviceURL);

HashMap env = new HashMap();
env.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
env.put(javax.naming.Context.SECURITY_PRINCIPAL, "weblogic");
env.put(javax.naming.Context.SECURITY_CREDENTIALS, "weblogic");

jmxConnector = JMXConnectorFactory.connect(serviceURL, env);
mbsc = jmxConnector.getMBeanServerConnection();
}

public static void main(String[] args)
{
try {
initRemoteConnection();
queryCustom();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Step15). Now open a command prompt again and then compile and then run the above program…like folowing: (After running the “setWLSEnv.cmd”)

Step16). Now write the following WLST script to change the Custom MBean Attribute “Something”  using …”ChangeCustomMBeanAttrinute.py” inside “C:MBeanChangeNotificationClient” location

connect('weblogic','weblogic','t3://localhost:7001')
custom()
cd ('mycustommbean')
cd ('mycustommbean:Name=MyCustomMBean,Type=MyCustomMBean')
set('Something','AAAAAAA')

Step17). Running the above WLST script.

Step18). Finally what we got is everything working. 🙂

.
.
Thanks
Jay SenSharma

If you enjoyed this post, please considerleaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.