From 2064095b24f9d3460a33404471bcbecf08b52f9d Mon Sep 17 00:00:00 2001
From: Daniel Fuchs
Date: Tue, 9 Dec 2008 20:20:48 +0100
Subject: [PATCH] 6768935: Clarify the behaviour of ObjectName pattern matching
with regards to namespaces
Reviewed-by: emcmanus
---
.../jmx/interceptor/DispatchInterceptor.java | 16 +--
.../DomainDispatchInterceptor.java | 30 ++---
.../NamespaceDispatchInterceptor.java | 125 +++++++++++++-----
.../com/sun/jmx/mbeanserver/MXBeanLookup.java | 11 +-
.../classes/com/sun/jmx/mbeanserver/Util.java | 1 -
.../sun/jmx/namespace/DomainInterceptor.java | 11 +-
.../jmx/namespace/NamespaceInterceptor.java | 9 +-
.../sun/jmx/namespace/ObjectNameRouter.java | 13 +-
.../RoutingMBeanServerConnection.java | 31 ++---
.../com/sun/jmx/namespace/RoutingProxy.java | 6 +-
.../classes/javax/management/MBeanServer.java | 10 +-
.../management/MBeanServerConnection.java | 34 ++++-
.../classes/javax/management/ObjectName.java | 106 ++++++++++++---
.../javax/management/namespace/JMXDomain.java | 10 +-
.../namespace/JMXNamespacePermission.java | 38 +-----
.../management/namespace/JMXNamespaces.java | 12 +-
.../management/namespace/package-info.java | 36 ++++-
.../namespace/LeadingSeparatorsTest.java | 23 +++-
.../namespace/NullDomainObjectNameTest.java | 35 ++++-
.../namespace/NullObjectNameTest.java | 29 +++-
.../management/namespace/QueryNamesTest.java | 66 ++++++++-
21 files changed, 441 insertions(+), 211 deletions(-)
diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java
index 4a79567fed1..f68e539d2fc 100644
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java
@@ -44,7 +44,6 @@ import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
@@ -205,8 +204,7 @@ public abstract class DispatchInterceptor
// Returns the ObjectName of the JMXNamespace (or JMXDomain) for that
// key (a namespace or a domain name).
- abstract ObjectName getHandlerNameFor(String key)
- throws MalformedObjectNameException;
+ abstract ObjectName getHandlerNameFor(String key);
// Creates an interceptor for the given key, name, JMXNamespace (or
// JMXDomain). Note: this will be either a NamespaceInterceptor
@@ -263,14 +261,10 @@ public abstract class DispatchInterceptor
void validateHandlerNameFor(String key, ObjectName name) {
if (key == null || key.equals(""))
throw new IllegalArgumentException("invalid key for "+name+": "+key);
- try {
- final ObjectName handlerName = getHandlerNameFor(key);
- if (!name.equals(handlerName))
- throw new IllegalArgumentException("bad handler name: "+name+
- ". Should be: "+handlerName);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(name.toString(),x);
- }
+ final ObjectName handlerName = getHandlerNameFor(key);
+ if (!name.equals(handlerName))
+ throw new IllegalArgumentException("bad handler name: "+name+
+ ". Should be: "+handlerName);
}
// Called by the DefaultMBeanServerInterceptor when an instance
diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java
index 9b9b1d6b19c..388af6b21dd 100644
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java
@@ -38,7 +38,6 @@ import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.namespace.JMXDomain;
@@ -248,21 +247,17 @@ class DomainDispatchInterceptor
if (pattern == null) return true;
if (pattern.isDomainPattern()) return true;
- try {
- // case b) above.
- //
- // This is a bit of a hack. If there's any chance that a JMXDomain
- // MBean name is selected by the given pattern then we must include
- // the local namespace in our search.
- //
- // Returning true will have this effect. see 2. above.
- //
- if (pattern.apply(ALL_DOMAINS.withDomain(pattern.getDomain())))
- return true;
- } catch (MalformedObjectNameException x) {
- // should not happen
- throw new IllegalArgumentException(String.valueOf(pattern), x);
- }
+ // case b) above.
+ //
+ // This is a bit of a hack. If there's any chance that a JMXDomain
+ // MBean name is selected by the given pattern then we must include
+ // the local namespace in our search.
+ //
+ // Returning true will have this effect. see 2. above.
+ //
+ if (pattern.apply(ALL_DOMAINS.withDomain(pattern.getDomain())))
+ return true;
+
return false;
}
@@ -291,8 +286,7 @@ class DomainDispatchInterceptor
}
@Override
- final ObjectName getHandlerNameFor(String key)
- throws MalformedObjectNameException {
+ final ObjectName getHandlerNameFor(String key) {
return JMXDomain.getDomainObjectName(key);
}
diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java
index d86c787b898..5ab61f8933a 100644
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java
@@ -37,8 +37,8 @@ import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
import javax.management.namespace.JMXDomain;
import javax.management.namespace.JMXNamespace;
import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
@@ -60,6 +60,7 @@ public class NamespaceDispatchInterceptor
private static final int NAMESPACE_SEPARATOR_LENGTH =
NAMESPACE_SEPARATOR.length();
+ private static final ObjectName X3 = ObjectName.valueOf("x:x=x");
private final DomainDispatchInterceptor nextInterceptor;
private final String serverName;
@@ -89,27 +90,38 @@ public class NamespaceDispatchInterceptor
serverName = Util.getMBeanServerSecurityName(delegate);
}
- // TODO: Should move that to JMXNamespace? or to ObjectName?
/**
* Get first name space in ObjectName path. Ignore leading namespace
- * separators.
+ * separators. Includes the trailing //.
+ *
+ * Examples:
+ *
+ * For ObjectName: Returns:
+ * foo//bar//baz:x=x -> "foo//"
+ * foo//:type=JMXNamespace -> "foo//"
+ * foo//:x=x -> "foo//"
+ * foo////:x=x -> "foo//"
+ * //foo//bar//baz:x=x -> "//"
+ * ////foo//bar//baz:x=x -> "//"
+ * //:x=x -> "//"
+ * foo:x=x -> ""
+ * (null) -> ""
+ * :x=x -> ""
+ *
+ *
**/
- static String getFirstNamespace(ObjectName name) {
+ static String getFirstNamespaceWithSlash(ObjectName name) {
if (name == null) return "";
final String domain = name.getDomain();
if (domain.equals("")) return "";
- // skip leading separators
- int first = 0;
- while (domain.startsWith(NAMESPACE_SEPARATOR,first))
- first += NAMESPACE_SEPARATOR_LENGTH;
-
// go to next separator
- final int end = domain.indexOf(NAMESPACE_SEPARATOR,first);
+ final int end = domain.indexOf(NAMESPACE_SEPARATOR);
if (end == -1) return ""; // no namespace
// This is the first element in the namespace path.
- final String namespace = domain.substring(first,end);
+ final String namespace =
+ domain.substring(0,end+NAMESPACE_SEPARATOR_LENGTH);
return namespace;
}
@@ -130,27 +142,49 @@ public class NamespaceDispatchInterceptor
resource.getClass().getName());
}
- final boolean isLocalHandlerNameFor(String namespace,
- ObjectName handlerName) {
- return handlerName.getDomain().equals(namespace+NAMESPACE_SEPARATOR) &&
- JMXNamespace.TYPE_ASSIGNMENT.equals(
- handlerName.getKeyPropertyListString());
+ // Removes the trailing //. namespaceWithSlash should be either
+ // "" or a namespace path ending with //.
+ //
+ private final String getKeyFor(String namespaceWithSlash) {
+ final int end = namespaceWithSlash.length() -
+ NAMESPACE_SEPARATOR_LENGTH;
+ if (end <= 0) return "";
+ final String key = namespaceWithSlash.substring(0,end);
+ return key;
}
@Override
final MBeanServer getInterceptorOrNullFor(ObjectName name) {
- final String namespace = getFirstNamespace(name);
- if (namespace.equals("") || isLocalHandlerNameFor(namespace,name) ||
- name.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) {
+ final String namespace = getFirstNamespaceWithSlash(name);
+
+ // Leading separators should trigger instance not found exception.
+ // returning null here has this effect.
+ //
+ if (namespace.equals(NAMESPACE_SEPARATOR)) {
+ LOG.finer("ObjectName starts with: "+namespace);
+ return null;
+ }
+
+ // namespace="" means that there was no namespace path in the
+ // ObjectName. => delegate to the next interceptor (local MBS)
+ // name.getDomain()=namespace means that we have an ObjectName of
+ // the form blah//:x=x. This is either a JMXNamespace or a non
+ // existent MBean. => delegate to the next interceptor (local MBS)
+ if (namespace.equals("") || name.getDomain().equals(namespace)) {
LOG.finer("dispatching to local name space");
return nextInterceptor;
}
- final NamespaceInterceptor ns = getInterceptor(namespace);
+
+ // There was a namespace path in the ObjectName. Returns the
+ // interceptor that handles it, or null if there is no such
+ // interceptor.
+ final String key = getKeyFor(namespace);
+ final NamespaceInterceptor ns = getInterceptor(key);
if (LOG.isLoggable(Level.FINER)) {
if (ns != null) {
- LOG.finer("dispatching to name space: " + namespace);
+ LOG.finer("dispatching to name space: " + key);
} else {
- LOG.finer("no handler for: " + namespace);
+ LOG.finer("no handler for: " + key);
}
}
return ns;
@@ -158,18 +192,44 @@ public class NamespaceDispatchInterceptor
@Override
final QueryInterceptor getInterceptorForQuery(ObjectName pattern) {
- final String namespace = getFirstNamespace(pattern);
- if (namespace.equals("") || isLocalHandlerNameFor(namespace,pattern) ||
- pattern.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) {
+ final String namespace = getFirstNamespaceWithSlash(pattern);
+
+ // Leading separators should trigger instance not found exception.
+ // returning null here has this effect.
+ //
+ if (namespace.equals(NAMESPACE_SEPARATOR)) {
+ LOG.finer("ObjectName starts with: "+namespace);
+ return null;
+ }
+
+ // namespace="" means that there was no namespace path in the
+ // ObjectName. => delegate to the next interceptor (local MBS)
+ // name.getDomain()=namespace means that we have an ObjectName of
+ // the form blah//:x=x. This is either a JMXNamespace or a non
+ // existent MBean. => delegate to the next interceptor (local MBS)
+ if (namespace.equals("") || pattern.getDomain().equals(namespace)) {
LOG.finer("dispatching to local name space");
return new QueryInterceptor(nextInterceptor);
}
- final NamespaceInterceptor ns = getInterceptor(namespace);
+
+ // This is a 'hack' to check whether the first namespace is a pattern.
+ // We wan to throw RTOE wrapping IAE in that case
+ if (X3.withDomain(namespace).isDomainPattern()) {
+ throw new RuntimeOperationsException(
+ new IllegalArgumentException("Pattern not allowed in namespace path"));
+ }
+
+ // There was a namespace path in the ObjectName. Returns the
+ // interceptor that handles it, or null if there is no such
+ // interceptor.
+ //
+ final String key = getKeyFor(namespace);
+ final NamespaceInterceptor ns = getInterceptor(key);
if (LOG.isLoggable(Level.FINER)) {
if (ns != null) {
- LOG.finer("dispatching to name space: " + namespace);
+ LOG.finer("dispatching to name space: " + key);
} else {
- LOG.finer("no handler for: " + namespace);
+ LOG.finer("no handler for: " + key);
}
}
if (ns == null) return null;
@@ -177,15 +237,16 @@ public class NamespaceDispatchInterceptor
}
@Override
- final ObjectName getHandlerNameFor(String key)
- throws MalformedObjectNameException {
- return ObjectName.getInstance(key+NAMESPACE_SEPARATOR,
+ final ObjectName getHandlerNameFor(String key) {
+ return ObjectName.valueOf(key+NAMESPACE_SEPARATOR,
"type", JMXNamespace.TYPE);
}
@Override
final public String getHandlerKey(ObjectName name) {
- return getFirstNamespace(name);
+ final String namespace = getFirstNamespaceWithSlash(name);
+ // namespace is either "" or a namespace ending with //
+ return getKeyFor(namespace);
}
@Override
diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
index 227c1eec990..605c67f16b4 100644
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
@@ -37,7 +37,6 @@ import javax.management.InstanceAlreadyExistsException;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.openmbean.OpenDataException;
@@ -225,7 +224,7 @@ public abstract class MXBeanLookup {
String domain = prefix + name.getDomain();
try {
name = name.withDomain(domain);
- } catch (MalformedObjectNameException e) {
+ } catch (IllegalArgumentException e) {
throw EnvHelp.initCause(
new InvalidObjectException(e.getMessage()), e);
}
@@ -239,12 +238,14 @@ public abstract class MXBeanLookup {
String domain = name.getDomain();
if (!domain.startsWith(prefix)) {
throw new OpenDataException(
- "Proxy's name does not start with " + prefix + ": " + name);
+ "Proxy's name does not start with " +
+ prefix + ": " + name);
}
try {
name = name.withDomain(domain.substring(prefix.length()));
- } catch (MalformedObjectNameException e) {
- throw EnvHelp.initCause(new OpenDataException(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw EnvHelp.initCause(
+ new OpenDataException(e.getMessage()), e);
}
return name;
}
diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java
index 5fe4d1542cc..1e575e419d2 100644
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java
@@ -48,7 +48,6 @@ import java.util.logging.Level;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerFactory;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.loading.ClassLoaderRepository;
diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java
index 7b88087a81c..6e56c8385e8 100644
--- a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java
@@ -42,7 +42,6 @@ import javax.management.ListenerNotFoundException;
import javax.management.MBeanPermission;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerNotification;
-import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
@@ -268,13 +267,9 @@ public class DomainInterceptor extends HandlerInterceptor {
// When we reach here, it has been verified that 'name' matches our domain
// name (done by DomainDispatchInterceptor)
private ObjectName getPatternFor(final ObjectName name) {
- try {
- if (name == null) return ALL;
- if (name.getDomain().equals(domainName)) return name;
- return name.withDomain(domainName);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(String.valueOf(name),x);
- }
+ if (name == null) return ALL;
+ if (name.getDomain().equals(domainName)) return name;
+ return name.withDomain(domainName);
}
@Override
diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
index 6862066d2bc..df03ed5ecba 100644
--- a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
@@ -24,15 +24,12 @@
*/
package com.sun.jmx.namespace;
-import com.sun.jmx.defaults.JmxProperties;
import java.util.ArrayList;
import java.util.List;
-import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.namespace.JMXNamespace;
import javax.management.namespace.JMXNamespacePermission;
@@ -114,14 +111,12 @@ public class NamespaceInterceptor extends HandlerInterceptor {
}
@Override
- protected ObjectName toSource(ObjectName targetName)
- throws MalformedObjectNameException {
+ protected ObjectName toSource(ObjectName targetName) {
return proc.toSourceContext(targetName, true);
}
@Override
- protected ObjectName toTarget(ObjectName sourceName)
- throws MalformedObjectNameException {
+ protected ObjectName toTarget(ObjectName sourceName) {
return proc.toTargetContext(sourceName, false);
}
diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java b/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java
index 7d668169fc7..55a6465407c 100644
--- a/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java
@@ -27,7 +27,6 @@ package com.sun.jmx.namespace;
import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
@@ -83,11 +82,7 @@ public class ObjectNameRouter {
}
final String targetDomain =
(tlen>0?targetPrefix+NAMESPACE_SEPARATOR+srcDomain:srcDomain);
- try {
- return sourceName.withDomain(targetDomain);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(String.valueOf(sourceName),x);
- }
+ return sourceName.withDomain(targetDomain);
}
public final ObjectName toSourceContext(ObjectName targetName,
@@ -113,11 +108,7 @@ public class ObjectNameRouter {
final String sourceDomain =
(slen>0?sourcePrefix+NAMESPACE_SEPARATOR+targetDomain:
targetDomain);
- try {
- return targetName.withDomain(sourceDomain);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(String.valueOf(targetName),x);
- }
+ return targetName.withDomain(sourceDomain);
}
public final ObjectInstance toTargetContext(ObjectInstance sourceMoi,
diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java
index 7022e7e2973..49b8290046b 100644
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java
@@ -46,7 +46,6 @@ import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
@@ -100,18 +99,17 @@ public abstract class RoutingMBeanServerConnection
public T source() { return source; }
@Override
- public ObjectName toSource(ObjectName targetName)
- throws MalformedObjectNameException {
+ public ObjectName toSource(ObjectName targetName) {
if (targetName == null) return null;
if (targetName.getDomain().equals("") && targetNs.equals("")) {
try {
@@ -229,8 +228,7 @@ public abstract class RoutingProxy
}
@Override
- public ObjectName toTarget(ObjectName sourceName)
- throws MalformedObjectNameException {
+ public ObjectName toTarget(ObjectName sourceName) {
if (sourceName == null) return null;
return router.toTargetContext(sourceName,false);
}
diff --git a/jdk/src/share/classes/javax/management/MBeanServer.java b/jdk/src/share/classes/javax/management/MBeanServer.java
index 6e4ee0a69c3..d602eadbcc5 100644
--- a/jdk/src/share/classes/javax/management/MBeanServer.java
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java
@@ -424,10 +424,16 @@ public interface MBeanServer extends MBeanServerConnection {
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException;
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ * @throws RuntimeOperationsException {@inheritDoc}
+ */
public Set queryMBeans(ObjectName name, QueryExp query);
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ * @throws RuntimeOperationsException {@inheritDoc}
+ */
public Set queryNames(ObjectName name, QueryExp query);
// doc comment inherited from MBeanServerConnection
diff --git a/jdk/src/share/classes/javax/management/MBeanServerConnection.java b/jdk/src/share/classes/javax/management/MBeanServerConnection.java
index add96cfcb94..11509df53c3 100644
--- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java
+++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java
@@ -436,7 +436,17 @@ public interface MBeanServerConnection extends NotificationManager {
* specified, all the MBeans registered will be retrieved.
* @param query The query expression to be applied for selecting
* MBeans. If null no query expression will be applied for
- * selecting MBeans.
+ * selecting MBeans. ObjectName patterns that may be contained in the
+ * query expression will be
+ * evaluated in the context of the
+ * {@link javax.management.namespace namespace}
+ * in which the MBeans selected by {@code name} are registered.
+ * Thus, in the {@code query} parameter, no ObjectName pattern containing a
+ * namespace path can match any of the MBean names selected by {@code name}.
+ * See the
+ * namespaces documentation for more details.
*
* @return A set containing the ObjectInstance
* objects for the selected MBeans. If no MBean satisfies the
@@ -444,6 +454,11 @@ public interface MBeanServerConnection extends NotificationManager {
*
* @exception IOException A communication problem occurred when
* talking to the MBean server.
+ * @exception RuntimeOperationsException Wraps a
+ * java.lang.IllegalArgumentException
: The name
+ * parameter contains an invalid pattern. See the
+ * namespaces documentation for more details.
*/
public Set queryMBeans(ObjectName name, QueryExp query)
throws IOException;
@@ -464,7 +479,17 @@ public interface MBeanServerConnection extends NotificationManager {
* specified, the name of all registered MBeans will be retrieved.
* @param query The query expression to be applied for selecting
* MBeans. If null no query expression will be applied for
- * selecting MBeans.
+ * selecting MBeans. ObjectName patterns that may be contained in the
+ * query expression will be
+ * evaluated in the context of the
+ * {@link javax.management.namespace namespace}
+ * in which the MBeans slected by {@code name} are registered.
+ * Thus, in the {@code query} parameter, no ObjectName pattern containing a
+ * namespace path can match any of the MBean names selected by {@code name}.
+ * See the
+ * namespaces documentation for more details.
*
* @return A set containing the ObjectNames for the MBeans
* selected. If no MBean satisfies the query, an empty list is
@@ -472,6 +497,11 @@ public interface MBeanServerConnection extends NotificationManager {
*
* @exception IOException A communication problem occurred when
* talking to the MBean server.
+ * @exception RuntimeOperationsException Wraps a
+ * java.lang.IllegalArgumentException
: The name
+ * parameter contains an invalid pattern. See the
+ * namespaces documentation for more details.
*/
public Set queryNames(ObjectName name, QueryExp query)
throws IOException;
diff --git a/jdk/src/share/classes/javax/management/ObjectName.java b/jdk/src/share/classes/javax/management/ObjectName.java
index 8185edc2742..41025a7688a 100644
--- a/jdk/src/share/classes/javax/management/ObjectName.java
+++ b/jdk/src/share/classes/javax/management/ObjectName.java
@@ -56,14 +56,38 @@ import java.util.Map;
* properties.
*
* The domain is a string of characters not including
- * the character colon (:
). It is recommended that the domain
- * should not contain the string "{@code //}", which is reserved for future use.
+ * the character colon (:
).
+ * Starting with the version 2.0 of the JMX specification, the
+ * domain can also start with a {@linkplain
+ * javax.management.namespace#NamespacePrefix namespace prefix} identifying
+ * the {@linkplain javax.management.namespace namespace} in which the
+ * MBean is registered. A namespace prefix is a path string where
+ * elements are separated by a double slash (//
).
+ * It identifies the {@linkplain javax.management.namespace namespace} in
+ * which the MBean so named is registered.
+ *
+ * For instance the ObjectName bar//baz:k=v identifiies an MBean
+ * named baz:k=v in the namespace bar. Similarly the
+ * ObjectName foo//bar//baz:k=v identifiies an MBean named
+ * baz:k=v in the namespace foo//bar. See the {@linkplain
+ * javax.management.namespace namespace} documentation for more details.
*
* If the domain includes at least one occurrence of the wildcard
* characters asterisk (*
) or question mark
* (?
), then the object name is a pattern. The asterisk
* matches any sequence of zero or more characters, while the question
- * mark matches any single character.
+ * mark matches any single character.
+ * A namespace separator //
does not match wildcard
+ * characters unless it is at the very end of the domain string.
+ * So foo*bar*:* does not match foo//bar:k=v but it
+ * does match fooxbar//:k=v.
+ *
+ *
+ * When included in a namespace path the special path element
+ * **
matches any number of sub namespaces
+ * recursively, but only if used as a complete namespace path element,
+ * as in **//b//c//D:k=v
or a//**//c//D:k=v
+ * - see below.
*
*
If the domain is empty, it will be replaced in certain contexts
* by the default domain of the MBean server in which the
@@ -171,6 +195,51 @@ import java.util.Map;
* with {@code \}.
*
*
+ *
Pattern and namespaces:
+ * In an object name pattern, a path element
+ * of exactly **
corresponds to a meta
+ * wildcard that will match any number of sub namespaces.
Hence:
+ *
+ * pattern | matches | doesn't match |
+ *
+ * |
+ * a//D:k=v
+ * a//b//D:k=v
+ * a//b//c//D:k=v |
+ * D:k=v |
+ * |
+ * a//b//D:k=v
+ * a//b//c//D:k=v |
+ * b//b//c//D:k=v
+ * a//D:k=v
+ * D:k=v |
+ * |
+ * a//b//e//D:k=v
+ * a//b//c//e//D:k=v |
+ * a//b//c//c//D:k=v
+ * b//b//c//e//D:k=v
+ * a//e//D:k=v
+ * e//D:k=v |
+ * |
+ * a//b//e//D:k=v |
+ * a//b//c//e//D:k=v
+ * because in that case b**
+ * is not a meta-wildcard - and b**
+ * is thus equivalent to b* . |
+ *
+ *
+ *
+ *
+ *
+ * Note: Although ObjectName patterns where the characters
+ * *
and ?
appear in the namespace path are legal,
+ * they are not valid in the {@code name} parameter of the MBean Server's
+ * {@link MBeanServer#queryNames queryNames} and {@link MBeanServer#queryMBeans
+ * queryMBeans} methods. See the
+ * namespaces documentation for more details.
+ *
+ *
* An ObjectName can be written as a String with the following
* elements in order:
*
@@ -439,11 +508,6 @@ public class ObjectName implements Comparable, QueryExp {
_propertyList = aname._propertyList;
_property_list_pattern = aname._property_list_pattern;
_property_value_pattern = aname._property_value_pattern;
- // TODO remove this hack
- // if (toString().endsWith("//javax.management.service:type1=event_client_delegeate_mbean,type2=default")) {
- // Thread.currentThread().dumpStack();
- // throw new Error("************************ Gotcha!");
- //}
}
// Instance private fields <=======================================
@@ -1096,11 +1160,10 @@ public class ObjectName implements Comparable, QueryExp {
*/
private boolean isDomain(String domain) {
if (domain == null) return true;
- final char[] d=domain.toCharArray();
- final int len = d.length;
+ final int len = domain.length();
int next = 0;
while (next < len) {
- final char c = d[next++];
+ final char c = domain.charAt(next++);
switch (c) {
case ':' :
case '\n' :
@@ -1234,12 +1297,6 @@ public class ObjectName implements Comparable, QueryExp {
if (!nw.equals("")) {
nameString = nw + NAMESPACE_SEPARATOR + nameString;
}
- // TODO remove this hack
- // if (nameString.endsWith("//javax.management.service:type1=event_client_delegeate_mbean,type2=default")) {
- // System.err.println("old="+old+", nw="+nw);
- // Thread.currentThread().dumpStack();
- // throw new Error("************************ Gotcha!");
- // }
return nameString;
}
@@ -1584,13 +1641,18 @@ public class ObjectName implements Comparable, QueryExp {
* @return A new {@code ObjectName} that is the same as {@code this}
* except the domain is {@code newDomain}.
* @throws NullPointerException if {@code newDomain} is null.
- * @throws MalformedObjectNameException if the new domain is syntactically
- * illegal.
+ * @exception IllegalArgumentException The {@code newDomain} passed as a
+ * parameter does not have the right format. The {@linkplain
+ * Throwable#getCause() cause} of this exception will be a
+ * {@link MalformedObjectNameException}.
* @since 1.7
**/
- public final ObjectName withDomain(String newDomain)
- throws MalformedObjectNameException {
- return new ObjectName(newDomain, this);
+ public final ObjectName withDomain(String newDomain) {
+ try {
+ return new ObjectName(newDomain, this);
+ } catch (MalformedObjectNameException x) {
+ throw new IllegalArgumentException(x.getMessage(),x);
+ }
}
/**
diff --git a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java
index bff3c137062..ca108bf126b 100644
--- a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java
+++ b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java
@@ -35,7 +35,6 @@ import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
/**
@@ -291,12 +290,9 @@ public class JMXDomain extends JMXNamespace {
public static ObjectName getDomainObjectName(String domain) {
if (domain == null) return null;
if (domain.contains(NAMESPACE_SEPARATOR))
- throw new IllegalArgumentException(domain);
- try {
- return ObjectName.getInstance(domain, "type", TYPE);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(domain,x);
- }
+ throw new IllegalArgumentException("domain contains " +
+ NAMESPACE_SEPARATOR+": "+domain);
+ return ObjectName.valueOf(domain, "type", TYPE);
}
diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java
index 5dd012672b3..62608cb0610 100644
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java
+++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java
@@ -136,7 +136,8 @@ import java.security.Permission;
* **
matches any number of sub namespaces
* recursively, but only if used as a complete namespace path element,
* as in **//b//c//D:k=v
or a//**//c//D:k=v
- * - see below.
+ * - see ObjectName documentation
+ * for more details.
*
*
*
@@ -270,38 +271,9 @@ import java.security.Permission;
*
* Note on wildcards: In an object name pattern, a path element
* of exactly **
corresponds to a meta
- * wildcard that will match any number of sub namespaces. Hence:
- *
- *
- * pattern | matches | doesn't match |
- *
- * **//D:k=v |
- * a//D:k=v
- * a//b//D:k=v
- * a//b//c//D:k=v |
- * D:k=v |
- * a//**//D:k=v |
- * a//b//D:k=v
- * a//b//c//D:k=v |
- * b//b//c//D:k=v
- * a//D:k=v
- * D:k=v |
- * a//**//e//D:k=v |
- * a//b//e//D:k=v
- * a//b//c//e//D:k=v |
- * a//b//c//c//D:k=v
- * b//b//c//e//D:k=v
- * a//e//D:k=v
- * e//D:k=v |
- * a//b**//e//D:k=v |
- * a//b//e//D:k=v |
- * a//b//c//e//D:k=v
- * because in that case b**
- * is not a meta-wildcard - and b**
- * is thus equivalent to b* . |
- *
- *
- *
+ * wildcard that will match any number of sub namespaces.
+ * See ObjectName documentation
+ * for more details.
*
* If {@code ::} is omitted, then one of
* member
or object name
may be omitted.
diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java
index f19dfa570e4..ca7244abd28 100644
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java
+++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java
@@ -292,17 +292,13 @@ public class JMXNamespaces {
if (path == null || to == null)
throw new IllegalArgumentException("Null argument");
checkTrailingSlashes(path);
- try {
- String prefix = path;
- if (!prefix.equals("")) prefix =
- ObjectNameRouter.normalizeNamespacePath(
+ String prefix = path;
+ if (!prefix.equals(""))
+ prefix = ObjectNameRouter.normalizeNamespacePath(
prefix + NAMESPACE_SEPARATOR,false,false,false);
- return to.withDomain(
+ return to.withDomain(
ObjectNameRouter.normalizeDomain(
prefix+to.getDomain(),false));
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(path+": "+x,x);
- }
}
/**
diff --git a/jdk/src/share/classes/javax/management/namespace/package-info.java b/jdk/src/share/classes/javax/management/namespace/package-info.java
index df8354bab63..5c014286d4d 100644
--- a/jdk/src/share/classes/javax/management/namespace/package-info.java
+++ b/jdk/src/share/classes/javax/management/namespace/package-info.java
@@ -204,7 +204,38 @@
*
* An easier way to access MBeans contained in a name space is to
* cd inside the name space, as shown in the following paragraph.
- *
+ *
+ * Although ObjectName patterns where the characters
+ * *
and ?
appear in the namespace path are
+ * legal, they are not valid in the {@code name} parameter of the
+ * MBean Server {@link
+ * javax.management.MBeanServer#queryNames queryNames} and {@link
+ * javax.management.MBeanServer#queryMBeans queryMBeans} methods.
+ * When invoking queryNames
or queryMBeans
,
+ * only ObjectNames of the form:
+ * [namespace-without-pattern//]*[pattern-without-namespace]:key-properties-with-or-without-pattern
+ * are valid.
+ * In other words: in the case of {@link
+ * javax.management.MBeanServer#queryNames queryNames} and {@link
+ * javax.management.MBeanServer#queryMBeans queryMBeans}, if a
+ * namespace path is present, it must not contain any pattern.
+ *
+ * There is no such restriction for the {@code query} parameter of these
+ * methods. However, it must be noted that the {@code query} parameter
+ * will be evaluated in the context of the namespace where the MBeans
+ * selected by the pattern specified in {@code name} are located.
+ * This means that if {@code query} parameter is an ObjectName pattern that
+ * contains a namespace path, no MBean name will match and the result of
+ * the query will be empty.
+ * In other words:
+ * - {@code queryNames("foo//bar//?a?:*","b?z:type=Monitor,*")} will select
+ * all MBeans in namespace foo//bar whose names match both
+ * ?a?:* and b?z:type=Monitor,*, but
+ * - {@code queryNames("foo//bar//?a?:*","foo//bar//b?z:type=Monitor,*")}
+ * will select nothing because no name matching ?a?:* will
+ * also match foo//bar//b?z:type=Monitor,*.
+ *
+ *
*
* Narrowing Down Into a Name Spaces
*
@@ -228,7 +259,8 @@
* to name space {@code "foo"} behaves just like a regular MBean server.
* However, it may sometimes throw an {@link
* java.lang.UnsupportedOperationException UnsupportedOperationException}
- * wrapped in a JMX exception if you try to call an operation which is not
+ * wrapped in a {@link javax.management.RuntimeOperationsException
+ * RuntimeOperationsException} if you try to call an operation which is not
* supported by the underlying name space handler.
*
For instance, {@link javax.management.MBeanServer#registerMBean
* registerMBean} is not supported for name spaces mounted from remote
diff --git a/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java b/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java
index 5660b275317..6f931ffd46d 100644
--- a/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java
+++ b/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java
@@ -24,7 +24,7 @@
* @test LeadingSeparatorsTest.java
* @summary Test that the semantics of a leading // in ObjectName is respected.
* @author Daniel Fuchs
- * @bug 5072476
+ * @bug 5072476 6768935
* @run clean LeadingSeparatorsTest Wombat WombatMBean
* @compile -XDignore.symbol.file=true LeadingSeparatorsTest.java
* @run build LeadingSeparatorsTest Wombat WombatMBean
@@ -36,6 +36,7 @@ import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.logging.Logger;
+import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.NotCompliantMBeanException;
@@ -121,19 +122,29 @@ public class LeadingSeparatorsTest {
// register wombat using an object name with a leading //
final Object obj = new MyWombat();
// check that returned object name doesn't have the leading //
- assertEquals(n2,top.registerMBean(obj, n1).getObjectName());
+ assertEquals(n2,top.registerMBean(obj, n2).getObjectName());
System.out.println(n1+" registered");
// check that the registered Wombat can be accessed with all its
// names.
System.out.println(n2+" mood is: "+top.getAttribute(n2, "Mood"));
- System.out.println(n1+" mood is: "+top.getAttribute(n1, "Mood"));
+ try {
+ System.out.println(n1+" mood is: "+top.getAttribute(n1, "Mood"));
+ throw new Exception("Excepected exception not thrown for "+n1);
+ } catch (InstanceNotFoundException x) {
+ System.out.println("OK: "+x);
+ }
System.out.println(n4+" mood is: "+top.getAttribute(n4, "Mood"));
- System.out.println(n3+" mood is: "+top.getAttribute(n3, "Mood"));
+ try {
+ System.out.println(n3+" mood is: "+top.getAttribute(n3, "Mood"));
+ throw new Exception("Excepected exception not thrown for "+n3);
+ } catch (InstanceNotFoundException x) {
+ System.out.println("OK: "+x);
+ }
// call listMatching. The result should not contain any prefix.
final Set res = (Set)
- top.invoke(n3, "listMatching",
+ top.invoke(n4, "listMatching",
// remove rmi// from rmi//*:*
JMXNamespaces.deepReplaceHeadNamespace(
new Object[] {ObjectName.WILDCARD.withDomain("rmi//*")},
@@ -158,7 +169,7 @@ public class LeadingSeparatorsTest {
// //niark//niark//
//
final Set res4 = (Set)
- top.invoke(n3, "untrue",
+ top.invoke(n4, "untrue",
// remove niark//niark : should remove nothing since
// our ObjectName begins with a leading //
JMXNamespaces.deepReplaceHeadNamespace(
diff --git a/jdk/test/javax/management/namespace/NullDomainObjectNameTest.java b/jdk/test/javax/management/namespace/NullDomainObjectNameTest.java
index 6b1ad51c252..fa8455e2a15 100644
--- a/jdk/test/javax/management/namespace/NullDomainObjectNameTest.java
+++ b/jdk/test/javax/management/namespace/NullDomainObjectNameTest.java
@@ -40,6 +40,7 @@ import javax.management.MBeanServerFactory;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.JMXRemoteNamespace;
import javax.management.namespace.JMXNamespace;
@@ -215,9 +216,20 @@ public class NullDomainObjectNameTest {
assertEquals(proxy.queryNames(
new ObjectName(":*"),null).
contains(moi3.getObjectName()),true);
- failed("queryNames(null,null) should have failed for faked//");
- } catch (IllegalArgumentException x) {
- System.out.println("Received expected exception for faked//: "+x);
+ failed("queryNames(new ObjectName(\":*\"),null) " +
+ "should have failed for faked//");
+ } catch (RuntimeOperationsException x) {
+ if (x.getCause() instanceof IllegalArgumentException)
+ System.out.println(
+ "Received expected exception for faked//: "+x);
+ else {
+ System.err.println(
+ "Expected exception has unexpected cause " +
+ "for faked//: "+x.getCause());
+ x.printStackTrace();
+ failed("queryNames(new ObjectName(\":*\"),null)" +
+ " failed with unexpected cause for faked//");
+ }
}
// These should fail because the ObjectName doesn't start
// with "faked//"
@@ -226,9 +238,20 @@ public class NullDomainObjectNameTest {
"new ObjectName(\":*\"),null) with faked//");
assertEquals(proxy.queryMBeans(
new ObjectName(":*"),null).contains(moi3),true);
- failed("queryMBeans(null,null) should have failed for faked//");
- } catch (IllegalArgumentException x) {
- System.out.println("Received expected exception for faked//: "+x);
+ failed("queryMBeans(new ObjectName(\":*\"),null)" +
+ " should have failed for faked//");
+ } catch (RuntimeOperationsException x) {
+ if (x.getCause() instanceof IllegalArgumentException)
+ System.out.println(
+ "Received expected exception for faked//: "+x);
+ else {
+ System.err.println(
+ "Expected exception has unexpected cause " +
+ "for faked//: "+x.getCause());
+ x.printStackTrace();
+ failed("queryMBeans(new ObjectName(\":*\"),null) " +
+ "failed with unexpected cause for faked//");
+ }
}
System.out.println("Checking queryNames(faked//*:*,null)");
diff --git a/jdk/test/javax/management/namespace/NullObjectNameTest.java b/jdk/test/javax/management/namespace/NullObjectNameTest.java
index 0e645dc1e3c..5cf99a230e5 100644
--- a/jdk/test/javax/management/namespace/NullObjectNameTest.java
+++ b/jdk/test/javax/management/namespace/NullObjectNameTest.java
@@ -41,6 +41,7 @@ import javax.management.MBeanServerFactory;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.JMXRemoteNamespace;
import javax.management.namespace.JMXNamespace;
@@ -189,15 +190,35 @@ public class NullObjectNameTest {
assertEquals(proxy.queryNames(null,null).
contains(moi3.getObjectName()),true);
failed("queryNames(null,null) should have failed for faked//");
- } catch (IllegalArgumentException x) {
- System.out.println("Received expected exception for faked//: "+x);
+ } catch (RuntimeOperationsException x) {
+ if (x.getCause() instanceof IllegalArgumentException)
+ System.out.println(
+ "Received expected exception for faked//: "+x);
+ else {
+ System.err.println(
+ "Expected exception has unexpected cause " +
+ "for faked//: "+x.getCause());
+ x.printStackTrace();
+ failed("queryNames(null,null) failed with unexpected " +
+ "cause for faked//");
+ }
}
try {
System.out.println("Checking queryMBeans(null,null) with faked//");
assertEquals(proxy.queryMBeans(null,null).contains(moi3),true);
failed("queryMBeans(null,null) should have failed for faked//");
- } catch (IllegalArgumentException x) {
- System.out.println("Received expected exception for faked//: "+x);
+ } catch (RuntimeOperationsException x) {
+ if (x.getCause() instanceof IllegalArgumentException)
+ System.out.println(
+ "Received expected exception for faked//: "+x);
+ else {
+ System.err.println(
+ "Expected exception has unexpected cause " +
+ "for faked//: "+x.getCause());
+ x.printStackTrace();
+ failed("queryMBeans(null,null) failed with unexpected " +
+ "cause for faked//");
+ }
}
System.out.println("Checking queryNames(faked//*:*,null)");
assertEquals(proxy.queryNames(new ObjectName("faked//*:*"),null).
diff --git a/jdk/test/javax/management/namespace/QueryNamesTest.java b/jdk/test/javax/management/namespace/QueryNamesTest.java
index 1af597aceb9..5b507644600 100644
--- a/jdk/test/javax/management/namespace/QueryNamesTest.java
+++ b/jdk/test/javax/management/namespace/QueryNamesTest.java
@@ -25,7 +25,7 @@
* @test QueryNamesTest.java 1.4
* @summary Test how queryNames works with Namespaces.
* @author Daniel Fuchs
- * @bug 5072476
+ * @bug 5072476 6768935
* @run clean QueryNamesTest Wombat WombatMBean
* @run build QueryNamesTest Wombat WombatMBean
* @run main QueryNamesTest
@@ -34,6 +34,7 @@
import java.io.IOException;
import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -52,7 +53,9 @@ import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
+import javax.management.ObjectInstance;
import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
import javax.management.namespace.JMXNamespace;
import javax.management.namespace.JMXNamespaces;
@@ -366,6 +369,66 @@ public class QueryNamesTest {
return res;
}
+ private static void checkNsPattern(MBeanServer server) throws Exception {
+ final List list = new ArrayList();
+ for (String s : namespaces) {
+ final String[] cmpnt = s.split("//");
+ for (int i=0;i res = new HashSet();
+
+ try {
+ res.addAll(server.queryNames(ObjectName.valueOf(s),null));
+ } catch (RuntimeOperationsException x) {
+ if (x.getCause() instanceof IllegalArgumentException) {
+ System.out.println("queryNames("+s+"): OK - received "+x.getCause());
+ continue;
+ }
+ System.err.println("queryNames("+s+"): Bad cause: "+x.getCause());
+ throw x;
+ } catch (Exception x) {
+ System.err.println("queryNames("+s+"): Bad exception: "+x);
+ throw x;
+ }
+ System.err.println("queryNames("+s+"): Bad result: "+res);
+ System.err.println("queryNames("+s+"): Excpected exception not thrown.");
+ throw new Exception("queryNames("+s+"): Excpected exception not thrown.");
+ }
+ for (String s : list) {
+ final Set res = new HashSet();
+
+ try {
+ res.addAll(server.queryMBeans(ObjectName.valueOf(s),null));
+ } catch (RuntimeOperationsException x) {
+ if (x.getCause() instanceof IllegalArgumentException) {
+ System.out.println("queryMBeans("+s+"): OK - received "+x.getCause());
+ continue;
+ }
+ System.err.println("queryMBeans("+s+"): Bad cause: "+x.getCause());
+ throw x;
+ } catch (Exception x) {
+ System.err.println("queryMBeans("+s+"): Bad exception: "+x);
+ throw x;
+ }
+ System.err.println("queryMBeans("+s+"): Bad result: "+res);
+ System.err.println("queryMBeans("+s+"): Excpected exception not thrown.");
+ throw new Exception("queryMBeans("+s+"): Excpected exception not thrown.");
+ }
+ }
+
public static void main(String[] args)
throws Exception {
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
@@ -378,6 +441,7 @@ public class QueryNamesTest {
System.out.println("Domains: " +Arrays.asList(server.getDomains()));
checkRegistration(server);
checkNsQuery(server);
+ checkNsPattern(server);
} finally {
boolean res = true;
res = res && removeWombats(server, wombats);