6747983: jmx namespace: unspecified self-link detection logic
Reviewed-by: emcmanus
--- a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java Fri Sep 12 17:58:15 2008 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java Fri Sep 12 19:06:38 2008 +0200
@@ -25,22 +25,15 @@
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
-import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
-import java.util.UUID;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.JMXNamespace;
import javax.management.namespace.JMXNamespacePermission;
@@ -54,8 +47,6 @@
*/
public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
- private static final Logger PROBE_LOG = Logger.getLogger(
- JmxProperties.NAMESPACE_LOGGER+".probe");
// The target name space in which the NamepsaceHandler is mounted.
private final String targetNs;
@@ -65,21 +56,6 @@
private final ObjectNameRouter proc;
/**
- * Internal hack. The JMXRemoteNamespace can be closed and reconnected.
- * Each time the JMXRemoteNamespace connects, a probe should be sent
- * to detect cycle. The MBeanServer exposed by JMXRemoteNamespace thus
- * implements the DynamicProbe interface, which makes it possible for
- * this handler to know that it should send a new probe.
- *
- * XXX: TODO this probe thing is way too complex and fragile.
- * This *must* go away or be replaced by something simpler.
- * ideas are welcomed.
- **/
- public static interface DynamicProbe {
- public boolean isProbeRequested();
- }
-
- /**
* Creates a new instance of NamespaceInterceptor
*/
public NamespaceInterceptor(
@@ -100,164 +76,6 @@
", namespace="+this.targetNs+")";
}
- /*
- * XXX: TODO this probe thing is way too complex and fragile.
- * This *must* go away or be replaced by something simpler.
- * ideas are welcomed.
- */
- private volatile boolean probed = false;
- private volatile ObjectName probe;
-
- // Query Pattern that we will send through the source server in order
- // to detect self-linking namespaces.
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- final ObjectName makeProbePattern(ObjectName probe)
- throws MalformedObjectNameException {
-
- // we could probably link the probe pattern with the probe - e.g.
- // using the UUID as key in the pattern - but is it worth it? it
- // also has some side effects on the context namespace - because
- // such a probe may get rejected by the jmx.context// namespace.
- //
- // The trick here is to devise a pattern that is not likely to
- // be blocked by intermediate levels. Querying for all namespace
- // handlers in the source (or source namespace) is more likely to
- // achieve this goal.
- //
- return ObjectName.getInstance("*" +
- JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- }
-
- // tell whether the name pattern corresponds to what might have been
- // sent as a probe.
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- final boolean isProbePattern(ObjectName name) {
- final ObjectName p = probe;
- if (p == null) return false;
- try {
- return String.valueOf(name).endsWith(targetNs+
- JMXNamespaces.NAMESPACE_SEPARATOR + "*" +
- JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- } catch (RuntimeException x) {
- // should not happen.
- PROBE_LOG.finest("Ignoring unexpected exception in self link detection: "+
- x);
- return false;
- }
- }
-
- // The first time a request reaches this NamespaceInterceptor, the
- // interceptor will send a probe to detect whether the underlying
- // JMXNamespace links to itslef.
- //
- // One way to create such self-linking namespace would be for instance
- // to create a JMXNamespace whose getSourceServer() method would return:
- // JMXNamespaces.narrowToNamespace(getMBeanServer(),
- // getObjectName().getDomain())
- //
- // If such an MBeanServer is returned, then any call to that MBeanServer
- // will trigger an infinite loop.
- // There can be even trickier configurations if remote connections are
- // involved.
- //
- // In order to prevent this from happening, the NamespaceInterceptor will
- // send a probe, in an attempt to detect whether it will receive it at
- // the other end. If the probe is received, an exception will be thrown
- // in order to break the recursion. The probe is only sent once - when
- // the first request to the namespace occurs. The DynamicProbe interface
- // can also be used by a Sun JMXNamespace implementation to request the
- // emission of a probe at any time (see JMXRemoteNamespace
- // implementation).
- //
- // Probes work this way: the NamespaceInterceptor sets a flag and sends
- // a queryNames() request. If a queryNames() request comes in when the flag
- // is on, then it deduces that there is a self-linking loop - and instead
- // of calling queryNames() on the source MBeanServer of the JMXNamespace
- // handler (which would cause the loop to go on) it breaks the recursion
- // by returning the probe ObjectName.
- // If the NamespaceInterceptor receives the probe ObjectName as result of
- // its original sendProbe() request it knows that it has been looping
- // back on itslef and throws an IOException...
- //
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- //
- final void sendProbe(MBeanServerConnection msc)
- throws IOException {
- try {
- PROBE_LOG.fine("Sending probe");
-
- // This is just to prevent any other thread to modify
- // the probe while the detection cycle is in progress.
- //
- final ObjectName probePattern;
- // we don't want to synchronize on this - we use targetNs
- // because it's non null and final.
- synchronized (targetNs) {
- probed = false;
- if (probe != null) {
- throw new IOException("concurent connection in progress");
- }
- final String uuid = UUID.randomUUID().toString();
- final String endprobe =
- JMXNamespaces.NAMESPACE_SEPARATOR + uuid +
- ":type=Probe,key="+uuid;
- final ObjectName newprobe =
- ObjectName.getInstance(endprobe);
- probePattern = makeProbePattern(newprobe);
- probe = newprobe;
- }
-
- try {
- PROBE_LOG.finer("Probe query: "+probePattern+" expecting: "+probe);
- final Set<ObjectName> res = msc.queryNames(probePattern, null);
- final ObjectName expected = probe;
- PROBE_LOG.finer("Probe res: "+res);
- if (res.contains(expected)) {
- throw new IOException("namespace " +
- targetNs + " is linking to itself: " +
- "cycle detected by probe");
- }
- } catch (SecurityException x) {
- PROBE_LOG.finer("Can't check for cycles: " + x);
- // can't do anything....
- } catch (RuntimeException x) {
- PROBE_LOG.finer("Exception raised by queryNames: " + x);
- throw x;
- } finally {
- probe = null;
- }
- } catch (MalformedObjectNameException x) {
- final IOException io =
- new IOException("invalid name space: probe failed");
- io.initCause(x);
- throw io;
- }
- PROBE_LOG.fine("Probe returned - no cycles");
- probed = true;
- }
-
- // allows a Sun implementation JMX Namespace, such as the
- // JMXRemoteNamespace, to control when a probe should be sent.
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- private boolean isProbeRequested(Object o) {
- if (o instanceof DynamicProbe)
- return ((DynamicProbe)o).isProbeRequested();
- return false;
- }
-
/**
* This method will send a probe to detect self-linking name spaces.
* A self linking namespace is a namespace that links back directly
@@ -277,29 +95,9 @@
* (see JMXRemoteNamespace implementation).
*/
private MBeanServer connection() {
- try {
- final MBeanServer c = super.source();
- if (probe != null) // should not happen
- throw new RuntimeException("connection is being probed");
-
- if (probed == false || isProbeRequested(c)) {
- try {
- // Should not happen if class well behaved.
- // Never probed. Force it.
- //System.err.println("sending probe for " +
- // "target="+targetNs+", source="+srcNs);
- sendProbe(c);
- } catch (IOException io) {
- throw new RuntimeException(io.getMessage(), io);
- }
- }
-
- if (c != null) {
- return c;
- }
- } catch (RuntimeException x) {
- throw x;
- }
+ final MBeanServer c = super.source();
+ if (c != null) return c;
+ // should not come here
throw new NullPointerException("getMBeanServerConnection");
}
@@ -315,24 +113,6 @@
return super.source();
}
- /**
- * Calls {@link MBeanServerConnection#queryNames queryNames}
- * on the underlying
- * {@link #getMBeanServerConnection MBeanServerConnection}.
- **/
- @Override
- public final Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- PROBE_LOG.finer("probe is: "+probe+" pattern is: "+name);
- if (probe != null && isProbePattern(name)) {
- PROBE_LOG.finer("Return probe: "+probe);
- return Collections.singleton(probe);
- }
- return super.queryNames(name, query);
- }
-
@Override
protected ObjectName toSource(ObjectName targetName)
throws MalformedObjectNameException {
--- a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java Fri Sep 12 17:58:15 2008 +0200
+++ b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java Fri Sep 12 19:06:38 2008 +0200
@@ -28,11 +28,9 @@
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.namespace.JMXNamespaceUtils;
-import com.sun.jmx.namespace.NamespaceInterceptor.DynamicProbe;
import com.sun.jmx.remote.util.EnvHelp;
import java.io.IOException;
-import java.security.AccessControlException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@@ -44,9 +42,7 @@
import javax.management.InstanceNotFoundException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanPermission;
import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationEmitter;
@@ -118,9 +114,6 @@
*/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
- private static final Logger PROBE_LOG = Logger.getLogger(
- JmxProperties.NAMESPACE_LOGGER_NAME+".probe");
-
// This connection listener is used to listen for connection events from
// the underlying JMXConnector. It is used in particular to maintain the
@@ -153,8 +146,7 @@
// because the one that is actually used is the one supplied by the
// override of getMBeanServerConnection().
private static class JMXRemoteNamespaceDelegate
- extends MBeanServerConnectionWrapper
- implements DynamicProbe {
+ extends MBeanServerConnectionWrapper {
private volatile JMXRemoteNamespace parent=null;
JMXRemoteNamespaceDelegate() {
@@ -180,9 +172,6 @@
}
- public boolean isProbeRequested() {
- return this.parent.isProbeRequested();
- }
}
private static final MBeanNotificationInfo connectNotification =
@@ -201,7 +190,6 @@
private volatile MBeanServerConnection server = null;
private volatile JMXConnector conn = null;
private volatile ClassLoader defaultClassLoader = null;
- private volatile boolean probed;
/**
* Creates a new instance of {@code JMXRemoteNamespace}.
@@ -241,9 +229,6 @@
// handles (dis)connection events
this.listener = new ConnectionListener();
-
- // XXX TODO: remove the probe, or simplify it.
- this.probed = false;
}
/**
@@ -274,10 +259,6 @@
return optionsMap;
}
- boolean isProbeRequested() {
- return probed==false;
- }
-
public void addNotificationListener(NotificationListener listener,
NotificationFilter filter, Object handback) {
broadcaster.addNotificationListener(listener, filter, handback);
@@ -603,26 +584,7 @@
}
public void connect() throws IOException {
- if (conn != null) {
- try {
- // This is much too fragile. It must go away!
- PROBE_LOG.finest("Probing again...");
- triggerProbe(getMBeanServerConnection());
- } catch(Exception x) {
- close();
- Throwable cause = x;
- // if the cause is a security exception - rethrows it...
- while (cause != null) {
- if (cause instanceof SecurityException)
- throw (SecurityException) cause;
- cause = cause.getCause();
- }
- throw new IOException("connection failed: cycle?",x);
- }
- }
LOG.fine("connecting...");
- // TODO remove these traces
- // System.err.println(getInitParameter()+" connecting");
final Map<String,Object> env =
new HashMap<String,Object>(getEnvMap());
try {
@@ -652,79 +614,9 @@
throw x;
}
-
- // XXX Revisit here
- // Note from the author: This business of switching connection is
- // incredibly complex. Isn't there any means to simplify it?
- //
switchConnection(conn,aconn,msc);
- try {
- triggerProbe(msc);
- } catch(Exception x) {
- close();
- Throwable cause = x;
- // if the cause is a security exception - rethrows it...
- while (cause != null) {
- if (cause instanceof SecurityException)
- throw (SecurityException) cause;
- cause = cause.getCause();
- }
- throw new IOException("connection failed: cycle?",x);
- }
- LOG.fine("connected.");
- }
- // If this is a self-linking namespace, this method should trigger
- // the emission of a probe in the wrapping NamespaceInterceptor.
- // The first call to source() in the wrapping NamespaceInterceptor
- // causes the emission of the probe.
- //
- // Note: the MBeanServer returned by getSourceServer
- // (our private JMXRemoteNamespaceDelegate inner class)
- // implements a sun private interface (DynamicProbe) which is
- // used by the NamespaceInterceptor to determine whether it should
- // send a probe or not.
- // We needed this interface here because the NamespaceInterceptor
- // has otherwise no means to knows that this object has just
- // connected, and that a new probe should be sent.
- //
- // Probes work this way: the NamespaceInterceptor sets a flag and sends
- // a queryNames() request. If a queryNames() request comes in when the flag
- // is on, then it deduces that there is a self-linking loop - and instead
- // of calling queryNames() on the JMXNamespace (which would cause the
- // loop to go on) it breaks the recursion by returning the probe ObjectName.
- // If the NamespaceInterceptor receives the probe ObjectName as result of
- // its original queryNames() it knows that it has been looping back on
- // itslef and throws an Exception - which will be raised through this
- // method, thus preventing the connection to be established...
- //
- // More info in the com.sun.jmx.namespace.NamespaceInterceptor class
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- //
- private void triggerProbe(final MBeanServerConnection msc)
- throws MalformedObjectNameException, IOException {
- // Query Pattern that we will send through the source server in order
- // to detect self-linking namespaces.
- //
- //
- final ObjectName pattern;
- pattern = ObjectName.getInstance("*" +
- JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- probed = false;
- try {
- msc.queryNames(pattern, null);
- probed = true;
- } catch (AccessControlException x) {
- // if we have an MBeanPermission missing then do nothing...
- if (!(x.getPermission() instanceof MBeanPermission))
- throw x;
- PROBE_LOG.finer("Can't check for cycles: " + x);
- probed = false; // no need to do it again...
- }
+ LOG.fine("connected.");
}
public void close() throws IOException {
--- a/jdk/test/javax/management/namespace/JMXNamespaceTest.java Fri Sep 12 17:58:15 2008 +0200
+++ b/jdk/test/javax/management/namespace/JMXNamespaceTest.java Fri Sep 12 19:06:38 2008 +0200
@@ -35,7 +35,6 @@
* NamespaceController.java NamespaceControllerMBean.java
* @run main/othervm JMXNamespaceTest
*/
-import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.reflect.InvocationTargetException;
@@ -52,10 +51,10 @@
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerFactory;
import javax.management.NotificationEmitter;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
-import javax.management.RuntimeOperationsException;
import javax.management.StandardMBean;
import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.JMXNamespace;
@@ -155,7 +154,7 @@
}
}
- private static class SimpleTestConf {
+ public static class SimpleTestConf {
public final Wombat wombat;
public final StandardMBean mbean;
public final String dirname;
@@ -457,259 +456,56 @@
}
}
- /**
- * Test cycle detection.
- * mkdir test ; cd test ; ln -s . kanga ; ln -s kanga/kanga/roo/kanga roo
- * touch kanga/roo/wombat
- **/
- public static void probeKangaRooTest(String[] args) {
- final SimpleTestConf conf;
+ public static void verySimpleTest(String[] args) {
+ System.err.println("verySimpleTest: starting");
try {
- conf = new SimpleTestConf(args);
- try {
- final JMXServiceURL url =
- new JMXServiceURL("rmi","localHost",0);
- final Map<String,Object> empty = Collections.emptyMap();
- final JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url,
- empty,conf.server);
- server.start();
- final JMXServiceURL address = server.getAddress();
- final JMXConnector client =
- JMXConnectorFactory.connect(address,
- empty);
- final String[] signature = {
- JMXServiceURL.class.getName(),
- Map.class.getName(),
- };
-
- final Object[] params = {
- address,
- null,
- };
- final MBeanServerConnection c =
- client.getMBeanServerConnection();
-
- // ln -s . kanga
- final ObjectName dirName1 =
- new ObjectName("kanga//:type=JMXNamespace");
- c.createMBean(JMXRemoteTargetNamespace.class.getName(),
- dirName1, params,signature);
- c.invoke(dirName1, "connect", null, null);
- try {
- // ln -s kanga//kanga//roo//kanga roo
- final JMXNamespace local = new JMXNamespace(
- new MBeanServerConnectionWrapper(null,
- JMXNamespaceTest.class.getClassLoader()){
-
- @Override
- protected MBeanServerConnection getMBeanServerConnection() {
- return JMXNamespaces.narrowToNamespace(c,
- "kanga//kanga//roo//kanga"
- );
- }
-
- });
- final ObjectName dirName2 =
- new ObjectName("roo//:type=JMXNamespace");
- conf.server.registerMBean(local,dirName2);
- System.out.println(dirName2 + " created!");
- try {
- // touch kanga/roo/wombat
- final ObjectName wombatName1 =
- new ObjectName("kanga//roo//"+conf.wombatName);
- final WombatMBean wombat1 =
- JMX.newMBeanProxy(c,wombatName1,WombatMBean.class);
- final String newCaption="I am still the same old wombat";
- Exception x = null;
- try {
- wombat1.setCaption(newCaption);
- } catch (RuntimeOperationsException r) {
- x=r.getTargetException();
- System.out.println("Got expected exception: " + x);
- // r.printStackTrace();
- }
- if (x == null)
- throw new RuntimeException("cycle not detected!");
- } finally {
- c.unregisterMBean(dirName2);
- }
- } finally {
- c.unregisterMBean(dirName1);
- client.close();
- server.stop();
- }
- } finally {
- conf.close();
- }
- System.err.println("probeKangaRooTest PASSED");
+ final MBeanServer srv = MBeanServerFactory.createMBeanServer();
+ srv.registerMBean(new JMXNamespace(
+ JMXNamespaces.narrowToNamespace(srv, "foo")),
+ JMXNamespaces.getNamespaceObjectName("foo"));
+ throw new Exception("Excpected IllegalArgumentException not raised.");
+ } catch (IllegalArgumentException x) {
+ System.err.println("verySimpleTest: got expected exception: "+x);
} catch (Exception x) {
- System.err.println("probeKangaRooTest FAILED: " +x);
+ System.err.println("verySimpleTest FAILED: " +x);
x.printStackTrace();
throw new RuntimeException(x);
}
+ System.err.println("verySimpleTest: PASSED");
}
- /**
- * Test cycle detection 2.
- * mkdir test ; cd test ; ln -s . roo ; ln -s roo/roo kanga
- * touch kanga/roo/wombat ; rm roo ; ln -s kanga roo ;
- * touch kanga/roo/wombat
- *
- **/
- public static void probeKangaRooCycleTest(String[] args) {
- final SimpleTestConf conf;
- try {
- conf = new SimpleTestConf(args);
- Exception failed = null;
- try {
- final JMXServiceURL url =
- new JMXServiceURL("rmi","localHost",0);
- final Map<String,Object> empty = Collections.emptyMap();
- final JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url,
- empty,conf.server);
- server.start();
- final JMXServiceURL address = server.getAddress();
- final JMXConnector client =
- JMXConnectorFactory.connect(address,
- empty);
- final String[] signature = {
- JMXServiceURL.class.getName(),
- Map.class.getName(),
- };
- final String[] signature2 = {
- JMXServiceURL.class.getName(),
- Map.class.getName(),
- String.class.getName()
- };
- final Object[] params = {
- address,
- Collections.emptyMap(),
- };
- final Object[] params2 = {
- address,
- null,
- "kanga",
- };
- final MBeanServerConnection c =
- client.getMBeanServerConnection();
- // ln -s . roo
- final ObjectName dirName1 =
- new ObjectName("roo//:type=JMXNamespace");
- c.createMBean(JMXRemoteTargetNamespace.class.getName(),
- dirName1, params,signature);
- c.invoke(dirName1, "connect",null,null);
- try {
- final Map<String,Object> emptyMap =
- Collections.emptyMap();
- final JMXNamespace local = new JMXNamespace(
- new MBeanServerConnectionWrapper(
- JMXNamespaces.narrowToNamespace(c,
- "roo//roo//"),
- JMXNamespaceTest.class.getClassLoader())) {
- };
- // ln -s roo/roo kanga
- final ObjectName dirName2 =
- new ObjectName("kanga//:type=JMXNamespace");
- conf.server.registerMBean(local,dirName2);
- System.out.println(dirName2 + " created!");
- try {
- // touch kanga/roo/wombat
- final ObjectName wombatName1 =
- new ObjectName("kanga//roo//"+conf.wombatName);
- final WombatMBean wombat1 =
- JMX.newMBeanProxy(c,wombatName1,WombatMBean.class);
- final String newCaption="I am still the same old wombat";
- wombat1.setCaption(newCaption);
- // rm roo
- c.unregisterMBean(dirName1);
- // ln -s kanga roo
- System.err.println("**** Creating " + dirName1 +
- " ****");
- c.createMBean(JMXRemoteTargetNamespace.class.getName(),
- dirName1, params2,signature2);
- System.err.println("**** Created " + dirName1 +
- " ****");
- Exception x = null;
- try {
- // touch kanga/roo/wombat
- wombat1.setCaption(newCaption+" I hope");
- } catch (RuntimeOperationsException r) {
- x=(Exception)r.getCause();
- System.out.println("Got expected exception: " + x);
- //r.printStackTrace();
- }
- if (x == null)
- throw new RuntimeException("should have failed!");
- x = null;
- try {
- // ls kanga/roo/wombat
- System.err.println("**** Connecting " + dirName1 +
- " ****");
- JMX.newMBeanProxy(c,dirName1,
- JMXRemoteNamespaceMBean.class).connect();
- System.err.println("**** Connected " + dirName1 +
- " ****");
- } catch (IOException r) {
- x=r;
- System.out.println("Got expected exception: " + x);
- //r.printStackTrace();
- }
- System.err.println("**** Expected Exception Not Raised ****");
- if (x == null) {
- System.out.println(dirName1+" contains: "+
- c.queryNames(new ObjectName(
- dirName1.getDomain()+"*:*"),null));
- throw new RuntimeException("cycle not detected!");
- }
- } catch (Exception t) {
- if (failed == null) failed = t;
- } finally {
- c.unregisterMBean(dirName2);
- }
- } finally {
- try {
- c.unregisterMBean(dirName1);
- } catch (Exception t) {
- if (failed == null) failed = t;
- System.err.println("Failed to unregister "+dirName1+
- ": "+t);
- }
- try {
- client.close();
- } catch (Exception t) {
- if (failed == null) failed = t;
- System.err.println("Failed to close client: "+t);
- }
- try {
- server.stop();
- } catch (Exception t) {
- if (failed == null) failed = t;
- System.err.println("Failed to stop server: "+t);
- }
- }
- } finally {
- try {
- conf.close();
- } catch (Exception t) {
- if (failed == null) failed = t;
- System.err.println("Failed to stop server: "+t);
- }
- }
- if (failed != null) throw failed;
- System.err.println("probeKangaRooCycleTest PASSED");
+ public static void verySimpleTest2(String[] args) {
+ System.err.println("verySimpleTest2: starting");
+ try {
+ final MBeanServer srv = MBeanServerFactory.createMBeanServer();
+ final JMXConnectorServer cs = JMXConnectorServerFactory.
+ newJMXConnectorServer(new JMXServiceURL("rmi",null,0),
+ null, srv);
+ cs.start();
+ final JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress());
+
+ srv.registerMBean(new JMXNamespace(
+ new MBeanServerConnectionWrapper(
+ JMXNamespaces.narrowToNamespace(
+ cc.getMBeanServerConnection(),
+ "foo"))),
+ JMXNamespaces.getNamespaceObjectName("foo"));
+ throw new Exception("Excpected IllegalArgumentException not raised.");
+ } catch (IllegalArgumentException x) {
+ System.err.println("verySimpleTest2: got expected exception: "+x);
} catch (Exception x) {
- System.err.println("probeKangaRooCycleTest FAILED: " +x);
+ System.err.println("verySimpleTest2 FAILED: " +x);
x.printStackTrace();
throw new RuntimeException(x);
}
+ System.err.println("verySimpleTest2: PASSED");
}
+
public static void main(String[] args) {
simpleTest(args);
recursiveTest(args);
- probeKangaRooTest(args);
- probeKangaRooCycleTest(args);
+ verySimpleTest(args);
+ verySimpleTest2(args);
}
}