Hi,
I developed the code to load all jmx-rmi classes at run-time.
Now the JMX front can register any object as an MBean and publish it in RMI.
It does not depend on any jmx or jmx-rmi classes at the compile-time.
I have developed a simple MBean as a prototype, which can do following tasks:
> list all services and modules
> list faulty services and modules
> list all phases
> list all operations of a given service
> engage a module globally
> engage a module to a service
> engage a module to an operation
What would be the other possible tasks that we can do through the JMX front?
Do we need to develop an Axis2 specific JMX client other than
accessing Axis2 JMX front using jmx clients like JConsole or JManage?
I think if we develop a seperate JMX client for Axis2, we can add
functionality to save the configuration of one Axis2 engine (to an XML
file) and load the same configuration to a different Axis2 engine.
This functionality would be helpful if we want to apply the same
configuration (may be with minor modifications) to many Axis2 engines
running on different servers. But I am not sure whether this is
required, because I have no experience in server management.
It also can be developed to display the configuration information
nicely without restricting to the standard formats supported by the
normal JMX clients.
My code is at
https://svn.apache.org/repos/asf/webservices/axis/trunk/archive/java/scratch/jmx-front/.
Please commit the attached patch to that URL.
Regards,
Chathura
Index: org/apache/axis2/management/manager/JMXAdmin.java
===================================================================
--- org/apache/axis2/management/manager/JMXAdmin.java (revision 234155)
+++ org/apache/axis2/management/manager/JMXAdmin.java (working copy)
@@ -4,6 +4,12 @@
import org.apache.axis2.engine.AxisFault;
import org.apache.axis2.management.mbeans.Axis2Manager;
+/**
+ * JMXAdmin creates necessary MBeans and registers them using the JMXManager.
It is assumed that all
+ * MBean registrations will be done in this class. Currently Axis2 has only a
single MBean to wrap
+ * its management functionality.
+ *
+ */
public class JMXAdmin{
/**
@@ -17,11 +23,11 @@
try{
// Create MBeans
- String axis2ManagerName =
"Axis2:type=management.Manager,index=1";
+ String axis2ManagerName =
"Axis2:type=management.Manager";
Axis2Manager axis2Manager = new
Axis2Manager(configContext.getAxisConfiguration());
// Register MBeans using JMXManager
- JMXManagerR jmxManager = JMXManagerR.getJMXManagerR();
+ JMXManager jmxManager = JMXManager.getJMXManager();
jmxManager.registerMBean(axis2Manager,
axis2ManagerName);
Index: org/apache/axis2/management/manager/JMXManager.java
===================================================================
--- org/apache/axis2/management/manager/JMXManager.java (revision 234155)
+++ org/apache/axis2/management/manager/JMXManager.java (working copy)
@@ -3,24 +3,35 @@
import org.apache.axis2.engine.AxisFault;
import java.rmi.registry.LocateRegistry;
-import org.apache.commons.modeler.Registry;
+import java.util.Map;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * JMXManager manages everything related to registering and publishing MBeans.
It is not aware about
+ * the MBeans it is going to publish. Instead it provides a set of methods to
register and publish any
+ * object as an MBean. Currently only JMXAdmin uses this to publish MBeans.
But this can be used by any module
+ * to publish objects for management. This is a singleton class and the users
should use the "getJMXManager"
+ * factory method to obtain an instance of this.
+ *
+ */
public class JMXManager{
- private Registry registry;
private static JMXManager jmxManager = null;
- private MBeanServer mbs = null;
- JMXConnectorServer cs;
+ private Class registryClass = null;
+ private Object registry = null;
+ private Method registerComponent = null;
- public static JMXManager getJMXManager(){
+ /**
+ * This is a factory method to create a JMXManager. Only one JMXManager
instance is allowed.
+ *
+ * @throws AxisFault
+ */
+ public static JMXManager getJMXManager() throws AxisFault{
if(jmxManager != null){
return jmxManager;
@@ -32,77 +43,138 @@
}
- private JMXManager(){
+ /**
+ * Initializes the modeler and publishes the MBeanServer in RMI.
+ *
+ * @throws AxisFault
+ */
+ private JMXManager() throws AxisFault{
+
try{
- initMBeanServer();
+ initModeler();
publishRMI();
}catch(Exception e){
+ throw AxisFault.makeFault(e);
}
+
}
- public void startMBeanServer() throws AxisFault{
+ /**
+ * This method initializes the modeler registry. An MBeanServer is
created if it was not alrady
+ * created.
+ *
+ * @throws AxisFault
+ */
+ public boolean initModeler() throws Exception{
+ try {
+ registryClass =
Class.forName("org.apache.commons.modeler.Registry");
+ } catch (ClassNotFoundException e) {
+ registry = null;
+ return false;
+ }
- try{
- //initMBeans();
- }catch(Exception e){
- throw new AxisFault(e.getMessage());
- }
+ try {
+ Class[] getRegistryArgs = new Class[]{Object.class,
Object.class,};
+ Method getRegistry =
registryClass.getMethod("getRegistry", getRegistryArgs);
+ Object[] getRegistryOptions = new Object[]{null, null};
+ registry = getRegistry.invoke(null, getRegistryOptions);
- }
+ Class[] registerComponentArgs = new
Class[]{Object.class, String.class, String.class};
+ registerComponent =
registryClass.getMethod("registerComponent", registerComponentArgs);
+ } catch (IllegalAccessException e) {
+ throw e;
+ } catch (IllegalArgumentException e) {
+ throw e;
+ } catch (InvocationTargetException e) {
+ throw e;
+ } catch (NoSuchMethodException e) {
+ throw e;
+ }
+ return true;
+ }
- public void initModeler() throws Exception{
- Registry registry = Registry.getRegistry(null, null);
- mbs = registry.getMBeanServer();
+ /**
+ * This method is used to register MBeans. It registers any object
provided to it as an MBean.
+ * All public fields and methods of the object will be exposed for
management.
+ *
+ * @param mbean
+ * @param mbeanName
+ * @throws AxisFault
+ */
+ public boolean registerMBean(Object mbean, String mbeanName) throws
Exception{
- }
+ String context = "Axis2";
+ if (registry != null) {
+ Object args[] = new Object[]{mbean, mbeanName,
context};
+ try {
+ registerComponent.invoke(registry,
args);
+ } catch (IllegalAccessException e) {
+ return false;
+ } catch (IllegalArgumentException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ return false;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
- public void registerModelerMBeans(Object mbean, String mbeanName)
throws Exception{
- registry.registerComponent(mbean, mbeanName, "Axis2Manager");
- }
+ /**
+ * Publishes the MBeanServer in RMI. Currently this method is called in
the constructor, so that the
+ * MBeanServer is always published. But it is yet to be decided whether
to make this optional. In such
+ * case JMXAdmin admin may call this, if it is activated by the
adminstrator.
+ *
+ * @throws AxisFault
+ */
+ public void publishRMI() throws Exception{
- private void initMBeanServer() throws Exception{
+ java.rmi.registry.Registry reg=null; // RMI registry
- // try to find existing MBeanServers. If there are no
MBeanServers create a new one for Axis2
- if (MBeanServerFactory.findMBeanServer(null).size() >
0) {
- mbs = (MBeanServer)
MBeanServerFactory.findMBeanServer(null).get(0);
- } else {
- mbs = MBeanServerFactory.createMBeanServer();
- }
+ // create RMI registry on port 9995
+ try {
+ if( reg==null )
+ reg=LocateRegistry.createRegistry(9995);
+ } catch(Exception e) {
+ throw new AxisFault(e.getMessage());
+ }
- }
+ // Retreive the MBeanServer used by the modeler
+ Method getMBeanServer =
registryClass.getMethod("getMBeanServer", null);
+ Object mbs = getMBeanServer.invoke(registry, null);
+ // create an JMXServiceURL object with the service URL
+ Class jmxServiceURLClass =
Class.forName("javax.management.remote.JMXServiceURL");
+ Class[] constructorArgs = new Class[]{String.class};
+ Constructor jmxServiceURLConstructor =
jmxServiceURLClass.getConstructor(constructorArgs);
- public void registerMBean(Object mbean, String mbeanName) throws
Exception{
+ String serviceURL =
"service:jmx:rmi:///jndi/rmi://localhost:9995/axis2";
+ Object jmxServiceURL =
jmxServiceURLConstructor.newInstance(new String[]{serviceURL});
- ObjectName mbeanObjectName = ObjectName.getInstance(mbeanName);
- mbs.registerMBean(mbean, mbeanObjectName);
- }
+ // Create and start a JMXConnector server
+ Class mbeanServerClass =
Class.forName("javax.management.MBeanServer");
+ Class jmxConnectorServerFactoryClass =
Class.forName("javax.management.remote.JMXConnectorServerFactory");
+ Class[] newJMXConnectorServerArgsTypes = new
Class[]{jmxServiceURLClass, Map.class, mbeanServerClass};
+ Method newJMXConnectorServer =
jmxConnectorServerFactoryClass.getMethod("newJMXConnectorServer",
newJMXConnectorServerArgsTypes);
+ Object[] newJMXConnectorServerArgs = {jmxServiceURL,
null, mbs};
+ Object jmxConnectorServer =
newJMXConnectorServer.invoke(null, newJMXConnectorServerArgs);
- public void publishRMI() throws Exception{
+ Class jmxConnectorServerClass =
Class.forName("javax.management.remote.JMXConnectorServer");
+ Method start =
jmxConnectorServerClass.getMethod("start", null);
+ start.invoke(jmxConnectorServer, null);
- // RMI registry
- java.rmi.registry.Registry reg=null;
+ }
- try {
- if( reg==null )
- reg=LocateRegistry.createRegistry(9995);
- } catch(Exception e) {
- throw new AxisFault(e.getMessage());
- }
- JMXServiceURL url = new
JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9995/axis2");
- cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null,
mbs);
- cs.start();
- }
-
}
\ No newline at end of file