Author: julien(a)jboss.com
Date: 2007-05-17 06:17:48 -0400 (Thu, 17 May 2007)
New Revision: 7268
Added:
trunk/jems/src/main/org/jboss/portal/jems/as/system/JMXConstants.java
trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjection.java
trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjector.java
Modified:
trunk/jems/src/main/org/jboss/portal/jems/as/system/JBossServiceModelMBean.java
Log:
added possibility to unwrap JMX dynamic proxies and replace them by the POJOs, disabled by
default for now as it is experimental
Modified: trunk/jems/src/main/org/jboss/portal/jems/as/system/JBossServiceModelMBean.java
===================================================================
---
trunk/jems/src/main/org/jboss/portal/jems/as/system/JBossServiceModelMBean.java 2007-05-16
20:25:06 UTC (rev 7267)
+++
trunk/jems/src/main/org/jboss/portal/jems/as/system/JBossServiceModelMBean.java 2007-05-17
10:17:48 UTC (rev 7268)
@@ -27,6 +27,8 @@
import org.jboss.mx.server.InvocationContext;
import org.jboss.mx.server.Invocation;
import org.jboss.mx.interceptor.AbstractInterceptor;
+import org.jboss.mx.interceptor.Interceptor;
+import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.portal.common.mx.JavaBeanModelMBeanBuilder;
import org.jboss.portal.common.util.Tools;
import org.jboss.system.ServiceMBeanSupport;
@@ -35,6 +37,8 @@
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
+import javax.management.ObjectName;
+import javax.management.MBeanServer;
import javax.management.modelmbean.InvalidTargetObjectTypeException;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanOperationInfo;
@@ -44,8 +48,11 @@
import javax.management.modelmbean.ModelMBeanNotificationInfo;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
@@ -77,9 +84,15 @@
// Constructors --------------------------------------------------
/** . */
+ private final boolean replaceProxies;
+
+ /** . */
private final ServiceMixin serviceMixin;
/** . */
+ private final POJOInjector injector;
+
+ /** . */
private final boolean createExists;
/** . */
@@ -118,7 +131,9 @@
ModelMBeanInfo info = JavaBeanModelMBeanBuilder.build(resource.getClass(), pojo
? Object.class : ServiceMBeanSupport.class);
//
- serviceMixin = new ServiceMixin(resource);
+ this.replaceProxies =
"true".equals(System.getProperty("replace.proxies"));
+ this.injector = new POJOInjector();
+ this.serviceMixin = new ServiceMixin(resource);
//
List mmois = Tools.toList(info.getOperations());
@@ -290,6 +305,48 @@
}
});
}
+ else if (replaceProxies)
+ {
+ // Retrieve original dispatcher
+ final Interceptor dispatcher = ctx.getDispatcher();
+
+ //
+ ctx.setDispatcher(new AbstractInterceptor()
+ {
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ if (InvocationContext.OP_SETATTRIBUTE.equals(invocation.getType()))
+ {
+ Object value = invocation.getArgs()[0];
+ if (value != null && Proxy.isProxyClass(value.getClass()))
+ {
+ Object handler = Proxy.getInvocationHandler(value);
+ if (handler instanceof MBeanProxyExt)
+ {
+ MBeanProxyExt pojoHandler = (MBeanProxyExt)handler;
+ POJOInjection injection = new POJOInjection(pojoHandler,
dispatcher, invocation);
+ injector.addInjection(injection);
+ }
+ else
+ {
+ dispatcher.invoke(invocation);
+ }
+ }
+ else
+ {
+ dispatcher.invoke(invocation);
+ }
+
+ //
+ return null;
+ }
+ else
+ {
+ return dispatcher.invoke(invocation);
+ }
+ }
+ });
+ }
}
//
@@ -450,4 +507,36 @@
}
}
}
+
+ // MBeanRegistration implementation
*********************************************************************************
+
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
+ {
+ name = super.preRegister(server, name);
+
+ //
+ server.addNotificationListener(JMXConstants.MBEAN_SERVER_DELEGATE, injector, null,
null);
+
+ //
+ return name;
+ }
+
+ public void postRegister(Boolean done)
+ {
+ super.postRegister(done);
+ }
+
+ public void preDeregister() throws Exception
+ {
+ getServer().removeNotificationListener(JMXConstants.MBEAN_SERVER_DELEGATE,
injector);
+
+ //
+ super.preDeregister();
+ }
+
+ public void postDeregister()
+ {
+ super.postDeregister();
+ }
}
Added: trunk/jems/src/main/org/jboss/portal/jems/as/system/JMXConstants.java
===================================================================
--- trunk/jems/src/main/org/jboss/portal/jems/as/system/JMXConstants.java
(rev 0)
+++ trunk/jems/src/main/org/jboss/portal/jems/as/system/JMXConstants.java 2007-05-17
10:17:48 UTC (rev 7268)
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.jems.as.system;
+
+import org.jboss.mx.util.ObjectNameFactory;
+
+import javax.management.ObjectName;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public interface JMXConstants
+{
+ /** The name of the server delegate. */
+ ObjectName MBEAN_SERVER_DELEGATE =
ObjectNameFactory.create("JMImplementation:type=MBeanServerDelegate");
+}
Added: trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjection.java
===================================================================
--- trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjection.java
(rev 0)
+++ trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjection.java 2007-05-17
10:17:48 UTC (rev 7268)
@@ -0,0 +1,113 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.jems.as.system;
+
+import org.jboss.mx.interceptor.Interceptor;
+import org.jboss.mx.server.Invocation;
+import org.jboss.mx.server.registry.MBeanEntry;
+import org.jboss.mx.util.MBeanProxyExt;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.ReflectionException;
+import javax.management.MalformedObjectNameException;
+import java.lang.reflect.Proxy;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class POJOInjection
+{
+
+ /** . */
+ private final Interceptor dispatcher;
+
+ /** . */
+ private final Invocation invocation;
+
+ /** . */
+ private final MBeanServer server;
+
+ /** . */
+ private final ObjectName pojoName;
+
+ /** . */
+ private boolean resolved;
+
+ public POJOInjection(MBeanProxyExt pojoHandler, Interceptor dispatcher, Invocation
invocation)
+ {
+ this.dispatcher = dispatcher;
+ this.invocation = invocation;
+ this.server = pojoHandler.getMBeanProxyMBeanServer();
+ this.pojoName = pojoHandler.getMBeanProxyObjectName();
+ }
+
+ public ObjectName getPOJOName()
+ {
+ return pojoName;
+ }
+
+ public synchronized void resolve()
+ {
+ if (!resolved)
+ {
+ if (server.isRegistered(pojoName))
+ {
+ try
+ {
+ // Get the mbean entry
+ MBeanEntry entry = (MBeanEntry)server.invoke(new
ObjectName("JMImplementation:type=MBeanRegistry"), "get", new
Object[]{pojoName}, new String[]{ObjectName.class.getName()});
+
+ //
+ if (entry != null)
+ {
+ // Get the managed resource (aka the service)
+ Object pojo = entry.getInvoker().getResource();
+
+ // Replace the proxy by the service
+ invocation.getArgs()[0] = pojo;
+
+ // Dispatch the invocation finally
+ dispatcher.invoke(invocation);
+ }
+
+ //
+ this.resolved = true;
+ }
+ catch (InstanceNotFoundException ignore)
+ {
+ // Not found will resolve later
+ }
+ catch (Throwable e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+}
Added: trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjector.java
===================================================================
--- trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjector.java
(rev 0)
+++ trunk/jems/src/main/org/jboss/portal/jems/as/system/POJOInjector.java 2007-05-17
10:17:48 UTC (rev 7268)
@@ -0,0 +1,74 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.jems.as.system;
+
+import javax.management.NotificationListener;
+import javax.management.Notification;
+import javax.management.MBeanServerNotification;
+import javax.management.ObjectName;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class POJOInjector implements NotificationListener
+{
+
+ /** . */
+ private final Map injections;
+
+ public POJOInjector()
+ {
+ this.injections = new HashMap();
+ }
+
+ public void addInjection(POJOInjection injection)
+ {
+ injections.put(injection.getPOJOName(), injection);
+
+ //
+ injection.resolve();
+ }
+
+ public void handleNotification(Notification notification, Object object)
+ {
+ String type = notification.getType();
+ if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type))
+ {
+ MBeanServerNotification msn = (MBeanServerNotification)notification;
+ ObjectName name = msn.getMBeanName();
+ POJOInjection injection = (POJOInjection)injections.get(name);
+ if (injection != null)
+ {
+ injection.resolve();
+ }
+ }
+ else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type))
+ {
+ MBeanServerNotification msn = (MBeanServerNotification)notification;
+ // ObjectName name = msn.getMBeanName();
+ }
+ }
+}