[seam-commits] Seam SVN: r11360 - branches/community/Seam_2_2/src/main/org/jboss/seam/jmx.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Mon Aug 10 19:27:39 EDT 2009


Author: norman.richards at jboss.com
Date: 2009-08-10 19:27:39 -0400 (Mon, 10 Aug 2009)
New Revision: 11360

Added:
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/AgentID.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/DefaultExceptionHandler.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/JMXInvocationHandler.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxy.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxyCreationException.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/Mbean.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyContext.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyExceptionHandler.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/RuntimeProxyException.java
   branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/package-info.java
Log:
JBSEAM-4339

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/AgentID.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/AgentID.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/AgentID.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,103 @@
+package org.jboss.seam.jmx;
+
+import java.net.InetAddress;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.util.Random;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedLong;
+
+import org.jboss.mx.server.ServerConstants;
+
+/**
+ * Utility class for creating JMX agent identifiers. Also contains the
+ * helper method for retrieving the <tt>AgentID</tt> of an existing MBean server
+ * instance.
+ *
+ * @see javax.management.MBeanServerDelegateMBean
+ *
+ * @author  <a href="mailto:juha at jboss.org">Juha Lindfors</a>.
+ * @version $Revision: 81019 $
+ *   
+ */
+public class AgentID 
+   implements ServerConstants
+{
+   // Static ----------------------------------------------------
+   private static SynchronizedLong id = new SynchronizedLong(0);
+
+   private static final Random rand = new Random(System.currentTimeMillis());
+
+   /**
+    * Creates a new agent ID string. The identifier is of the form
+    * <tt>&lt;ip.address&gt;/&lt;creation time in ms&gt;/&lt;VMID+(random int 0-100)&gt;/&lt;sequence #&gt;</tt>.<P>
+    *
+    * This AgentID string is globally unique.
+    *
+    * @return Agent ID string
+    */
+   public static String create()
+   {
+      String ipAddress = null;
+
+      try
+      {
+         ipAddress = (String) AccessController.doPrivileged(
+            new PrivilegedExceptionAction()
+            {
+               public Object run() throws Exception
+               {
+                  return InetAddress.getLocalHost().getHostAddress();
+               }
+            }
+         );
+      }
+      catch(PrivilegedActionException e)
+      {
+         ipAddress = "127.0.0.1";
+      }
+      // use the VMID to create a more unique ID that can be used to guarantee that this
+      // MBeanServerID is unique across multiple JVMs, even on the same host
+      String vmid = new java.rmi.dgc.VMID().toString().replace(':','x').replace('-','X') + rand.nextInt(100);
+
+      return ipAddress + "/" + System.currentTimeMillis() + "/" + vmid + "/"+ (id.increment());
+   }
+    /**
+     * test
+     *
+     * @param args
+     */
+   public static void main (String args[])
+   {
+       for (int c=0;c<10;c++)
+        System.out.println(AgentID.create());
+   }
+
+   /**
+    * Returns the agent identifier string of a given MBean server instance.
+    *
+    * @return <tt>MBeanServerId</tt> attribute of the MBean server delegate.
+    */
+   public static String get(MBeanServer server)
+   {
+      try 
+      {
+         ObjectName name = new ObjectName(MBEAN_SERVER_DELEGATE);
+         String agentID = (String)server.getAttribute(name, "MBeanServerId");   
+      
+         return agentID;
+      }
+      catch (Throwable t)
+      {
+         throw new Error("Cannot find the MBean server delegate: " + t.toString());
+      }
+   }
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/DefaultExceptionHandler.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/DefaultExceptionHandler.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/DefaultExceptionHandler.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,110 @@
+package org.jboss.seam.jmx;
+
+
+import java.lang.reflect.Method;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanException;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeErrorException;
+
+/**
+ * Default exception handler for MBean proxy.
+ *
+ * @author  <a href="mailto:juha at jboss.org">Juha Lindfors</a>.
+ * @version $Revision: 81019 $
+ *   
+ */
+public class DefaultExceptionHandler
+      implements ProxyExceptionHandler
+{
+
+   // InstanceNotFound, AttributeNotFound and InvalidAttributeValue
+   // are not exceptions declared in the mgmt interface and therefore
+   // must be rethrown as runtime exceptions to avoid UndeclaredThrowable
+   // exceptions on the client
+
+   public Object handleInstanceNotFound(ProxyContext ctx,
+                                        InstanceNotFoundException e,
+                                        Method m, Object[] args)
+                                        throws Exception
+   {
+      throw new RuntimeProxyException("Instance not found: " + e.toString());
+   }
+   
+   public Object handleAttributeNotFound(ProxyContext ctx,
+                                         AttributeNotFoundException e,
+                                         Method m, Object[] args)
+                                         throws Exception
+   {
+      throw new RuntimeProxyException("Attribute not found: " + e.toString());
+   }
+   
+   public Object handleInvalidAttributeValue(ProxyContext ctx,
+                                             InvalidAttributeValueException e,
+                                             Method m, Object[] args)
+                                             throws Exception
+   {
+      throw new RuntimeProxyException("Invalid attribute value: " + e.toString());
+   }
+   
+   public Object handleMBeanException(ProxyContext ctx, MBeanException e,
+                                      Method m, Object[] args)
+                                      throws Exception
+   {
+      // assuming MBeanException only wraps mgmt interface "application" 
+      // exceptions therefore we can safely rethrow the target exception
+      // as its declared in the mgmt interface
+      throw e.getTargetException();
+   }
+   
+   public Object handleReflectionException(ProxyContext ctx,
+                                           ReflectionException e,
+                                           Method m, Object[] args)
+                                           throws Exception
+   {
+      // use of reflection exception is inconsistent in the API so the 
+      // safest bet is to rethrow a runtime exception
+      
+      Exception target = e.getTargetException();
+      if (target instanceof RuntimeException)
+         throw target;
+      else
+         throw new RuntimeProxyException(target.toString());
+   }
+   
+   public Object handleRuntimeOperationsException(ProxyContext ctx,
+                                                  RuntimeOperationsException e,
+                                                  Method m, Object[] args)
+                                                  throws Exception
+   {
+      // target is always a runtime exception, so its ok to throw it from here
+      throw e.getTargetException();
+   }
+   
+   public Object handleRuntimeMBeanException(ProxyContext ctx,
+                                             RuntimeMBeanException e,
+                                             Method m, Object[] args)
+                                             throws Exception
+   {
+      // target is always a runtime exception, so its ok to throw it from here
+      throw e.getTargetException();
+   }
+   
+   public Object handleRuntimeError(ProxyContext ctx, RuntimeErrorException e,
+                                    Method m, Object[] args)
+                                    throws Exception
+   {
+      // just unwrap and throw the actual error
+      throw e.getTargetError();
+   }
+   
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/JMXInvocationHandler.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/JMXInvocationHandler.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/JMXInvocationHandler.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,445 @@
+package org.jboss.seam.jmx;
+
+
+import java.io.Serializable;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import java.util.HashMap;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeErrorException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
+
+/**
+ * Invocation handler for MBean proxies.
+ *
+ * @author  <a href="mailto:juha at jboss.org">Juha Lindfors</a>.
+ * @version $Revision: 81019 $
+ *   
+ */
+public class JMXInvocationHandler 
+      implements ProxyContext, InvocationHandler, Serializable
+{  
+   private static final long serialVersionUID = 3714728148040623702L;
+   
+   // Attributes -------------------------------------------------
+   
+   /**
+    * Reference to the MBean server this proxy connects to.
+    */
+   protected MBeanServer server    = null;
+   
+   /**
+    * The object name of the MBean this proxy represents.
+    */
+   protected ObjectName objectName = null;
+   
+   /**
+    * Default exception handler for the proxy.
+    */
+   private ProxyExceptionHandler handler = new DefaultExceptionHandler();
+   
+   /**
+    * MBean attribute meta data.
+    */
+   private HashMap attributeMap          = new HashMap();
+   
+   /**
+    * Indicates whether Object.toString() should be delegated to the resource
+    * or handled by the proxy.
+    */
+   private boolean delegateToStringToResource = false;
+
+   /**
+    * Indicates whether Object.equals() should be delegated to the resource
+    * or handled by the proxy.
+    */
+   private boolean delegateEqualsToResource   = false;
+
+   /**
+    * Indicates whether Object.hashCode() should be delegated to the resource
+    * or handled by the proxy.
+    */
+   private boolean delegateHashCodeToResource = false;
+   
+   
+   // Constructors -----------------------------------------------
+   
+   /**
+    * Constructs a new JMX MBean Proxy invocation handler.
+    *
+    * @param server  reference to the MBean server this proxy connects to
+    * @param name    object name of the MBean this proxy represents
+    *
+    * @throws MBeanProxyCreationException wraps underlying JMX exceptions in
+    *         case the proxy creation fails
+    */
+   public JMXInvocationHandler(MBeanServer server, ObjectName name) 
+      throws MBeanProxyCreationException
+   {
+      try
+      {
+         if (server == null)
+            throw new MBeanProxyCreationException("null agent reference");
+            
+         this.server     = server;
+         this.objectName = name;
+         
+         MBeanInfo info = server.getMBeanInfo(objectName);
+         MBeanAttributeInfo[] attributes = info.getAttributes();
+         MBeanOperationInfo[] operations = info.getOperations();
+         
+         // collect the MBean attribute metadata for standard mbean proxies
+         for (int i = 0; i < attributes.length; ++i)
+            attributeMap.put(attributes[i].getName(), attributes[i]);
+         
+         // Check whether the target resource exposes the common object methods.
+         // Dynamic Proxy will delegate these methods automatically to the
+         // invoke() implementation.
+         for (int i = 0; i < operations.length; ++i)
+         {
+            if (operations[i].getName().equals("toString") &&
+                operations[i].getReturnType().equals("java.lang.String") &&
+                operations[i].getSignature().length == 0)
+            {
+               delegateToStringToResource = true;  
+            }
+            
+            else if (operations[i].getName().equals("equals") &&
+                     operations[i].getReturnType().equals(Boolean.TYPE.getName()) &&
+                     operations[i].getSignature().length == 1 &&
+                     operations[i].getSignature() [0].getType().equals("java.lang.Object"))
+            {
+               delegateEqualsToResource = true;
+            }
+            
+            else if (operations[i].getName().equals("hashCode") &&
+                     operations[i].getReturnType().equals(Integer.TYPE.getName()) &&
+                     operations[i].getSignature().length == 0)
+            {
+               delegateHashCodeToResource = true;  
+            }
+         }
+      }
+      catch (InstanceNotFoundException e)
+      {
+         throw new MBeanProxyCreationException("Object name " + name + " not found: " + e.toString());
+      }
+      catch (IntrospectionException e)
+      {
+         throw new MBeanProxyCreationException(e.toString());
+      }
+      catch (ReflectionException e)
+      {
+         throw new MBeanProxyCreationException(e.toString());
+      }
+   }
+   
+   
+   // InvocationHandler implementation ---------------------------
+   
+   public Object invoke(Object proxy, Method method, Object[] args) 
+      throws Exception
+   {
+      Class declaringClass = method.getDeclaringClass();
+      
+      // Handle methods from Object class. If the target resource exposes 
+      // operation metadata with same signature then the invocations will be
+      // delegated to the target. Otherwise this instance of invocation handler
+      // will execute them.
+      if (declaringClass == Object.class)
+         return handleObjectMethods(method, args);
+      
+      // Check methods from ProxyContext interface. If invoked, delegate
+      // to the context implementation part of this invocation handler.
+      if (declaringClass == ProxyContext.class)
+         return method.invoke(this, args);
+      
+      // Check methods from DynamicMBean interface. This allows the proxy
+      // to be used in cases where the underlying metadata has changed (a la
+      // Dynamic MBean).
+      if (declaringClass == DynamicMBean.class)
+         return handleDynamicMBeanInvocation(method, args);
+      
+      try 
+      {
+         String methodName = method.getName();
+         
+         // Assume a get/setAttribute convention on the typed proxy interface.
+         // If the MBean metadata exposes a matching attribute then use the
+         // MBeanServer attribute accessors to read/modify the value. If not,
+         // fallback to MBeanServer.invoke() assuming this is an operation
+         // invocation despite the accessor naming convention.
+         
+         // getter
+         if (methodName.startsWith("get") && args == null)
+         {
+            String attrName = methodName.substring(3, methodName.length());
+            
+            // check that the metadata exists
+            MBeanAttributeInfo info = (MBeanAttributeInfo)attributeMap.get(attrName);
+            if (info != null)
+            {
+               String retType  = method.getReturnType().getName();
+      
+               // check for correct return type on the getter         
+               if (retType.equals(info.getType())) 
+               {
+                  return server.getAttribute(objectName, attrName);
+               }
+            }
+         }
+         
+         // boolean getter
+         else if (methodName.startsWith("is") && args == null)
+         {
+            String attrName = methodName.substring(2, methodName.length());
+            
+            // check that the metadata exists
+            MBeanAttributeInfo info = (MBeanAttributeInfo)attributeMap.get(attrName);
+            if (info != null && info.isIs())
+            {
+               Class retType = method.getReturnType();
+               
+               // check for correct return type on the getter
+               if (retType.equals(Boolean.class) || retType.equals(Boolean.TYPE))
+               {
+                  return server.getAttribute(objectName, attrName);
+               }
+            }
+         }
+         
+         // setter
+         else if (methodName.startsWith("set") && args != null && args.length == 1)
+         {
+            String attrName = methodName.substring(3, methodName.length());
+            
+            // check that the metadata exists
+            MBeanAttributeInfo info = (MBeanAttributeInfo)attributeMap.get(attrName);
+            if (info != null && method.getReturnType().equals(Void.TYPE))
+            {
+               ClassLoader cl = Thread.currentThread().getContextClassLoader();
+               
+               Class signatureClass = null;
+               String classType     = info.getType();
+               
+               if (isPrimitive(classType))
+                  signatureClass = getPrimitiveClass(classType);
+               else
+                  signatureClass = cl.loadClass(info.getType());
+               
+               if (signatureClass.isAssignableFrom(args[0].getClass()))
+               {
+                  server.setAttribute(objectName, new Attribute(attrName, args[0]));
+                  return null;
+               }
+            }
+         }
+
+         String[] signature = null;
+         
+         if (args != null)
+         {
+            signature = new String[args.length];
+            Class[] sign = method.getParameterTypes();
+            
+            for (int i = 0; i < sign.length; ++i)
+               signature[i] = sign[i].getName();
+         }
+         
+         return server.invoke(objectName, methodName, args, signature);
+      }
+      catch (InstanceNotFoundException e)
+      {
+         return getExceptionHandler().handleInstanceNotFound(this, e, method, args);
+      }
+      catch (AttributeNotFoundException e)
+      {
+         return getExceptionHandler().handleAttributeNotFound(this, e, method, args);
+      }
+      catch (InvalidAttributeValueException e)
+      {
+         return getExceptionHandler().handleInvalidAttributeValue(this, e, method, args);
+      }
+      catch (MBeanException e)
+      {
+         return getExceptionHandler().handleMBeanException(this, e, method, args);
+      }
+      catch (ReflectionException e)
+      {
+         return getExceptionHandler().handleReflectionException(this, e, method, args);
+      }
+      catch (RuntimeOperationsException e)
+      {
+         return getExceptionHandler().handleRuntimeOperationsException(this, e, method, args);
+      }
+      catch (RuntimeMBeanException e)
+      {
+         return getExceptionHandler().handleRuntimeMBeanException(this, e, method, args);
+      }
+      catch (RuntimeErrorException e)
+      {
+         return getExceptionHandler().handleRuntimeError(this, e, method, args);
+      }
+   }
+
+   public ProxyExceptionHandler getExceptionHandler()
+   {
+      return handler;
+   }
+   
+   
+   // ProxyContext implementation -----------------------------------
+   
+   // The proxy provides an access point for the client to methods not part
+   // of the MBean's management interface. It can be used to configure the
+   // invocation (with context, client side interceptors, RPC), exception
+   // handling, act as an access point to MBean server interface and so on.
+      
+   public void setExceptionHandler(ProxyExceptionHandler handler)
+   {
+      this.handler = handler;
+   }
+   
+   public MBeanServer getMBeanServer() 
+   {
+      return server;
+   }      
+
+   public ObjectName getObjectName()
+   {
+      return objectName;
+   }
+   
+   
+   // Object overrides ----------------------------------------------
+   
+   public String toString() 
+   {
+      return "MBeanProxy for " + objectName + " (Agent ID: " + AgentID.get(server) + ")";
+   }
+   
+   
+   // Private -------------------------------------------------------
+   
+   private Object handleObjectMethods(Method method, Object[] args)
+      throws InstanceNotFoundException, ReflectionException,
+      IntrospectionException, MBeanException
+   {
+      if (method.getName().equals("toString"))
+      {
+         if (delegateToStringToResource)
+            return server.invoke(objectName, "toString", null, null);
+         else
+            return toString();
+      }
+      
+      else if (method.getName().equals("equals"))
+      {
+         if (delegateEqualsToResource)
+         {
+            return server.invoke(objectName, "equals", 
+                                 new Object[] { args[0] },
+                                 new String[] { "java.lang.Object" }
+            );
+         }
+         else if (Proxy.isProxyClass(args[0].getClass()))
+         {
+            Proxy prxy = (Proxy)args[0];
+            return new Boolean(this.equals(Proxy.getInvocationHandler(prxy)));
+         }
+         else
+         {
+            return new Boolean(this.equals(args[0]));
+         }
+      }
+      
+      else if (method.getName().equals("hashCode"))
+      {
+         if (delegateHashCodeToResource)
+            return server.invoke(objectName, "hashCode", null, null);
+         else  
+            return new Integer(this.hashCode());
+      }
+      
+      else throw new Error("Unexpected method invocation!");
+   }
+   
+   private Object handleDynamicMBeanInvocation(Method method, Object[] args)
+      throws InstanceNotFoundException, ReflectionException,
+      IntrospectionException, MBeanException, AttributeNotFoundException,
+      InvalidAttributeValueException
+   {
+      String methodName = method.getName();
+      
+      if (methodName.equals("setAttribute"))
+      {
+         server.setAttribute(objectName, (Attribute)args[0]);
+         return null;
+      }
+      else if (methodName.equals("setAttributes"))
+         return server.setAttributes(objectName, (AttributeList)args[0]);
+      else if (methodName.equals("getAttribute"))
+         return server.getAttribute(objectName, (String)args[0]);
+      else if (methodName.equals("getAttributes"))
+         return server.getAttributes(objectName, (String[])args[0]);
+      else if (methodName.equals("invoke"))
+         return server.invoke(objectName, (String)args[0], (Object[])args[1], (String[])args[2]);
+      else if (methodName.equals("getMBeanInfo"))
+         return server.getMBeanInfo(objectName);
+      
+      else throw new Error("Unexpected method invocation!");
+   }
+
+   private boolean isPrimitive(String type)
+   {
+      if (type.equals(Integer.TYPE.getName()))   return true;
+      if (type.equals(Long.TYPE.getName()))      return true;
+      if (type.equals(Boolean.TYPE.getName()))   return true;
+      if (type.equals(Byte.TYPE.getName()))      return true;
+      if (type.equals(Character.TYPE.getName())) return true;
+      if (type.equals(Short.TYPE.getName()))     return true;
+      if (type.equals(Float.TYPE.getName()))     return true;
+      if (type.equals(Double.TYPE.getName()))    return true;
+      if (type.equals(Void.TYPE.getName()))      return true;
+      
+      return false;
+   }
+
+   private Class getPrimitiveClass(String type)
+   {
+      if (type.equals(Integer.TYPE.getName()))  return Integer.TYPE;
+      if (type.equals(Long.TYPE.getName()))     return Long.TYPE;
+      if (type.equals(Boolean.TYPE.getName()))  return Boolean.TYPE;
+      if (type.equals(Byte.TYPE.getName()))     return Byte.TYPE;
+      if (type.equals(Character.TYPE.getName()))return Character.TYPE;
+      if (type.equals(Short.TYPE.getName()))    return Short.TYPE;
+      if (type.equals(Float.TYPE.getName()))    return Float.TYPE;
+      if (type.equals(Double.TYPE.getName()))   return Double.TYPE;
+      if (type.equals(Void.TYPE.getName()))     return Void.TYPE;
+      
+      return null;
+   }
+   
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxy.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxy.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxy.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,119 @@
+package org.jboss.seam.jmx;
+
+import java.lang.reflect.Proxy;
+
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+public class MBeanProxy
+{
+
+   // Static --------------------------------------------------------
+   
+   /**
+    * Creates a proxy to an MBean in the given MBean server.
+    *
+    * @param   intrface    the interface this proxy implements
+    * @param   name        object name of the MBean this proxy connects to
+    * @param   agentID     agent ID of the MBean server this proxy connects to
+    *
+    * @return  proxy instance
+    *
+    * @throws MBeanProxyCreationException if the proxy could not be created
+    */
+   public static Object get(Class intrface, ObjectName name, String agentID) throws MBeanProxyCreationException
+   {
+      return get(intrface, name, (MBeanServer)MBeanServerFactory.findMBeanServer(agentID).get(0));
+   }
+
+   /**
+    * Creates a proxy to an MBean in the given MBean server.
+    *
+    * @param   intrface the interface this proxy implements
+    * @param   name     object name of the MBean this proxy connects to
+    * @param   server   MBean server this proxy connects to
+    *
+    * @return proxy instance
+    *
+    * @throws MBeanProxyCreationException if the proxy could not be created
+    */
+   public static Object get(Class intrface, ObjectName name, MBeanServer server)  throws MBeanProxyCreationException
+   {
+      return get(new Class[] { intrface, ProxyContext.class, DynamicMBean.class }, name, server);
+   }
+
+   /**
+    */
+   public static Object get(ObjectName name, MBeanServer server)  throws MBeanProxyCreationException
+   {
+      return get(new Class[] { ProxyContext.class, DynamicMBean.class }, name, server);
+   }
+
+   private static Object get(Class[] interfaces, ObjectName name, MBeanServer server) throws MBeanProxyCreationException
+   {
+      return Proxy.newProxyInstance(
+            Thread.currentThread().getContextClassLoader(),
+            interfaces, new JMXInvocationHandler(server, name)
+      );
+   }
+   
+   /**
+    * Convenience method for registering an MBean and retrieving a proxy for it.
+    *
+    * @param   instance MBean instance to be registered
+    * @param   intrface the interface this proxy implements
+    * @param   name     object name of the MBean
+    * @param   agentID  agent ID of the MBean server this proxy connects to
+    *
+    * @return proxy instance
+    *
+    * @throws MBeanProxyCreationException if the proxy could not be created
+    */
+   public static Object create(Class instance, Class intrface, ObjectName name, String agentID) throws MBeanProxyCreationException
+   {
+      return create(instance, intrface, name, (MBeanServer)MBeanServerFactory.findMBeanServer(agentID).get(0));
+   }   
+   
+   /**
+    * Convenience method for registering an MBean and retrieving a proxy for it.
+    *
+    * @param   instance MBean instance to be registered
+    * @param   intrface the interface this proxy implements
+    * @param   name     object name of the MBean
+    * @param   server   MBean server this proxy connects to
+    *
+    * @throws MBeanProxyCreationException if the proxy could not be created
+    */
+   public static Object create(Class instance, Class intrface, ObjectName name, MBeanServer server) throws MBeanProxyCreationException
+   {
+      try
+      {
+         server.createMBean(instance.getName(), name);
+         return get(intrface, name, server);
+      }
+      catch (ReflectionException e) {
+         throw new MBeanProxyCreationException("Creating the MBean failed: " + e.toString());
+      }
+      catch (InstanceAlreadyExistsException e) {
+         throw new MBeanProxyCreationException("Instance already exists: " + name);
+      }
+      catch (MBeanRegistrationException e) {
+         throw new MBeanProxyCreationException("Error registering the MBean to the server: " + e.toString());
+      }
+      catch (MBeanException e) {
+         throw new MBeanProxyCreationException(e.toString());
+      }
+      catch (NotCompliantMBeanException e) {
+         throw new MBeanProxyCreationException("Not a compliant MBean " + instance.getClass().getName() + ": " + e.toString());
+      }
+   }
+   
+}
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxyCreationException.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxyCreationException.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/MBeanProxyCreationException.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,24 @@
+package org.jboss.seam.jmx;
+
+import javax.management.JMException;
+
+public class MBeanProxyCreationException
+   extends JMException
+{
+   private static final long serialVersionUID = 1008637966352433381L;
+
+   // Constructors --------------------------------------------------
+   public MBeanProxyCreationException() 
+   {
+      super();
+   }
+   
+   public MBeanProxyCreationException(String msg)
+   {
+      super(msg);
+   }
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/Mbean.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/Mbean.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/Mbean.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,46 @@
+package org.jboss.seam.jmx;
+
+import javax.management.ObjectName;
+
+import org.jboss.seam.annotations.Unwrap;
+
+public class Mbean
+{
+    String objectName;
+    String agentId;
+    String proxyClass;
+    
+    public String getAgentId() {
+        return agentId;
+    }
+
+    public void setAgentId(String agentId) {
+        this.agentId = agentId;
+    }
+
+    public String getObjectName() {
+        return objectName;
+    }
+   
+    public void setObjectName(String objectName) {
+        this.objectName = objectName;
+    }
+   
+    public String getProxyClass() {
+        return proxyClass;
+    }
+   
+    public void setProxyClass(String proxyClass) {
+        this.proxyClass = proxyClass;
+    }
+   
+    @Unwrap 
+    public Object createProxy() {
+        try {
+            Object o = MBeanProxy.get(Class.forName(proxyClass), new ObjectName(getObjectName()), getAgentId());
+            return o;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyContext.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyContext.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyContext.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,23 @@
+package org.jboss.seam.jmx;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+/**
+ *
+ * @author  <a href="mailto:juha at jboss.org">Juha Lindfors</a>.
+ * @version $Revision: 81019 $
+ *   
+ */
+public interface ProxyContext
+{
+   void setExceptionHandler(ProxyExceptionHandler handler);
+   
+   MBeanServer getMBeanServer();
+   
+   ObjectName getObjectName();
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyExceptionHandler.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyExceptionHandler.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/ProxyExceptionHandler.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,40 @@
+package org.jboss.seam.jmx;
+
+import java.lang.reflect.Method;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanException;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeErrorException;
+
+/**
+ *
+ * @author  <a href="mailto:juha at jboss.org">Juha Lindfors</a>.
+ * @version $Revision: 81019 $
+ */
+public interface ProxyExceptionHandler
+{
+   public Object handleInstanceNotFound(ProxyContext ctx, InstanceNotFoundException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleAttributeNotFound(ProxyContext ctx, AttributeNotFoundException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleInvalidAttributeValue(ProxyContext ctx, InvalidAttributeValueException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleMBeanException(ProxyContext ctx, MBeanException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleReflectionException(ProxyContext ctx, ReflectionException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleRuntimeOperationsException(ProxyContext ctx, RuntimeOperationsException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleRuntimeMBeanException(ProxyContext ctx, RuntimeMBeanException e, Method m, Object[] args) throws Exception;
+   
+   public Object handleRuntimeError(ProxyContext ctx, RuntimeErrorException e, Method m, Object[] args) throws Exception;
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/RuntimeProxyException.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/RuntimeProxyException.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/RuntimeProxyException.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,29 @@
+package org.jboss.seam.jmx;
+
+import javax.management.JMRuntimeException;
+
+/**
+ *
+ * @author  <a href="mailto:juha at jboss.org">Juha Lindfors</a>.
+ * @version $Revision: 81019 $  
+ */
+public class RuntimeProxyException
+   extends JMRuntimeException
+{
+   private static final long serialVersionUID = -1166909485463779459L;
+
+   // Constructors --------------------------------------------------
+   public RuntimeProxyException() 
+   {
+      super();
+   }
+   
+   public RuntimeProxyException(String msg)
+   {
+      super(msg);
+   }
+}
+      
+
+
+

Added: branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/package-info.java
===================================================================
--- branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/package-info.java	                        (rev 0)
+++ branches/community/Seam_2_2/src/main/org/jboss/seam/jmx/package-info.java	2009-08-10 23:27:39 UTC (rev 11360)
@@ -0,0 +1,6 @@
+ at Namespace(value="http://jboss.com/products/seam/jmx", prefix="org.jboss.seam.jmx")
+ at AutoCreate
+package org.jboss.seam.jmx;
+
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Namespace;



More information about the seam-commits mailing list