You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by da...@apache.org on 2003/11/07 18:32:11 UTC
cvs commit: incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx InterfaceCallbackFilter.java InvokeMBean.java MBeanOperationSignature.java MBeanProxyCallback.java MBeanProxyFactory.java AbstractMBeanProxyHandler.java
dain 2003/11/07 09:32:11
Modified: modules/kernel/src/java/org/apache/geronimo/kernel/jmx
MBeanProxyFactory.java
Added: modules/kernel/src/java/org/apache/geronimo/kernel/jmx
InterfaceCallbackFilter.java InvokeMBean.java
MBeanOperationSignature.java
MBeanProxyCallback.java
Removed: modules/kernel/src/java/org/apache/geronimo/kernel/jmx
AbstractMBeanProxyHandler.java
Log:
Converted to use cglib dynamic proxies.
Revision Changes Path
1.2 +66 -20 incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx/MBeanProxyFactory.java
Index: MBeanProxyFactory.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx/MBeanProxyFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MBeanProxyFactory.java 8 Sep 2003 04:38:34 -0000 1.1
+++ MBeanProxyFactory.java 7 Nov 2003 17:32:11 -0000 1.2
@@ -55,22 +55,28 @@
*/
package org.apache.geronimo.kernel.jmx;
-import java.lang.reflect.Proxy;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.SimpleCallbacks;
+import net.sf.cglib.reflect.FastClass;
+
/**
* MBeanProxyFactory creates a dynamic proxy to an MBean by ObjectName.
- * The interface type and object existance is not enforced during construction. Instead, if a method is
- * invoked on the proxy and there is no object registered with the assigned name, an InvocationTargetException
- * is thrown, which contains an InstanceNotFoundException. If an interface method that is not implemented by
- * the MBean is invoked, an InvocationTargetException is thrown, which contains an NoSuchMethodException.
+ * The interface type and object existance are enforced during construction.
*
* @version $Revision$ $Date$
*/
public final class MBeanProxyFactory {
- private MBeanProxyFactory() {
- }
/**
* Creates an MBean proxy using the specified interface to the objectName.
@@ -85,20 +91,60 @@
assert iface.isInterface();
assert server != null;
- ClassLoader cl = iface.getClassLoader();
- return Proxy.newProxyInstance(cl, new Class[]{iface}, new LocalHandler(iface, server, objectName));
- }
-
- private static class LocalHandler extends AbstractMBeanProxyHandler {
- private ObjectName objectName;
-
- public LocalHandler(Class iface, MBeanServer server, ObjectName objectName) {
- super(iface, server);
- this.objectName = objectName;
+ // get the factory
+ Factory factory = Enhancer.create(
+ Object.class,
+ new Class[]{iface},
+ new InterfaceCallbackFilter(),
+ new SimpleCallbacks());
+
+ // build the method table
+ FastClass fastClass = FastClass.create(iface);
+
+ if (objectName.isPattern()) {
+ Set names = server.queryNames(objectName, null);
+ if (names.isEmpty()) {
+ throw new IllegalArgumentException("No names mbeans registered that match object name pattern: " + objectName);
+ }
+ objectName = (ObjectName) names.iterator().next();
+ }
+
+ MBeanInfo info = null;
+ try {
+ info = server.getMBeanInfo(objectName);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Could not get MBeanInfo for target object: " + objectName);
+ }
+
+ MBeanAttributeInfo[] attributeInfos = info.getAttributes();
+ Map attributes = new HashMap(attributeInfos.length);
+ for (int i = 0; i < attributeInfos.length; i++) {
+ MBeanAttributeInfo attributeInfo = attributeInfos[i];
+ attributes.put(attributeInfo.getName(), attributeInfo);
+ }
+
+ MBeanOperationInfo[] operationInfos = info.getOperations();
+ Map operations = new HashMap(operationInfos.length);
+ for (int i = 0; i < operationInfos.length; i++) {
+ MBeanOperationInfo operationInfo = operationInfos[i];
+ operations.put(new MBeanOperationSignature(operationInfo), operationInfo);
}
- public ObjectName getObjectName() {
- return objectName;
+ InvokeMBean[] methodTable = new InvokeMBean[fastClass.getMaxIndex() + 1];
+ Method[] methods = fastClass.getJavaClass().getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ int index = fastClass.getIndex(method.getName(), method.getParameterTypes());
+ if (operations.containsKey(new MBeanOperationSignature(method))) {
+ methodTable[index] = new InvokeMBean(method, false, false);
+ } else if (method.getName().startsWith("get") && attributes.containsKey(method.getName().substring(3))) {
+ methodTable[index] = new InvokeMBean(method, true, true);
+ } else if (method.getName().startsWith("is") && attributes.containsKey(method.getName().substring(2))) {
+ methodTable[index] = new InvokeMBean(method, true, true);
+ } else if (method.getName().startsWith("set") && attributes.containsKey(method.getName().substring(3))) {
+ methodTable[index] = new InvokeMBean(method, true, false);
+ }
}
+ return factory.newInstance(new MBeanProxyCallback(methodTable, server, objectName));
}
}
1.1 incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx/InterfaceCallbackFilter.java
Index: InterfaceCallbackFilter.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.kernel.jmx;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.SimpleFilter;
import net.sf.cglib.proxy.Callbacks;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/11/07 17:32:11 $
*/
public final class InterfaceCallbackFilter extends SimpleFilter {
public InterfaceCallbackFilter() {
super(Callbacks.INTERCEPT);
}
public int accept(Method method) {
if(method.getDeclaringClass() == Object.class) {
return Callbacks.NO_OP;
}
return Callbacks.INTERCEPT;
}
}
1.1 incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx/InvokeMBean.java
Index: InvokeMBean.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.kernel.jmx;
import java.lang.reflect.Method;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeErrorException;
import javax.management.Attribute;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/11/07 17:32:11 $
*/
public final class InvokeMBean {
private final String name;
private final String[] argumentTypes;
private final Class[] declaredExceptions;
private final boolean isAttribute;
private final boolean isGetter;
private final int expectedArguments;
public InvokeMBean(Method method, boolean isAttribute, boolean isGetter) {
name = method.getName();
this.isAttribute = isAttribute;
this.isGetter = isGetter;
this.expectedArguments = method.getParameterTypes().length;
if (isAttribute) {
if (isGetter && (method.getReturnType() == Void.TYPE || method.getParameterTypes().length > 0)) {
throw new IllegalArgumentException("Getter attribute must take no parameters and return a value");
}
if (!isGetter && (method.getReturnType() != Void.TYPE || method.getParameterTypes().length != 1)) {
throw new IllegalArgumentException("Getter attribute must take one parameter and not return a value");
}
}
// conver the parameters to a MBeanServer friendly string array
Class[] parameters = method.getParameterTypes();
argumentTypes = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {
argumentTypes[i] = parameters[i].getName();
}
declaredExceptions = method.getExceptionTypes();
}
public Object invoke(MBeanServer server, ObjectName objectName, Object[] arguments) throws Throwable {
if (arguments.length != expectedArguments) {
throw new IllegalArgumentException("Wrong number of arguments:" +
" expected " + expectedArguments + " but got " + arguments.length);
}
try {
if (isAttribute) {
if (isGetter) {
return server.getAttribute(objectName, name);
} else {
server.setAttribute(objectName, new Attribute(name, arguments[0]));
return null;
}
} else {
return server.invoke(objectName, name, arguments, argumentTypes);
}
} catch (Throwable t) {
Throwable throwable = t;
while (true) {
for (int i = 0; i < declaredExceptions.length; i++) {
Class declaredException = declaredExceptions[i];
if (declaredException.isInstance(throwable)) {
throw throwable;
}
}
// Unwrap the exceptions we understand
if (throwable instanceof MBeanException) {
throwable = (((MBeanException) throwable).getTargetException());
} else if (throwable instanceof ReflectionException) {
throwable = (((ReflectionException) throwable).getTargetException());
} else if (throwable instanceof RuntimeOperationsException) {
throwable = (((RuntimeOperationsException) throwable).getTargetException());
} else if (throwable instanceof RuntimeMBeanException) {
throwable = (((RuntimeMBeanException) throwable).getTargetException());
} else if (throwable instanceof RuntimeErrorException) {
throwable = (((RuntimeErrorException) throwable).getTargetError());
} else {
// don't know how to unwrap this, just throw it
throw throwable;
}
}
}
}
}
1.1 incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx/MBeanOperationSignature.java
Index: MBeanOperationSignature.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.kernel.jmx;
import java.lang.reflect.Method;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
/**
* This is a key class based on a MBean operation name and parameters.
*
* @version $Revision: 1.1 $ $Date: 2003/11/07 17:32:11 $
*/
public final class MBeanOperationSignature {
private final static String[] NO_TYPES = new String[0];
private final String name;
private final String[] argumentTypes;
public MBeanOperationSignature(Method method) {
name = method.getName();
Class[] parameters = method.getParameterTypes();
argumentTypes = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {
argumentTypes[i] = parameters[i].getName();
}
}
public MBeanOperationSignature(MBeanOperationInfo operationInfo) {
name = operationInfo.getName();
MBeanParameterInfo[] parameters = operationInfo.getSignature();
argumentTypes = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {
argumentTypes[i] = parameters[i].getType();
}
}
public MBeanOperationSignature(String name, String[] argumentTypes) {
this.name = name;
if (argumentTypes != null) {
this.argumentTypes = argumentTypes;
} else {
this.argumentTypes = NO_TYPES;
}
}
public boolean equals(Object object) {
if (!(object instanceof MBeanOperationSignature)) {
return false;
}
// match names
MBeanOperationSignature methodKey = (MBeanOperationSignature) object;
if (!methodKey.name.equals(name)) {
return false;
}
// match arg length
int length = methodKey.argumentTypes.length;
if (length != argumentTypes.length) {
return false;
}
// match each arg
for (int i = 0; i < length; i++) {
if (!methodKey.argumentTypes[i].equals(argumentTypes[i])) {
return false;
}
}
return true;
}
public int hashCode() {
int result = 17;
result = 37 * result + name.hashCode();
for (int i = 0; i < argumentTypes.length; i++) {
result = 37 * result + argumentTypes[i].hashCode();
}
return result;
}
public String toString() {
StringBuffer buffer = new StringBuffer(name);
for (int i = 0; i < argumentTypes.length; i++) {
buffer.append(argumentTypes[i]);
}
return buffer.toString();
}
}
1.1 incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/jmx/MBeanProxyCallback.java
Index: MBeanProxyCallback.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.kernel.jmx;
import java.lang.reflect.Method;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* This class handles invocations for MBean proxies. Normally only the getObjectName method is necessary.
*
* @version $Revision: 1.1 $ $Date: 2003/11/07 17:32:11 $
*/
public final class MBeanProxyCallback implements MethodInterceptor {
private final InvokeMBean[] methodTable;
private final MBeanServer server;
private final ObjectName objectName;
public MBeanProxyCallback(InvokeMBean[] methodTable, MBeanServer server, ObjectName objectName) {
this.methodTable = methodTable;
this.server = server;
this.objectName = objectName;
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return methodTable[proxy.getIndex()].invoke(server, objectName, args);
}
}