Pages

Friday, November 16, 2007

jmx for starting background processes

The oc4j container support jmx, with this you can use mbeans to check the status of processes change application variables or you can start or stop background processes. You don't need to make a custom page with buttons to see the mbeans you can do this in the enterprise manager website.
If you deploy the ear then you have in the administration page of the deployed application a link to the mbeans.

If you click on this link then you see the mbeans of the application. On the left site you see the registered mbeans and on the right you see two tabs , The first are the attributes and the second tab are the operations where you can start methods

Here we see two operations

Let's start databaseaction, in my example it updates the time variable to the current time

In a mbean you have to define some methods
public MBeanAttributeInfo[] getMBeanAttributeInfo() , the attribute information
public MBeanOperationInfo[] getMBeanOperationInfo(), the supported operations
public String getMBeanName() , the name of the bean
public String getMBeanDescription() , bean description
public MBeanConstructorInfo[] getMBeanConstructorInfo() constructor
Here you see the bean.


public class EmployeesMBean extends StandardMBean implements ManagementMBean {

public EmployeesMBean() throws NotCompliantMBeanException {
super(ManagementMBean.class);
}
private Date time;

public String getMBeanName() {
return this.getClass().getName();
}
public String getMBeanDescription() {
return "jmx example";
}
public MBeanConstructorInfo[] getMBeanConstructorInfo() {
return new MBeanConstructorInfo[] { new MBeanConstructorInfo(getMBeanName(),
"Constructor MBean",
null) };
}
public MBeanAttributeInfo[] getMBeanAttributeInfo() {
MBeanAttributeInfo[] attr =
{ new MBeanAttributeInfo("time", "java.util.Date",
"time when the service is started", true,
false, false)
};
return attr;
}
public MBeanOperationInfo[] getMBeanOperationInfo() {
MBeanOperationInfo[] ops =
new MBeanOperationInfo[] { new MBeanOperationInfo("start",
"start the service.",
null, "void",
MBeanOperationInfo.ACTION),
new MBeanOperationInfo("databaseaction",
"Get the database time",
null, "void",
MBeanOperationInfo.ACTION) };
return ops;
}
public void start() {
this.time = new Date();
}
public void databaseaction() {
this.time = new Date();
}
public Date getTime() {
return time;
}
}


The next step is to make a ServletContextListener which register the bean when the webapp starts up


public class ScottServletContextListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent sce) {
}
public void contextInitialized(ServletContextEvent sce) {
try {
MBeanServer mbs = MBeanServerFactory.newMBeanServer();

//Taken:
registerMBean(mbs,
"nl.ordina.scott.jmx.EmployeesMBean",
":type=Scott,name=EmployeesMBean");
startServices();
} catch (Throwable t) {
t.printStackTrace();
}
}
private void registerMBean(MBeanServer server, String beanClass,
String naam) {
try {
Object bean = Class.forName(beanClass).newInstance();
ObjectName oName =
new ObjectName(server.getDefaultDomain() + naam);
server.registerMBean(bean, oName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (NotCompliantMBeanException e) {
e.printStackTrace();
} catch (InstanceAlreadyExistsException e) {
e.printStackTrace();
} catch (MBeanRegistrationException e) {
e.printStackTrace();
}
}
private void startServices() {
startService(":type=Scott,name=EmployeesMBean");
}
private void startService(String objectname) {
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
try {
ObjectName name =
new ObjectName(mbs.getDefaultDomain() + objectname);
mbs.invoke(name, "start", null, null);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (MBeanException e) {
e.printStackTrace();
} catch (ReflectionException e) {
e.printStackTrace();
} catch (InstanceNotFoundException e) {
e.printStackTrace();
}
}
private void stopServices() {
//Taken:
stopService(":type=Scott,name=EmployeesMBean");
}
private void stopService(String objectname) {
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
try {
ObjectName name =
new ObjectName(mbs.getDefaultDomain() + objectname);
mbs.invoke(name, "stop", null, null);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (MBeanException e) {
e.printStackTrace();
} catch (ReflectionException e) {
e.printStackTrace();
} catch (InstanceNotFoundException e) {
e.printStackTrace();
}
}
}



the last step is we edit the web.xml for the servercontextlistener


here is the example workspace

2 comments:

  1. Hi,

    Scott is a Oracle database schema with a department and employee table.

    nothing special

    thanks Edwin

    ReplyDelete