2.0
.
+ * The value is 1.4
.
*/
- public static final String JMX_SPEC_VERSION = "2.0";
+ public static final String JMX_SPEC_VERSION = "1.4";
/**
* The vendor of the JMX specification implemented by this product.
diff --git a/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java b/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java
deleted file mode 100644
index ca2462b32ad9df58df7e2cf0f5a750245bf2dfe4..0000000000000000000000000000000000000000
--- a/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.jmx.event;
-
-import com.sun.jmx.remote.util.ClassLogger;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class DaemonThreadFactory implements ThreadFactory {
- public DaemonThreadFactory(String nameTemplate) {
- this(nameTemplate, null);
- }
-
- // nameTemplate should be a format with %d in it, which will be replaced
- // by a sequence number of threads created by this factory.
- public DaemonThreadFactory(String nameTemplate, ThreadGroup threadGroup) {
- if (logger.debugOn()) {
- logger.debug("DaemonThreadFactory",
- "Construct a new daemon factory: "+nameTemplate);
- }
-
- if (threadGroup == null) {
- SecurityManager s = System.getSecurityManager();
- threadGroup = (s != null) ? s.getThreadGroup() :
- Thread.currentThread().getThreadGroup();
- }
-
- this.nameTemplate = nameTemplate;
- this.threadGroup = threadGroup;
- }
-
- public Thread newThread(Runnable r) {
- final String name =
- String.format(nameTemplate, threadNumber.getAndIncrement());
- Thread t = new Thread(threadGroup, r, name, 0);
- t.setDaemon(true);
- if (t.getPriority() != Thread.NORM_PRIORITY)
- t.setPriority(Thread.NORM_PRIORITY);
-
- if (logger.debugOn()) {
- logger.debug("newThread",
- "Create a new daemon thread with the name "+t.getName());
- }
-
- return t;
- }
-
- private final String nameTemplate;
- private final ThreadGroup threadGroup;
- private final AtomicInteger threadNumber = new AtomicInteger(1);
-
- private static final ClassLogger logger =
- new ClassLogger("com.sun.jmx.event", "DaemonThreadFactory");
-}
diff --git a/src/share/classes/com/sun/jmx/event/EventBuffer.java b/src/share/classes/com/sun/jmx/event/EventBuffer.java
deleted file mode 100644
index ed804791097bbb90ec05908a970a7e76248f7dfc..0000000000000000000000000000000000000000
--- a/src/share/classes/com/sun/jmx/event/EventBuffer.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.jmx.event;
-
-import com.sun.jmx.remote.util.ClassLogger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
-
-public class EventBuffer {
-
- public EventBuffer() {
- this(Integer.MAX_VALUE, null);
- }
-
- public EventBuffer(int capacity) {
- this(capacity, new ArrayListManage a renewable lease. The lease can be renewed indefinitely - * but if the lease runs to its current expiry date without being renewed - * then the expiry callback is invoked. If the lease has already expired - * when renewal is attempted then the lease method returns zero.
- * @author sjiang - * @author emcmanus - */ -// The synchronization logic of this class is tricky to deal correctly with the -// case where the lease expires at the same time as the |lease| or |stop| method -// is called. If the lease is active then the field |scheduled| represents -// the expiry task; otherwise |scheduled| is null. Renewing or stopping the -// lease involves canceling this task and setting |scheduled| either to a new -// task (to renew) or to null (to stop). -// -// Suppose the expiry task runs at the same time as the |lease| method is called. -// If the task enters its synchronized block before the method starts, then -// it will set |scheduled| to null and the method will return 0. If the method -// starts before the task enters its synchronized block, then the method will -// cancel the task which will see that when it later enters the block. -// Similar reasoning applies to the |stop| method. It is not expected that -// different threads will call |lease| or |stop| simultaneously, although the -// logic should be correct then too. -public class LeaseManager { - public LeaseManager(Runnable callback) { - this(callback, EventParams.getLeaseTimeout()); - } - - public LeaseManager(Runnable callback, long timeout) { - if (logger.traceOn()) { - logger.trace("LeaseManager", "new manager with lease: "+timeout); - } - if (callback == null) { - throw new NullPointerException("Null callback."); - } - if (timeout <= 0) - throw new IllegalArgumentException("Timeout must be positive: " + timeout); - - this.callback = callback; - schedule(timeout); - } - - /** - *Renew the lease for the given time. The new time can be shorter - * than the previous one, in which case the lease will expire earlier - * than it would have.
- * - *Calling this method after the lease has expired will return zero - * immediately and have no other effect.
- * - * @param timeout the new lifetime. If zero, the lease - * will expire immediately. - */ - public synchronized long lease(long timeout) { - if (logger.traceOn()) { - logger.trace("lease", "new lease to: "+timeout); - } - - if (timeout < 0) - throw new IllegalArgumentException("Negative lease: " + timeout); - - if (scheduled == null) - return 0L; - - scheduled.cancel(false); - - if (logger.traceOn()) - logger.trace("lease", "start lease: "+timeout); - schedule(timeout); - - return timeout; - } - - private class Expire implements Runnable { - ScheduledFuture> task; - - public void run() { - synchronized (LeaseManager.this) { - if (task.isCancelled()) - return; - scheduled = null; - } - callback.run(); - executor.shutdown(); - } - } - - private synchronized void schedule(long timeout) { - Expire expire = new Expire(); - scheduled = executor.schedule(expire, timeout, TimeUnit.MILLISECONDS); - expire.task = scheduled; - } - - /** - *Cancel the lease without calling the expiry callback.
- */ - public synchronized void stop() { - logger.trace("stop", "canceling lease"); - scheduled.cancel(false); - scheduled = null; - try { - executor.shutdown(); - } catch (SecurityException e) { - // OK: caller doesn't have RuntimePermission("modifyThread") - // which is unlikely in reality but triggers a test failure otherwise - logger.trace("stop", "exception from executor.shutdown", e); - } - } - - private final Runnable callback; - private ScheduledFuture> scheduled; // If null, the lease has expired. - - private static final ThreadFactory threadFactory = - new DaemonThreadFactory("JMX LeaseManager %d"); - private final ScheduledExecutorService executor - = Executors.newScheduledThreadPool(1, threadFactory); - - private static final ClassLogger logger = - new ClassLogger("javax.management.event", "LeaseManager"); - -} diff --git a/src/share/classes/com/sun/jmx/event/LeaseRenewer.java b/src/share/classes/com/sun/jmx/event/LeaseRenewer.java deleted file mode 100644 index 8ba6877221e5b4176cca9a42bf9e17faaabd6348..0000000000000000000000000000000000000000 --- a/src/share/classes/com/sun/jmx/event/LeaseRenewer.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package com.sun.jmx.event; - -import com.sun.jmx.remote.util.ClassLogger; -import java.util.concurrent.Callable; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -/** - * - * @author sjiang - */ -public class LeaseRenewer { - public LeaseRenewer(ScheduledExecutorService scheduler, CallableA task that is repeatedly run by an Executor. The task will be - * repeated as long as the {@link #isSuspended()} method returns true. Once - * that method returns false, the task is no longer executed until someone - * calls {@link #resume()}.
- * @author sjiang - */ -public abstract class RepeatedSingletonJob implements Runnable { - public RepeatedSingletonJob(Executor executor) { - if (executor == null) { - throw new NullPointerException("Null executor!"); - } - - this.executor = executor; - } - - public boolean isWorking() { - return working; - } - - public void resume() { - - synchronized(this) { - if (!working) { - if (logger.traceOn()) { - logger.trace("resume", ""); - } - working = true; - execute(); - } - } - } - - public abstract void task(); - public abstract boolean isSuspended(); - - public void run() { - if (logger.traceOn()) { - logger.trace("run", "execute the task"); - } - try { - task(); - } catch (Exception e) { - // A correct task() implementation should not throw exceptions. - // It may cause isSuspended() to start returning true, though. - logger.trace("run", "failed to execute the task", e); - } - - synchronized(this) { - if (!isSuspended()) { - execute(); - } else { - if (logger.traceOn()) { - logger.trace("run", "suspend the task"); - } - working = false; - } - } - - } - - private void execute() { - try { - executor.execute(this); - } catch (RejectedExecutionException e) { - logger.warning( - "execute", - "Executor threw exception (" + this.getClass().getName() + ")", - e); - throw new RejectedExecutionException( - "Executor.execute threw exception -" + - "should not be possible", e); - // User-supplied Executor should not be configured in a way that - // might cause this exception, for example if it is shared between - // several client objects and doesn't have capacity for one job - // from each one. CR 6732037 will add text to the spec explaining - // the problem. The rethrown exception will propagate either out - // of resume() to user code, or out of run() to the Executor - // (which will probably ignore it). - } - } - - private boolean working = false; - private final Executor executor; - - private static final ClassLogger logger = - new ClassLogger("javax.management.event", "RepeatedSingletonJob"); -} diff --git a/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java b/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java index faa39e7656faacbbc6a55dc24f512cb46125c935..c959120e4a7dcf3a43b22a7974223a5a43e13736 100644 --- a/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java +++ b/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java @@ -30,16 +30,15 @@ package com.sun.jmx.interceptor; import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; import com.sun.jmx.mbeanserver.DynamicMBean2; import com.sun.jmx.mbeanserver.Introspector; -import com.sun.jmx.mbeanserver.MBeanInjector; import com.sun.jmx.mbeanserver.MBeanInstantiator; import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; import com.sun.jmx.mbeanserver.NamedObject; -import com.sun.jmx.mbeanserver.NotifySupport; import com.sun.jmx.mbeanserver.Repository; import com.sun.jmx.mbeanserver.Repository.RegistrationContext; import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.remote.util.EnvHelp; +import java.io.ObjectInputStream; import java.lang.ref.WeakReference; import java.security.AccessControlContext; import java.security.AccessController; @@ -48,10 +47,7 @@ import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; import java.util.List; -import java.util.Queue; import java.util.Set; import java.util.WeakHashMap; import java.util.logging.Level; @@ -61,7 +57,6 @@ import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; -import javax.management.DynamicWrapperMBean; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; @@ -70,7 +65,6 @@ import javax.management.JMRuntimeException; import javax.management.ListenerNotFoundException; import javax.management.MBeanException; import javax.management.MBeanInfo; -import javax.management.MBeanNotificationInfo; import javax.management.MBeanPermission; import javax.management.MBeanRegistration; import javax.management.MBeanRegistrationException; @@ -81,19 +75,19 @@ import javax.management.MBeanTrustPermission; import javax.management.NotCompliantMBeanException; import javax.management.Notification; import javax.management.NotificationBroadcaster; -import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationEmitter; import javax.management.NotificationFilter; import javax.management.NotificationListener; import javax.management.ObjectInstance; import javax.management.ObjectName; +import javax.management.OperationsException; import javax.management.QueryEval; import javax.management.QueryExp; import javax.management.ReflectionException; import javax.management.RuntimeErrorException; import javax.management.RuntimeMBeanException; import javax.management.RuntimeOperationsException; -import javax.management.namespace.JMXNamespace; +import javax.management.loading.ClassLoaderRepository; /** * This is the default class for MBean manipulation on the agent side. It @@ -116,8 +110,7 @@ import javax.management.namespace.JMXNamespace; * * @since 1.5 */ -public class DefaultMBeanServerInterceptor - extends MBeanServerInterceptorSupport { +public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { /** The MBeanInstantiator object used by the * DefaultMBeanServerInterceptor */ @@ -142,14 +135,9 @@ public class DefaultMBeanServerInterceptor new WeakHashMap- * This API is a Sun internal API and is subject to changes without notice. - *
- * @since 1.7 - */ -// -// This is the base class for implementing dispatchers. We have two concrete -// dispatcher implementations: -// -// * A NamespaceDispatchInterceptor, which dispatch calls to existing -// namespace interceptors -// * A DomainDispatchInterceptor, which dispatch calls to existing domain -// interceptors. -// -// With the JMX Namespaces feature, the JMX MBeanServer is now structured -// as follows: -// -// The JMX MBeanServer delegates to a NamespaceDispatchInterceptor, -// which either dispatches to a namespace, or delegates to the -// DomainDispatchInterceptor (if the object name contained no namespace). -// The DomainDispatchInterceptor in turn either dispatches to a domain (if -// there is a JMXDomain for that domain) or delegates to the -// DefaultMBeanServerInterceptor (if there is no JMXDomain for that -// domain). This makes the following picture: -// -// JMX MBeanServer (outer shell) -// | -// | -// NamespaceDispatchInterceptor -// / \ -// no namespace in object name? \ -// / \ -// / dispatch to namespace -// DomainDispatchInterceptor -// / \ -// no JMXDomain for domain? \ -// / \ -// / dispatch to domain -// DefaultMBeanServerInterceptor -// / -// invoke locally registered MBean -// -// The logic for maintaining a map of interceptors -// and dispatching to impacted interceptor, is implemented in this -// base class, which both NamespaceDispatchInterceptor and -// DomainDispatchInterceptor extend. -// -public abstract class DispatchInterceptor -- * This API is a Sun internal API and is subject to changes without notice. - *
- * @since 1.7 - */ -// -// See comments in DispatchInterceptor. -// -class DomainDispatchInterceptor - extends DispatchInterceptor- * This API is a Sun internal API and is subject to changes without notice. - *
- * @since 1.7 - */ -public abstract class MBeanServerInterceptorSupport - implements MBeanServerInterceptor { - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - public Object instantiate(String className) - throws ReflectionException, MBeanException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - public Object instantiate(String className, ObjectName loaderName) - throws ReflectionException, MBeanException, - InstanceNotFoundException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - public Object instantiate(String className, Object[] params, - String[] signature) throws ReflectionException, MBeanException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - public Object instantiate(String className, ObjectName loaderName, - Object[] params, String[] signature) - throws ReflectionException, MBeanException, - InstanceNotFoundException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - @Deprecated - public ObjectInputStream deserialize(ObjectName name, byte[] data) - throws InstanceNotFoundException, OperationsException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - @Deprecated - public ObjectInputStream deserialize(String className, byte[] data) - throws OperationsException, ReflectionException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - @Deprecated - public ObjectInputStream deserialize(String className, - ObjectName loaderName, byte[] data) - throws InstanceNotFoundException, OperationsException, - ReflectionException { - throw new UnsupportedOperationException("Not applicable."); - } - - /** - * This method should never be called. - * Throws UnsupportedOperationException. - */ - public ClassLoaderRepository getClassLoaderRepository() { - throw new UnsupportedOperationException("Not applicable."); - } - -} diff --git a/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java b/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java deleted file mode 100644 index 5ab61f8933ac2dd65eb2a236a960e7aa2ed4c03d..0000000000000000000000000000000000000000 --- a/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package com.sun.jmx.interceptor; - -import com.sun.jmx.defaults.JmxProperties; -import com.sun.jmx.mbeanserver.MBeanInstantiator; -import com.sun.jmx.mbeanserver.Repository; -import com.sun.jmx.mbeanserver.Util; -import com.sun.jmx.namespace.NamespaceInterceptor; - -import java.util.Queue; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.management.MBeanServer; -import javax.management.MBeanServerDelegate; -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; - -/** - * A dispatcher that dispatches to NamespaceInterceptors. - *- * This API is a Sun internal API and is subject to changes without notice. - *
- * @since 1.7 - */ -public class NamespaceDispatchInterceptor - extends DispatchInterceptorDo not forget to call initialize(outer,delegate)
- * before using this object.
- *
- * @param outer A pointer to the MBeanServer object that must be
- * passed to the MBeans when invoking their
- * {@link javax.management.MBeanRegistration} interface.
- * @param delegate A pointer to the MBeanServerDelegate associated
- * with the new MBeanServer. The new MBeanServer must register
- * this MBean in its MBean repository.
- * @param instantiator The MBeanInstantiator that will be used to
- * instantiate MBeans and take care of class loading issues.
- * @param repository The repository to use for this MBeanServer
- */
- public NamespaceDispatchInterceptor(MBeanServer outer,
- MBeanServerDelegate delegate,
- MBeanInstantiator instantiator,
- Repository repository) {
- nextInterceptor = new DomainDispatchInterceptor(outer,delegate,
- instantiator,repository,this);
- serverName = Util.getMBeanServerSecurityName(delegate);
- }
-
- /**
- * Get first name space in ObjectName path. Ignore leading namespace
- * 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 getFirstNamespaceWithSlash(ObjectName name) { - if (name == null) return ""; - final String domain = name.getDomain(); - if (domain.equals("")) return ""; - - // go to next separator - 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(0,end+NAMESPACE_SEPARATOR_LENGTH); - - return namespace; - } - - /** - * Called by the DefaultMBeanServerInterceptor, just before adding an - * MBean to the repository. - * - * @param resource the MBean to be registered. - * @param logicalName the name of the MBean to be registered. - */ - final void checkLocallyRegistrable(Object resource, - ObjectName logicalName) { - if (!(resource instanceof JMXNamespace) && - logicalName.getDomain().contains(NAMESPACE_SEPARATOR)) - throw new IllegalArgumentException(String.valueOf(logicalName)+ - ": Invalid ObjectName for an instance of " + - resource.getClass().getName()); - } - - // 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 = 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; - } - - // 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: " + key); - } else { - LOG.finer("no handler for: " + key); - } - } - return ns; - } - - @Override - final QueryInterceptor getInterceptorForQuery(ObjectName pattern) { - 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); - } - - // 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: " + key); - } else { - LOG.finer("no handler for: " + key); - } - } - if (ns == null) return null; - return new QueryInterceptor(ns); - } - - @Override - final ObjectName getHandlerNameFor(String key) { - return ObjectName.valueOf(key+NAMESPACE_SEPARATOR, - "type", JMXNamespace.TYPE); - } - - @Override - final public String getHandlerKey(ObjectName name) { - final String namespace = getFirstNamespaceWithSlash(name); - // namespace is either "" or a namespace ending with // - return getKeyFor(namespace); - } - - @Override - final NamespaceInterceptor createInterceptorFor(String key, - ObjectName name, JMXNamespace handler, - Queue
An {@link MBeanServerForwarder} that simulates the existence of a - * given MBean. Requests for that MBean, call it X, are intercepted by the - * forwarder, and requests for any other MBean are forwarded to the next - * forwarder in the chain. Requests such as queryNames which can span both the - * X and other MBeans are handled by merging the results for X with the results - * from the next forwarder, unless the "visible" parameter is false, in which - * case X is invisible to such requests.
- */ -public class SingleMBeanForwarder extends IdentityMBeanServerForwarder { - - private final ObjectName mbeanName; - private final boolean visible; - private DynamicMBean mbean; - - private MBeanServer mbeanMBS = new MBeanServerSupport() { - - @Override - public DynamicMBean getDynamicMBeanFor(ObjectName name) - throws InstanceNotFoundException { - if (mbeanName.equals(name)) { - return mbean; - } else { - throw new InstanceNotFoundException(name.toString()); - } - } - - @Override - protected SetMake a DynamicMBean out of the existing MBean object. The object - * may already be a DynamicMBean, or it may be a Standard MBean or - * MXBean, possibly defined using {@code @MBean} or {@code @MXBean}.
- * @param mbean the object to convert to a DynamicMBean. - * @param