This patch completes the implementation of a proxy for the MXBean platform server.
Changelog:
2006-12-23 Andrew John Hughes <[EMAIL PROTECTED]>
* gnu/java/lang/management/BeanImpl.java:
(translate(String)): Correct handling of
CompositeData objects.
* java/lang/management/ManagementFactory.java:
(ManagementInvocationHandler.invoke(Object,
Method,Object[])): Handle translation and notifications.
(ManagementInvocationHandler.translate(Object,
Method)): Implement type translation.
* java/lang/management/MemoryUsage.java:
(from(CompositeData)): Fix capitalisation.
* java/lang/management/ThreadInfo.java:
(from(CompositeData)): Likewise.
* javax/management/StandardMBean.java:
(getMBeanInfo()): Add notification handling.
--
Andrew :-)
Escape the Java Trap with GNU Classpath!
http://www.gnu.org/philosophy/java-trap.html
public class gcj extends Freedom implements Java { ... }
Index: gnu/java/lang/management/BeanImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/lang/management/BeanImpl.java,v
retrieving revision 1.11
diff -u -3 -p -u -r1.11 BeanImpl.java
--- gnu/java/lang/management/BeanImpl.java 21 Dec 2006 13:02:51 -0000
1.11
+++ gnu/java/lang/management/BeanImpl.java 23 Dec 2006 12:49:05 -0000
@@ -483,9 +483,9 @@ public class BeanImpl
try
{
c.getMethod("from", new Class[] { CompositeData.class });
- Method[] methods = c.getMethods();
- List names = new ArrayList();
- List types = new ArrayList();
+ Method[] methods = c.getDeclaredMethods();
+ List<String> names = new ArrayList<String>();
+ List<OpenType> types = new ArrayList<OpenType>();
for (int a = 0; a < methods.length; ++a)
{
String name = methods[a].getName();
@@ -495,10 +495,10 @@ public class BeanImpl
types.add(getTypeFromClass(methods[a].getReturnType()));
}
}
- String[] fields = (String[]) names.toArray();
+ String[] fields = names.toArray(new String[names.size()]);
CompositeType ctype = new CompositeType(c.getName(), c.getName(),
fields, fields,
- (OpenType[]) types.toArray());
+ types.toArray(new
OpenType[types.size()]));
return new OpenMBeanParameterInfoSupport("TransParam",
"Translated parameter",
ctype);
Index: java/lang/management/ManagementFactory.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/java/lang/management/ManagementFactory.java,v
retrieving revision 1.18
diff -u -3 -p -u -r1.18 ManagementFactory.java
--- java/lang/management/ManagementFactory.java 19 Dec 2006 00:33:44 -0000
1.18
+++ java/lang/management/ManagementFactory.java 23 Dec 2006 12:49:06 -0000
@@ -56,8 +56,10 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.logging.LogManager;
@@ -70,8 +72,13 @@ import javax.management.MBeanServerFacto
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
/**
* <p>
* Provides access to the system's management beans via a series
@@ -709,15 +716,37 @@ public class ManagementFactory
String name = method.getName();
if (name.equals("toString"))
return "Proxy for " + bean + " using " + conn;
+ if (name.equals("addNotificationListener"))
+ {
+ conn.addNotificationListener(bean,
+ (NotificationListener) args[0],
+ (NotificationFilter) args[1],
+ args[2]);
+ return null;
+ }
+ if (name.equals("getNotificationInfo"))
+ return conn.getMBeanInfo(bean).getNotifications();
+ if (name.equals("removeNotificationListener"))
+ {
+ if (args.length == 1)
+ conn.removeNotificationListener(bean,
+ (NotificationListener)
+ args[0]);
+ else
+ conn.removeNotificationListener(bean,
+ (NotificationListener)
+ args[0],
+ (NotificationFilter)
+ args[1], args[2]);
+ return null;
+ }
String attrib = null;
if (name.startsWith("get"))
attrib = name.substring(3);
else if (name.startsWith("is"))
attrib = name.substring(2);
if (attrib != null)
- {
- return conn.getAttribute(bean, attrib);
- }
+ return translate(conn.getAttribute(bean, attrib), method);
else if (name.startsWith("set"))
{
conn.setAttribute(bean, new Attribute(name.substring(3),
@@ -725,9 +754,64 @@ public class ManagementFactory
return null;
}
else
+ return translate(conn.invoke(bean, name, args, null), method);
+ }
+
+ /**
+ * Translates the returned open data type to the value
+ * required by the interface.
+ *
+ * @param otype the open type returned by the method call.
+ * @param method the method that was called.
+ * @return the equivalent return type required by the interface.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ private final Object translate(Object otype, Method method)
+ throws Throwable
+ {
+ Class<?> returnType = method.getReturnType();
+ if (returnType.isEnum())
{
- return conn.invoke(bean, name, args, null);
- }
+ String ename = (String) otype;
+ Enum[] constants = (Enum[]) returnType.getEnumConstants();
+ for (Enum c : constants)
+ if (c.name().equals(ename))
+ return c;
+ }
+ if (List.class.isAssignableFrom(returnType))
+ {
+ Object[] elems = (Object[]) otype;
+ List l = new ArrayList(elems.length);
+ for (Object elem : elems)
+ l.add(elem);
+ return l;
+ }
+ if (Map.class.isAssignableFrom(returnType))
+ {
+ TabularData data = (TabularData) otype;
+ Map m = new HashMap(data.size());
+ for (Object val : data.values())
+ {
+ CompositeData vals = (CompositeData) val;
+ m.put(vals.get("key"), vals.get("value"));
+ }
+ return m;
+ }
+ try
+ {
+ Method m = returnType.getMethod("from",
+ new Class[]
+ { CompositeData.class });
+ return m.invoke(null, (CompositeData) otype);
+ }
+ catch (NoSuchMethodException e)
+ {
+ /* Ignored; we expect this if this
+ isn't a from(CompositeData) class */
+ }
+ return otype;
}
+
}
}
Index: java/lang/management/MemoryUsage.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/management/MemoryUsage.java,v
retrieving revision 1.3
diff -u -3 -p -u -r1.3 MemoryUsage.java
--- java/lang/management/MemoryUsage.java 9 Jul 2006 20:02:03 -0000
1.3
+++ java/lang/management/MemoryUsage.java 23 Dec 2006 12:49:06 -0000
@@ -180,14 +180,14 @@ public class MemoryUsage
if (data == null)
return null;
CompositeType type = data.getCompositeType();
- ThreadInfo.checkAttribute(type, "init", SimpleType.LONG);
- ThreadInfo.checkAttribute(type, "used", SimpleType.LONG);
- ThreadInfo.checkAttribute(type, "committed", SimpleType.LONG);
- ThreadInfo.checkAttribute(type, "max", SimpleType.LONG);
- return new MemoryUsage(((Long) data.get("init")).longValue(),
- ((Long) data.get("used")).longValue(),
- ((Long) data.get("committed")).longValue(),
- ((Long) data.get("max")).longValue());
+ ThreadInfo.checkAttribute(type, "Init", SimpleType.LONG);
+ ThreadInfo.checkAttribute(type, "Used", SimpleType.LONG);
+ ThreadInfo.checkAttribute(type, "Committed", SimpleType.LONG);
+ ThreadInfo.checkAttribute(type, "Max", SimpleType.LONG);
+ return new MemoryUsage(((Long) data.get("Init")).longValue(),
+ ((Long) data.get("Used")).longValue(),
+ ((Long) data.get("Committed")).longValue(),
+ ((Long) data.get("Max")).longValue());
}
/**
Index: java/lang/management/ThreadInfo.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/management/ThreadInfo.java,v
retrieving revision 1.6
diff -u -3 -p -u -r1.6 ThreadInfo.java
--- java/lang/management/ThreadInfo.java 10 Dec 2006 20:25:44 -0000
1.6
+++ java/lang/management/ThreadInfo.java 23 Dec 2006 12:49:06 -0000
@@ -336,18 +336,18 @@ public class ThreadInfo
if (data == null)
return null;
CompositeType type = data.getCompositeType();
- checkAttribute(type, "threadId", SimpleType.LONG);
- checkAttribute(type, "threadName", SimpleType.STRING);
- checkAttribute(type, "threadState", SimpleType.STRING);
- checkAttribute(type, "suspended", SimpleType.BOOLEAN);
- checkAttribute(type, "inNative", SimpleType.BOOLEAN);
- checkAttribute(type, "blockedCount", SimpleType.LONG);
- checkAttribute(type, "blockedTime", SimpleType.LONG);
- checkAttribute(type, "waitedCount", SimpleType.LONG);
- checkAttribute(type, "waitedTime", SimpleType.LONG);
- checkAttribute(type, "lockName", SimpleType.STRING);
- checkAttribute(type, "lockOwnerId", SimpleType.LONG);
- checkAttribute(type, "lockOwnerName", SimpleType.STRING);
+ checkAttribute(type, "ThreadId", SimpleType.LONG);
+ checkAttribute(type, "ThreadName", SimpleType.STRING);
+ checkAttribute(type, "ThreadState", SimpleType.STRING);
+ checkAttribute(type, "Suspended", SimpleType.BOOLEAN);
+ checkAttribute(type, "InNative", SimpleType.BOOLEAN);
+ checkAttribute(type, "BlockedCount", SimpleType.LONG);
+ checkAttribute(type, "BlockedTime", SimpleType.LONG);
+ checkAttribute(type, "WaitedCount", SimpleType.LONG);
+ checkAttribute(type, "WaitedTime", SimpleType.LONG);
+ checkAttribute(type, "LockName", SimpleType.STRING);
+ checkAttribute(type, "LockOwnerId", SimpleType.LONG);
+ checkAttribute(type, "LockOwnerName", SimpleType.STRING);
try
{
CompositeType seType =
@@ -368,7 +368,7 @@ public class ThreadInfo
SimpleType.STRING, SimpleType.INTEGER,
SimpleType.BOOLEAN
});
- checkAttribute(type, "stackTrace", new ArrayType(1, seType));
+ checkAttribute(type, "StackTrace", new ArrayType(1, seType));
}
catch (OpenDataException e)
{
@@ -376,29 +376,29 @@ public class ThreadInfo
"the composite data type for the " +
"stack trace element.", e);
}
- CompositeData[] dTraces = (CompositeData[]) data.get("stackTrace");
+ CompositeData[] dTraces = (CompositeData[]) data.get("StackTrace");
StackTraceElement[] traces = new StackTraceElement[dTraces.length];
for (int a = 0; a < dTraces.length; ++a)
/* FIXME: We can't use the boolean as there is no available
constructor. */
traces[a] =
- new StackTraceElement((String) dTraces[a].get("className"),
- (String) dTraces[a].get("methodName"),
- (String) dTraces[a].get("fileName"),
+ new StackTraceElement((String) dTraces[a].get("ClassName"),
+ (String) dTraces[a].get("MethodName"),
+ (String) dTraces[a].get("FileName"),
((Integer)
- dTraces[a].get("lineNumber")).intValue());
- return new ThreadInfo(((Long) data.get("threadId")).longValue(),
- (String) data.get("threadName"),
- Thread.State.valueOf((String)
data.get("threadState")),
- ((Long) data.get("blockedCount")).longValue(),
- ((Long) data.get("blockedTime")).longValue(),
- (String) data.get("lockName"),
- ((Long) data.get("lockOwnerId")).longValue(),
- (String) data.get("lockOwnerName"),
- ((Long) data.get("waitedCount")).longValue(),
- ((Long) data.get("waitedTime")).longValue(),
- ((Boolean) data.get("inNative")).booleanValue(),
- ((Boolean) data.get("suspended")).booleanValue(),
+ dTraces[a].get("LineNumber")).intValue());
+ return new ThreadInfo(((Long) data.get("ThreadId")).longValue(),
+ (String) data.get("ThreadName"),
+ Thread.State.valueOf((String)
data.get("ThreadState")),
+ ((Long) data.get("BlockedCount")).longValue(),
+ ((Long) data.get("BlockedTime")).longValue(),
+ (String) data.get("LockName"),
+ ((Long) data.get("LockOwnerId")).longValue(),
+ (String) data.get("LockOwnerName"),
+ ((Long) data.get("WaitedCount")).longValue(),
+ ((Long) data.get("WaitedTime")).longValue(),
+ ((Boolean) data.get("InNative")).booleanValue(),
+ ((Boolean) data.get("Suspended")).booleanValue(),
traces);
}
Index: javax/management/StandardMBean.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/management/StandardMBean.java,v
retrieving revision 1.4
diff -u -3 -p -u -r1.4 StandardMBean.java
--- javax/management/StandardMBean.java 5 Aug 2006 18:08:28 -0000 1.4
+++ javax/management/StandardMBean.java 23 Dec 2006 12:49:07 -0000
@@ -665,7 +665,10 @@ public class StandardMBean
ainfo, cinfo, oinfo, null);
String cname = getClassName(info);
String desc = getDescription(info);
- info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, null);
+ MBeanNotificationInfo[] ninfo = null;
+ if (impl instanceof NotificationBroadcaster)
+ ninfo = ((NotificationBroadcaster) impl).getNotificationInfo();
+ info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, ninfo);
cacheMBeanInfo(info);
return info;
}
signature.asc
Description: Digital signature
