jboynes 2004/06/01 23:49:23
Modified: modules/kernel/src/java/org/apache/geronimo/gbean/jmx
CollectionProxy.java ProxyFactory.java
ProxyMethodInterceptor.java SingleProxy.java
modules/kernel/src/java/org/apache/geronimo/kernel
Kernel.java KernelMBean.java
modules/kernel/src/java/org/apache/geronimo/kernel/jmx
MBeanProxyFactory.java
Added: modules/kernel/src/java/org/apache/geronimo/gbean/jmx
CGLibMethodInterceptor.java CGLibProxyFactory.java
JMXGetAttributeInvoker.java
JMXOperationInvoker.java
JMXSetAttributeInvoker.java
VMMethodInterceptor.java VMProxyFactory.java
Log:
Support proxies based on both CGLib and raw JVM reflection
Revision Changes Path
1.17 +9 -15
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CollectionProxy.java
Index: CollectionProxy.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CollectionProxy.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- CollectionProxy.java 27 May 2004 01:05:59 -0000 1.16
+++ CollectionProxy.java 2 Jun 2004 06:49:23 -0000 1.17
@@ -17,7 +17,6 @@
package org.apache.geronimo.gbean.jmx;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -80,7 +79,7 @@
public CollectionProxy(GBeanMBean gmbean, String name, Class type) {
this.gmbean = gmbean;
this.name = name;
- factory = new ProxyFactory(type);
+ factory = ProxyFactory.newProxyFactory(type);
}
public synchronized void destroy() {
@@ -109,18 +108,13 @@
public synchronized void addTarget(ObjectName target) {
// if this is a new target...
if (!proxies.containsKey(target)) {
- try {
- ProxyMethodInterceptor interceptor = new
ProxyMethodInterceptor(factory.getType());
- interceptor.connect(gmbean.getServer(), target,
proxy.isStopped());
- interceptors.put(target, interceptor);
- Object targetProxy = factory.create(interceptor);
- proxies.put(target, targetProxy);
- if (!stopped) {
- proxy.fireMemberAdddedEvent(targetProxy);
- }
- } catch (InvocationTargetException e) {
- log.info("Could not create optional proxy to mbean:
objectName=" + target);
-
+ ProxyMethodInterceptor interceptor =
factory.getMethodInterceptor();
+ interceptor.connect(gmbean.getServer(), target,
proxy.isStopped());
+ interceptors.put(target, interceptor);
+ Object targetProxy = factory.create(interceptor);
+ proxies.put(target, targetProxy);
+ if (!stopped) {
+ proxy.fireMemberAdddedEvent(targetProxy);
}
}
}
1.6 +21 -24
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyFactory.java
Index: ProxyFactory.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyFactory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ProxyFactory.java 27 May 2004 01:05:59 -0000 1.5
+++ ProxyFactory.java 2 Jun 2004 06:49:23 -0000 1.6
@@ -19,36 +19,33 @@
import java.lang.reflect.InvocationTargetException;
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.MethodInterceptor;
-
/**
* @version $Revision$ $Date$
*/
-public class ProxyFactory {
- private final Class type;
- private final Enhancer enhancer;
+public abstract class ProxyFactory {
+ private static final boolean useCGLib;
- public ProxyFactory(Class type) {
- enhancer = new Enhancer();
- enhancer.setSuperclass(type);
- enhancer.setCallbackType(MethodInterceptor.class);
- enhancer.setUseFactory(false);
- this.type = enhancer.createClass();
+ static {
+ boolean flag = false;
+ try {
+ Class.forName("net.sf.cglib.proxy.Enhancer");
+ flag = true;
+ } catch (Exception e) {
+ }
+ useCGLib = flag;
}
- public Class getType() {
- return type;
+ public static ProxyFactory newProxyFactory(Class type) {
+ if (useCGLib) {
+ return new CGLibProxyFactory(type);
+ } else {
+ return new VMProxyFactory(type);
+ }
}
- public Object create(MethodInterceptor methodInterceptor) throws
InvocationTargetException {
- return create(methodInterceptor, new Class[0], new Object[0]);
- }
+ public abstract ProxyMethodInterceptor getMethodInterceptor();
- public synchronized Object create(MethodInterceptor methodInterceptor,
Class[] types, Object[] arguments) throws InvocationTargetException {
- enhancer.setCallbacks(new Callback[]{methodInterceptor});
- // @todo trap CodeGenerationException indicating missing no-arg ctr
- return enhancer.create(types, arguments);
- }
+ public abstract Object create(ProxyMethodInterceptor methodInterceptor);
+
+ public abstract Object create(ProxyMethodInterceptor methodInterceptor,
Class[] types, Object[] arguments);
}
1.13 +12 -223
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java
Index: ProxyMethodInterceptor.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ProxyMethodInterceptor.java 27 May 2004 01:05:59 -0000 1.12
+++ ProxyMethodInterceptor.java 2 Jun 2004 06:49:23 -0000 1.13
@@ -17,249 +17,38 @@
package org.apache.geronimo.gbean.jmx;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
-import net.sf.cglib.core.Signature;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-import net.sf.cglib.reflect.FastClass;
-import org.apache.geronimo.gbean.GOperationSignature;
-import org.objectweb.asm.Type;
-
/**
* @version $Revision$ $Date$
*/
-public final class ProxyMethodInterceptor implements MethodInterceptor {
- /**
- * Type of the proxy interface
- */
- private final Class proxyType;
-
- /**
- * The object name to which we are connected.
- */
- private ObjectName objectName;
-
- /**
- * GBeanInvokers keyed on the proxy interface method index
- */
- private GBeanInvoker[] gbeanInvokers;
-
- /**
- * Is this proxy currently stoped. If it is invocations will not be
allowed.
- */
- private boolean stopped;
-
- public ProxyMethodInterceptor(Class proxyType) {
- assert proxyType != null;
- this.proxyType = proxyType;
- stopped = true;
- }
-
- public synchronized void connect(MBeanServer server, ObjectName
objectName) {
- this.connect(server, objectName, false);
- }
-
- public synchronized void connect(MBeanServer server, ObjectName
objectName, boolean stopped) {
- assert server != null && objectName != null;
- this.objectName = objectName;
- this.stopped = stopped;
- gbeanInvokers = createGBeanInvokers(server, objectName, proxyType);
- }
-
- public synchronized void disconnect() {
- stopped = true;
- objectName = null;
- gbeanInvokers = null;
- }
-
- public synchronized void start() {
- if (gbeanInvokers == null) {
- throw new IllegalStateException("Proxy is not connected");
- }
- this.stopped = false;
- }
-
- public synchronized void stop() {
- this.stopped = true;
- }
-
- public Object intercept(Object object, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
- GBeanInvoker gbeanInvoker;
-
- int interfaceIndex = proxy.getSuperIndex();
- synchronized (this) {
- if (stopped) {
- throw new IllegalStateException("Proxy is stopped");
- }
- gbeanInvoker = gbeanInvokers[interfaceIndex];
- }
-
- if (gbeanInvoker == null) {
- throw new NoSuchOperationError("No implementation method:
objectName=" + objectName + ", method=" + method);
- }
-
- return gbeanInvoker.invoke(objectName, args);
- }
-
- public GBeanInvoker[] createGBeanInvokers(MBeanServer server, ObjectName
objectName, Class proxyType) {
- GBeanInvoker[] invokers;
- try {
- RawInvoker rawInvoker = (RawInvoker)
server.getAttribute(objectName, GBeanMBean.RAW_INVOKER);
- invokers = createRawGBeanInvokers(rawInvoker, objectName,
proxyType);
- } catch (Exception e) {
- invokers = createJMXGBeanInvokers(server, objectName, proxyType);
- }
-
- // handle equals, hashCode and toString directly here
- try {
- invokers[getSuperIndex(proxyType, proxyType.getMethod("equals",
new Class[]{Object.class}))] = new EqualsInvoke();
- invokers[getSuperIndex(proxyType,
proxyType.getMethod("hashCode", null))] = new HashCodeInvoke();
- invokers[getSuperIndex(proxyType,
proxyType.getMethod("toString", null))] = new
ToStringInvoke(proxyType.getName());
- } catch (Exception e) {
- // this can not happen... all classes must implement equals,
hashCode and toString
- throw new AssertionError(e);
- }
-
- return invokers;
- }
-
- public GBeanInvoker[] createRawGBeanInvokers(RawInvoker rawInvoker,
ObjectName objectName, Class proxyType) {
- Map operations = rawInvoker.getOperationIndex();
- Map attributes = rawInvoker.getAttributeIndex();
-
- // build the method lookup table
- FastClass fastClass = FastClass.create(proxyType);
- GBeanInvoker[] invokers = new GBeanInvoker[fastClass.getMaxIndex() +
1];
- Method[] methods = proxyType.getMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- int interfaceIndex = getSuperIndex(proxyType, method);
- if (interfaceIndex >= 0) {
- invokers[interfaceIndex] = createRawGBeanInvoker(rawInvoker,
method, operations, attributes);
- }
- }
+public interface ProxyMethodInterceptor {
- return invokers;
- }
-
- private GBeanInvoker createRawGBeanInvoker(RawInvoker rawInvoker, Method
method, Map operations, Map attributes) {
- if (operations.containsKey(new GOperationSignature(method))) {
- int methodIndex = ((Integer) operations.get(new
GOperationSignature(method))).intValue();
- return new RawGBeanInvoker(rawInvoker, methodIndex,
GBeanInvoker.OPERATION);
- }
-
- if (method.getName().startsWith("get")) {
- Integer methodIndex = ((Integer)
attributes.get(method.getName().substring(3)));
- if (methodIndex != null) {
- return new RawGBeanInvoker(rawInvoker,
methodIndex.intValue(), GBeanInvoker.GETTER);
- }
- }
-
- if (method.getName().startsWith("is")) {
- Integer methodIndex = ((Integer)
attributes.get(method.getName().substring(2)));
- if (methodIndex != null) {
- return new RawGBeanInvoker(rawInvoker,
methodIndex.intValue(), GBeanInvoker.GETTER);
- }
- }
-
- if (method.getName().startsWith("set")) {
- Integer methodIndex = ((Integer)
attributes.get(method.getName().substring(3)));
- if (methodIndex != null) {
- return new RawGBeanInvoker(rawInvoker,
methodIndex.intValue(), GBeanInvoker.SETTER);
- }
- }
- return null;
- }
-
- public GBeanInvoker[] createJMXGBeanInvokers(MBeanServer server,
ObjectName objectName, Class proxyType) {
- MBeanInfo info = null;
- try {
- info = server.getMBeanInfo(objectName);
- } catch (Exception e) {
- throw new IllegalArgumentException("Could not get MBeanInfo for
target object: " + objectName);
- }
-
- // build attributeName->attributeInfo map
- 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);
- }
+ void connect(MBeanServerConnection server, ObjectName objectName);
- // build operationName->operationInfo map
- 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 GOperationSignature(operationInfo),
operationInfo);
- }
-
- // build the method lookup table
- FastClass fastClass = FastClass.create(proxyType);
- GBeanInvoker[] invokers = new GBeanInvoker[fastClass.getMaxIndex() +
1];
- Method[] methods = proxyType.getMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- int interfaceIndex = getSuperIndex(proxyType, method);
- if (interfaceIndex >= 0) {
- invokers[interfaceIndex] = createJMXGBeanInvoker(server,
method, operations, attributes);
- }
- }
-
- return invokers;
- }
-
- private GBeanInvoker createJMXGBeanInvoker(MBeanServer server, Method
method, Map operations, Map attributes) {
- if (operations.containsKey(new GOperationSignature(method))) {
- return new JMXGBeanInvoker(server, method,
GBeanInvoker.OPERATION);
- }
+ void connect(MBeanServerConnection server, ObjectName objectName,
boolean stopped);
- if (method.getName().startsWith("get") &&
attributes.containsKey(method.getName().substring(3))) {
- return new JMXGBeanInvoker(server, method, GBeanInvoker.GETTER);
- }
+ void disconnect();
- if (method.getName().startsWith("is") &&
attributes.containsKey(method.getName().substring(2))) {
- return new JMXGBeanInvoker(server, method, GBeanInvoker.GETTER);
- }
+ void start();
- if (method.getName().startsWith("set") &&
attributes.containsKey(method.getName().substring(3))) {
- return new JMXGBeanInvoker(server, method, GBeanInvoker.SETTER);
- }
- return null;
- }
-
- private static int getSuperIndex(Class proxyType, Method method) {
- Signature signature = new Signature(method.getName(),
Type.getReturnType(method), Type.getArgumentTypes(method));
- MethodProxy methodProxy = MethodProxy.find(proxyType, signature);
- if (methodProxy != null) {
- return methodProxy.getSuperIndex();
- }
- return -1;
- }
+ void stop();
- private static final class HashCodeInvoke implements GBeanInvoker {
+ static final class HashCodeInvoke implements GBeanInvoker {
public Object invoke(ObjectName objectName, Object[] arguments)
throws Throwable {
return new Integer(objectName.hashCode());
}
}
- private static final class EqualsInvoke implements GBeanInvoker {
+ static final class EqualsInvoke implements GBeanInvoker {
public Object invoke(ObjectName objectName, Object[] arguments)
throws Throwable {
// todo this is broken.. we need a way to extract the object
name from the other proxy
- return new Boolean(objectName.equals(arguments[0]));
+ return Boolean.valueOf(objectName.equals(arguments[0]));
}
}
- private static final class ToStringInvoke implements GBeanInvoker {
+ static final class ToStringInvoke implements GBeanInvoker {
private final String interfaceName;
public ToStringInvoke(String interfaceName) {
1.12 +3 -3
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/SingleProxy.java
Index: SingleProxy.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/SingleProxy.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- SingleProxy.java 27 May 2004 01:05:59 -0000 1.11
+++ SingleProxy.java 2 Jun 2004 06:49:23 -0000 1.12
@@ -73,8 +73,8 @@
this.gmbean = gmbean;
this.name = name;
this.patterns = patterns;
- ProxyFactory factory = new ProxyFactory(type);
- methodInterceptor = new ProxyMethodInterceptor(factory.getType());
+ ProxyFactory factory = ProxyFactory.newProxyFactory(type);
+ methodInterceptor = factory.getMethodInterceptor();
proxy = factory.create(methodInterceptor);
}
1.1
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java
Index: CGLibMethodInterceptor.java
===================================================================
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import org.apache.geronimo.gbean.GOperationSignature;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.reflect.FastClass;
import org.objectweb.asm.Type;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public class CGLibMethodInterceptor implements ProxyMethodInterceptor,
MethodInterceptor {
/**
* Type of the proxy interface
*/
private final Class proxyType;
/**
* The object name to which we are connected.
*/
private ObjectName objectName;
/**
* GBeanInvokers keyed on the proxy interface method index
*/
private GBeanInvoker[] gbeanInvokers;
/**
* Is this proxy currently stopped. If it is invocations will not be
allowed.
*/
protected boolean stopped;
public CGLibMethodInterceptor(Class proxyType) {
this.proxyType = proxyType;
stopped = true;
}
public synchronized void connect(MBeanServerConnection server, ObjectName
objectName) {
this.connect(server, objectName, false);
}
public synchronized void connect(MBeanServerConnection server, ObjectName
objectName, boolean stopped) {
assert server != null && objectName != null;
this.objectName = objectName;
this.stopped = stopped;
gbeanInvokers = createGBeanInvokers(server, objectName);
}
public synchronized void disconnect() {
stopped = true;
objectName = null;
gbeanInvokers = null;
}
public synchronized void start() {
if (gbeanInvokers == null) {
throw new IllegalStateException("Proxy is not connected");
}
this.stopped = false;
}
public synchronized void stop() {
this.stopped = true;
}
public Object intercept(Object object, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
GBeanInvoker gbeanInvoker;
int interfaceIndex = proxy.getSuperIndex();
synchronized (this) {
if (stopped) {
throw new IllegalStateException("Proxy is stopped");
}
gbeanInvoker = gbeanInvokers[interfaceIndex];
}
if (gbeanInvoker == null) {
throw new NoSuchOperationError("No implementation method:
objectName=" + objectName + ", method=" + method);
}
return gbeanInvoker.invoke(objectName, args);
}
private GBeanInvoker[] createGBeanInvokers(MBeanServerConnection server,
ObjectName objectName) {
GBeanInvoker[] invokers;
try {
RawInvoker rawInvoker = (RawInvoker)
server.getAttribute(objectName, GBeanMBean.RAW_INVOKER);
invokers = createRawGBeanInvokers(rawInvoker, proxyType);
} catch (Exception e) {
invokers = createJMXGBeanInvokers(server, objectName, proxyType);
}
// handle equals, hashCode and toString directly here
try {
invokers[getSuperIndex(proxyType, proxyType.getMethod("equals",
new Class[]{Object.class}))] = new EqualsInvoke();
invokers[getSuperIndex(proxyType, proxyType.getMethod("hashCode",
null))] = new HashCodeInvoke();
invokers[getSuperIndex(proxyType, proxyType.getMethod("toString",
null))] = new ToStringInvoke(proxyType.getName());
} catch (Exception e) {
// this can not happen... all classes must implement equals,
hashCode and toString
throw new AssertionError(e);
}
return invokers;
}
private GBeanInvoker[] createRawGBeanInvokers(RawInvoker rawInvoker,
Class proxyType) {
Map operations = rawInvoker.getOperationIndex();
Map attributes = rawInvoker.getAttributeIndex();
// build the method lookup table
FastClass fastClass = FastClass.create(proxyType);
GBeanInvoker[] invokers = new GBeanInvoker[fastClass.getMaxIndex() +
1];
Method[] methods = proxyType.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
int interfaceIndex = getSuperIndex(proxyType, method);
if (interfaceIndex >= 0) {
invokers[interfaceIndex] = createRawGBeanInvoker(rawInvoker,
method, operations, attributes);
}
}
return invokers;
}
private GBeanInvoker createRawGBeanInvoker(RawInvoker rawInvoker, Method
method, Map operations, Map attributes) {
if (operations.containsKey(new GOperationSignature(method))) {
int methodIndex = ((Integer) operations.get(new
GOperationSignature(method))).intValue();
return new RawGBeanInvoker(rawInvoker, methodIndex,
GBeanInvoker.OPERATION);
}
if (method.getName().startsWith("get")) {
Integer methodIndex = ((Integer)
attributes.get(method.getName().substring(3)));
if (methodIndex != null) {
return new RawGBeanInvoker(rawInvoker,
methodIndex.intValue(), GBeanInvoker.GETTER);
}
}
if (method.getName().startsWith("is")) {
Integer methodIndex = ((Integer)
attributes.get(method.getName().substring(2)));
if (methodIndex != null) {
return new RawGBeanInvoker(rawInvoker,
methodIndex.intValue(), GBeanInvoker.GETTER);
}
}
if (method.getName().startsWith("set")) {
Integer methodIndex = ((Integer)
attributes.get(method.getName().substring(3)));
if (methodIndex != null) {
return new RawGBeanInvoker(rawInvoker,
methodIndex.intValue(), GBeanInvoker.SETTER);
}
}
return null;
}
private GBeanInvoker[] createJMXGBeanInvokers(MBeanServerConnection
server, ObjectName objectName, Class proxyType) {
MBeanInfo info;
try {
info = server.getMBeanInfo(objectName);
} catch (Exception e) {
throw new IllegalArgumentException("Could not get MBeanInfo for
target object: " + objectName);
}
// build attributeName->attributeInfo map
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);
}
// build operationName->operationInfo map
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 GOperationSignature(operationInfo),
operationInfo);
}
// build the method lookup table
FastClass fastClass = FastClass.create(proxyType);
GBeanInvoker[] invokers = new GBeanInvoker[fastClass.getMaxIndex() +
1];
Method[] methods = proxyType.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
int interfaceIndex = getSuperIndex(proxyType, method);
if (interfaceIndex >= 0) {
invokers[interfaceIndex] = createJMXGBeanInvoker(server,
method, operations, attributes);
}
}
return invokers;
}
private GBeanInvoker createJMXGBeanInvoker(MBeanServerConnection server,
Method method, Map operations, Map attributes) {
if (operations.containsKey(new GOperationSignature(method))) {
return new JMXOperationInvoker(server, method);
}
String name = method.getName();
if (name.startsWith("get")) {
if (attributes.containsKey(name.substring(3))) {
return new JMXGetAttributeInvoker(server, method);
}
} else if (name.startsWith("is")) {
if (attributes.containsKey(name.substring(2))) {
return new JMXGetAttributeInvoker(server, method);
}
} else if (name.startsWith("set")) {
if (attributes.containsKey(name.substring(3))) {
return new JMXSetAttributeInvoker(server, method);
}
}
return null;
}
private static int getSuperIndex(Class proxyType, Method method) {
Signature signature = new Signature(method.getName(),
Type.getReturnType(method), Type.getArgumentTypes(method));
MethodProxy methodProxy = MethodProxy.find(proxyType, signature);
if (methodProxy != null) {
return methodProxy.getSuperIndex();
}
return -1;
}
}
1.1
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java
Index: CGLibProxyFactory.java
===================================================================
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public class CGLibProxyFactory extends ProxyFactory {
private final Class type;
private final Enhancer enhancer;
public CGLibProxyFactory(Class type) {
enhancer = new Enhancer();
enhancer.setSuperclass(type);
enhancer.setCallbackType(MethodInterceptor.class);
enhancer.setUseFactory(false);
this.type = enhancer.createClass();
}
public ProxyMethodInterceptor getMethodInterceptor() {
return new CGLibMethodInterceptor(type);
}
public Object create(ProxyMethodInterceptor methodInterceptor) {
return create(methodInterceptor, new Class[0], new Object[0]);
}
public synchronized Object create(ProxyMethodInterceptor
methodInterceptor, Class[] types, Object[] arguments) {
enhancer.setCallbacks(new
Callback[]{(CGLibMethodInterceptor)methodInterceptor});
// @todo trap CodeGenerationException indicating missing no-arg ctr
return enhancer.create(types, arguments);
}
}
1.1
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/JMXGetAttributeInvoker.java
Index: JMXGetAttributeInvoker.java
===================================================================
/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.Method;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
/**
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public final class JMXGetAttributeInvoker implements GBeanInvoker {
private final MBeanServerConnection server;
private final String name;
private final Class[] declaredExceptions;
public JMXGetAttributeInvoker(MBeanServerConnection server, Method
method) {
this.server = server;
if (method.getName().startsWith("is")) {
name = method.getName().substring(2);
} else {
name = method.getName().substring(3);
}
declaredExceptions = method.getExceptionTypes();
}
public Object invoke(ObjectName objectName, Object[] arguments) throws
Throwable {
try {
return server.getAttribute(objectName, name);
} catch (Throwable t) {
// todo do we need all this?
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/gbean/jmx/JMXOperationInvoker.java
Index: JMXOperationInvoker.java
===================================================================
/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.Method;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
/**
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public final class JMXOperationInvoker implements GBeanInvoker {
private final MBeanServerConnection server;
private final String name;
private final String[] argumentTypes;
private final Class[] declaredExceptions;
public JMXOperationInvoker(MBeanServerConnection server, Method method) {
this.server = server;
name = method.getName();
// convert 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(ObjectName objectName, Object[] arguments) throws
Throwable {
try {
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/gbean/jmx/JMXSetAttributeInvoker.java
Index: JMXSetAttributeInvoker.java
===================================================================
/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.Method;
import javax.management.Attribute;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
/**
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public final class JMXSetAttributeInvoker implements GBeanInvoker {
private final MBeanServerConnection server;
private final String name;
private final Class[] declaredExceptions;
public JMXSetAttributeInvoker(MBeanServerConnection server, Method
method) {
this.server = server;
name = method.getName().substring(3);
declaredExceptions = method.getExceptionTypes();
}
public Object invoke(ObjectName objectName, Object[] arguments) throws
Throwable {
try {
server.setAttribute(objectName, new Attribute(name,
arguments[0]));
return null;
} catch (Throwable t) {
// todo do we need all this?
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/gbean/jmx/VMMethodInterceptor.java
Index: VMMethodInterceptor.java
===================================================================
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import org.apache.geronimo.gbean.GOperationSignature;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public class VMMethodInterceptor implements ProxyMethodInterceptor,
InvocationHandler {
private final Class proxyType;
private ObjectName objectName;
private boolean stopped;
private Map gbeanInvokers;
public VMMethodInterceptor(Class proxyType) {
this.proxyType = proxyType;
}
public void connect(MBeanServerConnection server, ObjectName objectName) {
connect(server, objectName, false);
}
public void connect(MBeanServerConnection server, ObjectName objectName,
boolean stopped) {
assert server != null && objectName != null;
this.objectName = objectName;
this.stopped = stopped;
gbeanInvokers = createGBeanInvokers(server, objectName);
}
public void disconnect() {
stopped = true;
objectName = null;
gbeanInvokers = null;
}
public void start() {
if (gbeanInvokers == null) {
throw new IllegalStateException("Proxy is not connected");
}
this.stopped = false;
}
public void stop() {
this.stopped = true;
}
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
GBeanInvoker gbeanInvoker;
synchronized (this) {
if (stopped) {
throw new IllegalStateException("Proxy is stopped");
}
gbeanInvoker = (GBeanInvoker) gbeanInvokers.get(method);
}
if (gbeanInvoker == null) {
throw new NoSuchOperationError("No implementation method:
objectName=" + objectName + ", method=" + method);
}
return gbeanInvoker.invoke(objectName, args);
}
private Map createGBeanInvokers(MBeanServerConnection server, ObjectName
objectName) {
Map invokers = createJMXGBeanInvokers(server, objectName, proxyType);
// handle equals, hashCode and toString directly here
try {
invokers.put(Object.class.getMethod("equals", new
Class[]{Object.class}), new EqualsInvoke());
invokers.put(Object.class.getMethod("hashCode", null), new
HashCodeInvoke());
invokers.put(Object.class.getMethod("toString", null), new
ToStringInvoke(proxyType.getName()));
} catch (Exception e) {
// this can not happen... all classes must implement equals,
hashCode and toString
throw new AssertionError(e);
}
return invokers;
}
private Map createJMXGBeanInvokers(MBeanServerConnection server,
ObjectName objectName, Class proxyType) {
MBeanInfo info;
try {
info = server.getMBeanInfo(objectName);
} catch (Exception e) {
throw new IllegalArgumentException("Could not get MBeanInfo for
target object: " + objectName);
}
// build attributeName->attributeInfo map
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);
}
// build operationName->operationInfo map
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 GOperationSignature(operationInfo),
operationInfo);
}
// build the method lookup table
Method[] methods = proxyType.getMethods();
Map invokers = new HashMap(methods.length);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
invokers.put(method, createJMXGBeanInvoker(server, method,
operations, attributes));
}
return invokers;
}
private GBeanInvoker createJMXGBeanInvoker(MBeanServerConnection server,
Method method, Map operations, Map attributes) {
if (operations.containsKey(new GOperationSignature(method))) {
return new JMXOperationInvoker(server, method);
}
String name = method.getName();
if (name.startsWith("get")) {
if (attributes.containsKey(name.substring(3))) {
return new JMXGetAttributeInvoker(server, method);
}
} else if (name.startsWith("is")) {
if (attributes.containsKey(name.substring(2))) {
return new JMXGetAttributeInvoker(server, method);
}
} else if (name.startsWith("set")) {
if (attributes.containsKey(name.substring(3))) {
return new JMXSetAttributeInvoker(server, method);
}
}
return null;
}
}
1.1
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMProxyFactory.java
Index: VMProxyFactory.java
===================================================================
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.gbean.jmx;
import java.lang.reflect.InvocationTargetException;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2004/06/02 06:49:23 $
*/
public class VMProxyFactory extends ProxyFactory {
private final Class proxyType;
public VMProxyFactory(Class type) {
if (type.isInterface() == false) {
throw new IllegalArgumentException("VMProxyFactory can only
implement interfaces");
}
this.proxyType = type;
}
public ProxyMethodInterceptor getMethodInterceptor() {
return new VMMethodInterceptor(proxyType);
}
public Object create(ProxyMethodInterceptor methodInterceptor) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = this.getClass().getClassLoader();
}
return java.lang.reflect.Proxy.newProxyInstance(cl, new
Class[]{proxyType}, (VMMethodInterceptor)methodInterceptor);
}
public Object create(ProxyMethodInterceptor methodInterceptor, Class[]
types, Object[] arguments) {
if (types == null || types.length == 0) {
return create(methodInterceptor);
} else {
throw new IllegalArgumentException("VMProxyFactory cannot take
constructor args");
}
}
}
1.29 +5 -6
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java
Index: Kernel.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- Kernel.java 1 Jun 2004 18:27:02 -0000 1.28
+++ Kernel.java 2 Jun 2004 06:49:23 -0000 1.29
@@ -17,15 +17,14 @@
package org.apache.geronimo.kernel;
-import java.io.Serializable;
import java.io.IOException;
+import java.io.Serializable;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
+import java.net.URI;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
-import java.util.List;
-import java.net.URI;
import javax.management.Attribute;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
@@ -34,18 +33,18 @@
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;
-import javax.management.MalformedObjectNameException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.jmx.DependencyService;
import org.apache.geronimo.gbean.jmx.GBeanMBean;
+import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.config.ConfigurationManagerImpl;
import org.apache.geronimo.kernel.config.InvalidConfigException;
-import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.config.NoSuchConfigException;
import org.apache.geronimo.kernel.jmx.JMXUtil;
1.10 +2 -3
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/KernelMBean.java
Index: KernelMBean.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/KernelMBean.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- KernelMBean.java 1 Jun 2004 18:27:02 -0000 1.9
+++ KernelMBean.java 2 Jun 2004 06:49:23 -0000 1.10
@@ -17,9 +17,8 @@
package org.apache.geronimo.kernel;
-import java.net.URI;
import java.io.IOException;
-import java.util.List;
+import java.net.URI;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
1.10 +8 -5
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.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- MBeanProxyFactory.java 8 Apr 2004 05:22:15 -0000 1.9
+++ MBeanProxyFactory.java 2 Jun 2004 06:49:23 -0000 1.10
@@ -18,7 +18,7 @@
package org.apache.geronimo.kernel.jmx;
import java.util.Set;
-import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import org.apache.geronimo.gbean.jmx.ProxyFactory;
@@ -40,20 +40,23 @@
* @param objectName the objectName of the MBean to proxy
* @return the new MBean proxy, which implemnts the specified interface
*/
- public static Object getProxy(Class type, MBeanServer server, ObjectName
objectName) throws Exception {
+ public static Object getProxy(Class type, MBeanServerConnection server,
ObjectName objectName) {
assert type != null;
assert server != null;
if (objectName.isPattern()) {
+ throw new UnsupportedOperationException();
+/*
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();
+*/
}
- ProxyFactory factory = new ProxyFactory(type);
- ProxyMethodInterceptor methodInterceptor = new
ProxyMethodInterceptor(factory.getType());
+ ProxyFactory factory = ProxyFactory.newProxyFactory(type);
+ ProxyMethodInterceptor methodInterceptor =
factory.getMethodInterceptor();
methodInterceptor.connect(server, objectName);
return factory.create(methodInterceptor);
}