--- a/jdk/make/docs/CORE_PKGS.gmk Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/make/docs/CORE_PKGS.gmk Wed Oct 21 16:50:44 2009 +0100
@@ -160,10 +160,8 @@
javax.lang.model.type \
javax.lang.model.util \
javax.management \
- javax.management.event \
javax.management.loading \
javax.management.monitor \
- javax.management.namespace \
javax.management.relation \
javax.management.openmbean \
javax.management.timer \
--- a/jdk/src/share/classes/com/sun/jmx/defaults/JmxProperties.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/defaults/JmxProperties.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2007 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
@@ -177,18 +177,6 @@
"javax.management.relation";
/**
- * Logger name for Namespaces.
- */
- public static final String NAMESPACE_LOGGER_NAME =
- "javax.management.namespace";
-
- /**
- * Logger name for Namespaces.
- */
- public static final Logger NAMESPACE_LOGGER =
- Logger.getLogger(NAMESPACE_LOGGER_NAME);
-
- /**
* Logger for Relation Service.
*/
public static final Logger RELATION_LOGGER =
--- a/jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java Wed Oct 21 16:50:44 2009 +0100
@@ -69,9 +69,9 @@
/**
* The version of the JMX specification implemented by this product.
* <BR>
- * The value is <CODE>2.0</CODE>.
+ * The value is <CODE>1.4</CODE>.
*/
- 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.
--- a/jdk/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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");
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/EventBuffer.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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 ArrayList<TargetedNotification>());
- }
-
- public EventBuffer(int capacity, final List<TargetedNotification> list) {
- if (logger.traceOn()) {
- logger.trace("EventBuffer", "New buffer with the capacity: "
- +capacity);
- }
- if (capacity < 1) {
- throw new IllegalArgumentException(
- "The capacity must be bigger than 0");
- }
-
- if (list == null) {
- throw new NullPointerException("Null list.");
- }
-
- this.capacity = capacity;
- this.list = list;
- }
-
- public void add(TargetedNotification tn) {
- if (logger.traceOn()) {
- logger.trace("add", "Add one notif.");
- }
-
- synchronized(lock) {
- if (list.size() == capacity) { // have to throw one
- passed++;
- list.remove(0);
-
- if (logger.traceOn()) {
- logger.trace("add", "Over, remove the oldest one.");
- }
- }
-
- list.add(tn);
- lock.notify();
- }
- }
-
- public void add(TargetedNotification[] tns) {
- if (tns == null || tns.length == 0) {
- return;
- }
-
- if (logger.traceOn()) {
- logger.trace("add", "Add notifs: "+tns.length);
- }
-
- synchronized(lock) {
- final int d = list.size() - capacity + tns.length;
- if (d > 0) { // have to throw
- passed += d;
- if (logger.traceOn()) {
- logger.trace("add",
- "Over, remove the oldest: "+d);
- }
- if (tns.length <= capacity){
- list.subList(0, d).clear();
- } else {
- list.clear();
- TargetedNotification[] tmp =
- new TargetedNotification[capacity];
- System.arraycopy(tns, tns.length-capacity, tmp, 0, capacity);
- tns = tmp;
- }
- }
-
- Collections.addAll(list,tns);
- lock.notify();
- }
- }
-
- public NotificationResult fetchNotifications(long startSequenceNumber,
- long timeout,
- int maxNotifications) {
- if (logger.traceOn()) {
- logger.trace("fetchNotifications",
- "Being called: "
- +startSequenceNumber+" "
- +timeout+" "+maxNotifications);
- }
- if (startSequenceNumber < 0 ||
- timeout < 0 ||
- maxNotifications < 0) {
- throw new IllegalArgumentException("Negative value.");
- }
-
- TargetedNotification[] tns = new TargetedNotification[0];
- long earliest = startSequenceNumber < passed ?
- passed : startSequenceNumber;
- long next = earliest;
-
- final long startTime = System.currentTimeMillis();
- long toWait = timeout;
- synchronized(lock) {
- int toSkip = (int)(startSequenceNumber - passed);
-
- // skip those before startSequenceNumber.
- while (!closed && toSkip > 0) {
- toWait = timeout - (System.currentTimeMillis() - startTime);
- if (list.size() == 0) {
- if (toWait <= 0) {
- // the notification of startSequenceNumber
- // does not arrive yet.
- return new NotificationResult(startSequenceNumber,
- startSequenceNumber,
- new TargetedNotification[0]);
- }
-
- waiting(toWait);
- continue;
- }
-
- if (toSkip <= list.size()) {
- list.subList(0, toSkip).clear();
- passed += toSkip;
-
- break;
- } else {
- passed += list.size();
- toSkip -= list.size();
-
- list.clear();
- }
- }
-
- earliest = passed;
-
- if (list.size() == 0) {
- toWait = timeout - (System.currentTimeMillis() - startTime);
-
- waiting(toWait);
- }
-
- if (list.size() == 0) {
- tns = new TargetedNotification[0];
- } else if (list.size() <= maxNotifications) {
- tns = list.toArray(new TargetedNotification[0]);
- } else {
- tns = new TargetedNotification[maxNotifications];
- for (int i=0; i<maxNotifications; i++) {
- tns[i] = list.get(i);
- }
- }
-
- next = earliest + tns.length;
- }
-
- if (logger.traceOn()) {
- logger.trace("fetchNotifications",
- "Return: "+earliest+" "+next+" "+tns.length);
- }
-
- return new NotificationResult(earliest, next, tns);
- }
-
- public int size() {
- return list.size();
- }
-
- public void addLost(long nb) {
- synchronized(lock) {
- passed += nb;
- }
- }
-
- public void close() {
- if (logger.traceOn()) {
- logger.trace("clear", "done");
- }
-
- synchronized(lock) {
- list.clear();
- closed = true;
- lock.notifyAll();
- }
- }
-
-
- // -------------------------------------------
- // private classes
- // -------------------------------------------
- private void waiting(long timeout) {
- final long startTime = System.currentTimeMillis();
- long toWait = timeout;
- synchronized(lock) {
- while (!closed && list.size() == 0 && toWait > 0) {
- try {
- lock.wait(toWait);
-
- toWait = timeout - (System.currentTimeMillis() - startTime);
- } catch (InterruptedException ire) {
- logger.trace("waiting", ire);
- break;
- }
- }
- }
- }
-
- private final int capacity;
- private final List<TargetedNotification> list;
- private boolean closed;
-
- private long passed = 0;
- private final int[] lock = new int[0];
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "EventBuffer");
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/EventClientFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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 javax.management.event.*;
-
-/**
- * Implemented by objects which are using an {@link EventClient} to
- * subscribe for Notifications.
- *
- */
-public interface EventClientFactory {
- /**
- * Returns the {@code EventClient} that the object implementing this
- * interface uses to subscribe for Notifications. This method returns
- * {@code null} if no {@code EventClient} can be used - e.g. because
- * the underlying server does not have any {@link EventDelegate}.
- *
- * @return an {@code EventClient} or {@code null}.
- **/
- public EventClient getEventClient();
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/EventConnection.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright 2002-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 java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import javax.management.MBeanServerConnection;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventConsumer;
-import javax.management.event.NotificationManager;
-
-/**
- * Override the methods related to the notification to use the
- * Event service.
- */
-public interface EventConnection extends MBeanServerConnection, EventConsumer {
- public EventClient getEventClient();
-
- public static class Factory {
- public static EventConnection make(
- final MBeanServerConnection mbsc,
- final EventClient eventClient)
- throws IOException {
- if (!mbsc.isRegistered(EventClientDelegate.OBJECT_NAME)) {
- throw new IOException(
- "The server does not support the event service.");
- }
- InvocationHandler ih = new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- Class<?> intf = method.getDeclaringClass();
- try {
- if (intf.isInstance(eventClient))
- return method.invoke(eventClient, args);
- else
- return method.invoke(mbsc, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- };
- // It is important to declare NotificationManager.class first
- // in the array below, so that the relevant addNL and removeNL
- // methods will show up with method.getDeclaringClass() as
- // being from that interface and not MBeanServerConnection.
- return (EventConnection) Proxy.newProxyInstance(
- NotificationManager.class.getClassLoader(),
- new Class<?>[] {
- NotificationManager.class, EventConnection.class,
- },
- ih);
- }
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/EventParams.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +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.mbeanserver.GetPropertyAction;
-import com.sun.jmx.remote.util.ClassLogger;
-import java.security.AccessController;
-import javax.management.event.EventClient;
-
-/**
- *
- * @author sjiang
- */
-public class EventParams {
- public static final String DEFAULT_LEASE_TIMEOUT =
- "com.sun.event.lease.time";
-
-
- @SuppressWarnings("cast") // cast for jdk 1.5
- public static long getLeaseTimeout() {
- long timeout = EventClient.DEFAULT_REQUESTED_LEASE_TIME;
- try {
- final GetPropertyAction act =
- new GetPropertyAction(DEFAULT_LEASE_TIMEOUT);
- final String s = (String)AccessController.doPrivileged(act);
- if (s != null) {
- timeout = Long.parseLong(s);
- }
- } catch (RuntimeException e) {
- logger.fine("getLeaseTimeout", "exception getting property", e);
- }
-
- return timeout;
- }
-
- /** Creates a new instance of EventParams */
- private EventParams() {
- }
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "EventParams");
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +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.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-
-/**
- * <p>Manage 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.</p>
- * @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);
- }
-
- /**
- * <p>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.</p>
- *
- * <p>Calling this method after the lease has expired will return zero
- * immediately and have no other effect.</p>
- *
- * @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;
- }
-
- /**
- * <p>Cancel the lease without calling the expiry callback.</p>
- */
- 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");
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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, Callable<Long> doRenew) {
- if (logger.traceOn()) {
- logger.trace("LeaseRenewer", "New LeaseRenewer.");
- }
-
- if (doRenew == null) {
- throw new NullPointerException("Null job to call server.");
- }
-
- this.doRenew = doRenew;
- nextRenewTime = System.currentTimeMillis();
-
- this.scheduler = scheduler;
- future = this.scheduler.schedule(myRenew, 0, TimeUnit.MILLISECONDS);
- }
-
- public void close() {
- if (logger.traceOn()) {
- logger.trace("close", "Close the lease.");
- }
-
- synchronized(lock) {
- if (closed) {
- return;
- } else {
- closed = true;
- }
- }
-
- try {
- future.cancel(false); // not interrupt if running
- } catch (Exception e) {
- // OK
- if (logger.debugOn()) {
- logger.debug("close", "Failed to cancel the leasing job.", e);
- }
- }
- }
-
- public boolean closed() {
- synchronized(lock) {
- return closed;
- }
- }
-
- // ------------------------------
- // private
- // ------------------------------
- private final Runnable myRenew = new Runnable() {
- public void run() {
- synchronized(lock) {
- if (closed()) {
- return;
- }
- }
-
- long next = nextRenewTime - System.currentTimeMillis();
- if (next < MIN_MILLIS) {
- try {
- if (logger.traceOn()) {
- logger.trace("myRenew-run", "");
- }
- next = doRenew.call().longValue();
-
- } catch (Exception e) {
- logger.fine("myRenew-run", "Failed to renew lease", e);
- close();
- }
-
- if (next > 0 && next < Long.MAX_VALUE) {
- next = next/2;
- next = (next < MIN_MILLIS) ? MIN_MILLIS : next;
- } else {
- close();
- }
- }
-
- nextRenewTime = System.currentTimeMillis() + next;
-
- if (logger.traceOn()) {
- logger.trace("myRenew-run", "Next leasing: "+next);
- }
-
- synchronized(lock) {
- if (!closed) {
- future = scheduler.schedule(this, next, TimeUnit.MILLISECONDS);
- }
- }
- }
- };
-
- private final Callable<Long> doRenew;
- private ScheduledFuture<?> future;
- private boolean closed = false;
- private long nextRenewTime;
-
- private final int[] lock = new int[0];
-
- private final ScheduledExecutorService scheduler;
-
- private static final long MIN_MILLIS = 50;
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "LeaseRenewer");
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/ReceiverBuffer.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +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 ReceiverBuffer {
- public void addNotifs(NotificationResult nr) {
- if (nr == null) {
- return;
- }
-
- TargetedNotification[] tns = nr.getTargetedNotifications();
-
- if (logger.traceOn()) {
- logger.trace("addNotifs", "" + tns.length);
- }
-
- long impliedStart = nr.getEarliestSequenceNumber();
- final long missed = impliedStart - start;
- start = nr.getNextSequenceNumber();
-
- if (missed > 0) {
- if (logger.traceOn()) {
- logger.trace("addNotifs",
- "lost: "+missed);
- }
-
- lost += missed;
- }
-
- Collections.addAll(notifList, nr.getTargetedNotifications());
- }
-
- public TargetedNotification[] removeNotifs() {
- if (logger.traceOn()) {
- logger.trace("removeNotifs", String.valueOf(notifList.size()));
- }
-
- if (notifList.size() == 0) {
- return null;
- }
-
- TargetedNotification[] ret = notifList.toArray(
- new TargetedNotification[]{});
- notifList.clear();
-
- return ret;
- }
-
- public int size() {
- return notifList.size();
- }
-
- public int removeLost() {
- int ret = lost;
- lost = 0;
- return ret;
- }
-
- private List<TargetedNotification> notifList
- = new ArrayList<TargetedNotification>();
- private long start = 0;
- private int lost = 0;
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "ReceiverBuffer");
-}
--- a/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +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.Executor;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- * <p>A 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()}.</p>
- * @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");
-}
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Wed Oct 21 16:50:44 2009 +0100
@@ -30,16 +30,15 @@
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.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.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.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.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 @@
*
* @since 1.5
*/
-public class DefaultMBeanServerInterceptor
- extends MBeanServerInterceptorSupport {
+public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
/** The MBeanInstantiator object used by the
* DefaultMBeanServerInterceptor */
@@ -142,14 +135,9 @@
new WeakHashMap<ListenerWrapper,
WeakReference<ListenerWrapper>>();
- private final NamespaceDispatchInterceptor dispatcher;
-
/** The default domain of the object names */
private final String domain;
- /** The mbeanServerName */
- private final String mbeanServerName;
-
/** The sequence number identifying the notifications sent */
// Now sequence number is handled by MBeanServerDelegate.
// private int sequenceNumber=0;
@@ -168,13 +156,11 @@
* @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.
- * @param dispatcher The dispatcher used by this MBeanServer
*/
public DefaultMBeanServerInterceptor(MBeanServer outer,
MBeanServerDelegate delegate,
MBeanInstantiator instantiator,
- Repository repository,
- NamespaceDispatchInterceptor dispatcher) {
+ Repository repository) {
if (outer == null) throw new
IllegalArgumentException("outer MBeanServer cannot be null");
if (delegate == null) throw new
@@ -189,8 +175,6 @@
this.instantiator = instantiator;
this.repository = repository;
this.domain = repository.getDefaultDomain();
- this.dispatcher = dispatcher;
- this.mbeanServerName = Util.getMBeanServerSecurityName(delegate);
}
public ObjectInstance createMBean(String className, ObjectName name)
@@ -269,8 +253,8 @@
name = nonDefaultDomain(name);
}
- checkMBeanPermission(mbeanServerName,className, null, null, "instantiate");
- checkMBeanPermission(mbeanServerName,className, null, name, "registerMBean");
+ checkMBeanPermission(className, null, null, "instantiate");
+ checkMBeanPermission(className, null, name, "registerMBean");
/* Load the appropriate class. */
if (withDefaultLoaderRepository) {
@@ -334,7 +318,7 @@
final String infoClassName = getNewMBeanClassName(object);
- checkMBeanPermission(mbeanServerName,infoClassName, null, name, "registerMBean");
+ checkMBeanPermission(infoClassName, null, name, "registerMBean");
checkMBeanTrustPermission(theClass);
return registerObject(infoClassName, object, name);
@@ -443,8 +427,7 @@
DynamicMBean instance = getMBean(name);
// may throw InstanceNotFoundException
- checkMBeanPermission(mbeanServerName, instance, null, name,
- "unregisterMBean");
+ checkMBeanPermission(instance, null, name, "unregisterMBean");
if (instance instanceof MBeanRegistration)
preDeregisterInvoke((MBeanRegistration) instance);
@@ -478,8 +461,7 @@
name = nonDefaultDomain(name);
DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName,
- instance, null, name, "getObjectInstance");
+ checkMBeanPermission(instance, null, name, "getObjectInstance");
final String className = getClassName(instance);
@@ -491,7 +473,7 @@
if (sm != null) {
// Check if the caller has the right to invoke 'queryMBeans'
//
- checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryMBeans");
+ checkMBeanPermission((String) null, null, null, "queryMBeans");
// Perform query without "query".
//
@@ -504,7 +486,7 @@
new HashSet<ObjectInstance>(list.size());
for (ObjectInstance oi : list) {
try {
- checkMBeanPermission(mbeanServerName,oi.getClassName(), null,
+ checkMBeanPermission(oi.getClassName(), null,
oi.getObjectName(), "queryMBeans");
allowedList.add(oi);
} catch (SecurityException e) {
@@ -537,7 +519,7 @@
if (sm != null) {
// Check if the caller has the right to invoke 'queryNames'
//
- checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryNames");
+ checkMBeanPermission((String) null, null, null, "queryNames");
// Perform query without "query".
//
@@ -550,7 +532,7 @@
new HashSet<ObjectInstance>(list.size());
for (ObjectInstance oi : list) {
try {
- checkMBeanPermission(mbeanServerName, oi.getClassName(), null,
+ checkMBeanPermission(oi.getClassName(), null,
oi.getObjectName(), "queryNames");
allowedList.add(oi);
} catch (SecurityException e) {
@@ -602,7 +584,7 @@
if (sm != null) {
// Check if the caller has the right to invoke 'getDomains'
//
- checkMBeanPermission(mbeanServerName, (String) null, null, null, "getDomains");
+ checkMBeanPermission((String) null, null, null, "getDomains");
// Return domains
//
@@ -614,8 +596,8 @@
List<String> result = new ArrayList<String>(domains.length);
for (int i = 0; i < domains.length; i++) {
try {
- ObjectName dom = ObjectName.valueOf(domains[i] + ":x=x");
- checkMBeanPermission(mbeanServerName, (String) null, null, dom, "getDomains");
+ ObjectName dom = Util.newObjectName(domains[i] + ":x=x");
+ checkMBeanPermission((String) null, null, dom, "getDomains");
result.add(domains[i]);
} catch (SecurityException e) {
// OK: Do not add this domain to the list
@@ -659,8 +641,7 @@
}
final DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName, instance, attribute,
- name, "getAttribute");
+ checkMBeanPermission(instance, attribute, name, "getAttribute");
try {
return instance.getAttribute(attribute);
@@ -705,7 +686,7 @@
// Check if the caller has the right to invoke 'getAttribute'
//
- checkMBeanPermission(mbeanServerName, classname, null, name, "getAttribute");
+ checkMBeanPermission(classname, null, name, "getAttribute");
// Check if the caller has the right to invoke 'getAttribute'
// on each specific attribute
@@ -714,8 +695,7 @@
new ArrayList<String>(attributes.length);
for (String attr : attributes) {
try {
- checkMBeanPermission(mbeanServerName, classname, attr,
- name, "getAttribute");
+ checkMBeanPermission(classname, attr, name, "getAttribute");
allowedList.add(attr);
} catch (SecurityException e) {
// OK: Do not add this attribute to the list
@@ -760,8 +740,7 @@
}
DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName, instance, attribute.getName(),
- name, "setAttribute");
+ checkMBeanPermission(instance, attribute.getName(), name, "setAttribute");
try {
instance.setAttribute(attribute);
@@ -803,7 +782,7 @@
// Check if the caller has the right to invoke 'setAttribute'
//
- checkMBeanPermission(mbeanServerName, classname, null, name, "setAttribute");
+ checkMBeanPermission(classname, null, name, "setAttribute");
// Check if the caller has the right to invoke 'setAttribute'
// on each specific attribute
@@ -811,7 +790,7 @@
allowedAttributes = new AttributeList(attributes.size());
for (Attribute attribute : attributes.asList()) {
try {
- checkMBeanPermission(mbeanServerName, classname, attribute.getName(),
+ checkMBeanPermission(classname, attribute.getName(),
name, "setAttribute");
allowedAttributes.add(attribute);
} catch (SecurityException e) {
@@ -835,8 +814,7 @@
name = nonDefaultDomain(name);
DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName, instance, operationName,
- name, "invoke");
+ checkMBeanPermission(instance, operationName, name, "invoke");
try {
return instance.invoke(operationName, params, signature);
} catch (Throwable t) {
@@ -919,12 +897,6 @@
DynamicMBean mbean = Introspector.makeDynamicMBean(object);
- //Access the ObjectName template value only if the provided name is null
- if(name == null) {
- name = Introspector.templateToObjectName(mbean.getMBeanInfo().
- getDescriptor(), mbean);
- }
-
return registerDynamicMBean(classname, mbean, name);
}
@@ -953,8 +925,6 @@
ResourceContext context = null;
try {
- mbean = injectResources(mbean, server, logicalName);
-
if (mbean instanceof DynamicMBean2) {
try {
((DynamicMBean2) mbean).preRegister2(server, logicalName);
@@ -973,8 +943,7 @@
ObjectName.getInstance(nonDefaultDomain(logicalName));
}
- checkMBeanPermission(mbeanServerName, classname, null, logicalName,
- "registerMBean");
+ checkMBeanPermission(classname, null, logicalName, "registerMBean");
if (logicalName == null) {
final RuntimeException wrapped =
@@ -988,10 +957,9 @@
// Register the MBean with the repository.
// Returns the resource context that was used.
// The returned context does nothing for regular MBeans.
- // For ClassLoader MBeans and JMXNamespace (and JMXDomain)
- // MBeans - the context makes it possible to register these
+ // For ClassLoader MBeans the context makes it possible to register these
// objects with the appropriate framework artifacts, such as
- // the CLR or the dispatcher, from within the repository lock.
+ // the CLR, from within the repository lock.
// In case of success, we also need to call context.done() at the
// end of this method.
//
@@ -1045,27 +1013,6 @@
else return name;
}
- private static DynamicMBean injectResources(
- DynamicMBean mbean, MBeanServer mbs, ObjectName name)
- throws MBeanRegistrationException {
- try {
- Object resource = getResource(mbean);
- MBeanInjector.inject(resource, mbs, name);
- if (MBeanInjector.injectsSendNotification(resource)) {
- MBeanNotificationInfo[] mbnis =
- mbean.getMBeanInfo().getNotifications();
- NotificationBroadcasterSupport nbs =
- new NotificationBroadcasterSupport(mbnis);
- MBeanInjector.injectSendNotification(resource, nbs);
- mbean = NotifySupport.wrap(mbean, nbs);
- }
- return mbean;
- } catch (Throwable t) {
- throwMBeanRegistrationException(t, "injecting @Resources");
- return null; // not reached
- }
- }
-
private static void postRegister(
ObjectName logicalName, DynamicMBean mbean,
boolean registrationDone, boolean registerFailed) {
@@ -1151,19 +1098,12 @@
}
private static Object getResource(DynamicMBean mbean) {
- if (mbean instanceof DynamicWrapperMBean)
- return ((DynamicWrapperMBean) mbean).getWrappedObject();
+ if (mbean instanceof DynamicMBean2)
+ return ((DynamicMBean2) mbean).getResource();
else
return mbean;
}
- private static ClassLoader getResourceLoader(DynamicMBean mbean) {
- if (mbean instanceof DynamicWrapperMBean)
- return ((DynamicWrapperMBean) mbean).getWrappedClassLoader();
- else
- return mbean.getClass().getClassLoader();
- }
-
private ObjectName nonDefaultDomain(ObjectName name) {
if (name == null || name.getDomain().length() > 0)
return name;
@@ -1177,7 +1117,7 @@
if one is supplied where it shouldn't be). */
final String completeName = domain + name;
- return ObjectName.valueOf(completeName);
+ return Util.newObjectName(completeName);
}
public String getDefaultDomain() {
@@ -1243,8 +1183,7 @@
}
DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName, instance, null,
- name, "addNotificationListener");
+ checkMBeanPermission(instance, null, name, "addNotificationListener");
NotificationBroadcaster broadcaster =
getNotificationBroadcaster(name, instance,
@@ -1381,8 +1320,7 @@
}
DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName, instance, null, name,
- "removeNotificationListener");
+ checkMBeanPermission(instance, null, name, "removeNotificationListener");
/* We could simplify the code by assigning broadcaster after
assigning listenerWrapper, but that would change the error
@@ -1415,8 +1353,8 @@
Class<T> reqClass) {
if (reqClass.isInstance(instance))
return reqClass.cast(instance);
- if (instance instanceof DynamicWrapperMBean)
- instance = ((DynamicWrapperMBean) instance).getWrappedObject();
+ if (instance instanceof DynamicMBean2)
+ instance = ((DynamicMBean2) instance).getResource();
if (reqClass.isInstance(instance))
return reqClass.cast(instance);
final RuntimeException exc =
@@ -1452,7 +1390,7 @@
throw new JMRuntimeException("MBean " + name +
"has no MBeanInfo");
- checkMBeanPermission(mbeanServerName, mbi.getClassName(), null, name, "getMBeanInfo");
+ checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo");
return mbi;
}
@@ -1461,8 +1399,7 @@
throws InstanceNotFoundException {
final DynamicMBean instance = getMBean(name);
- checkMBeanPermission(mbeanServerName,
- instance, null, name, "isInstanceOf");
+ checkMBeanPermission(instance, null, name, "isInstanceOf");
try {
Object resource = getResource(instance);
@@ -1474,20 +1411,12 @@
if (resourceClassName.equals(className))
return true;
- final ClassLoader cl = getResourceLoader(instance);
+ final ClassLoader cl = resource.getClass().getClassLoader();
final Class<?> classNameClass = Class.forName(className, false, cl);
if (classNameClass.isInstance(resource))
return true;
- // Ensure that isInstanceOf(NotificationEmitter) is true when
- // the MBean is a NotificationEmitter by virtue of a @Resource
- // annotation specifying a SendNotification resource.
- // This is a hack.
- if (instance instanceof NotificationBroadcaster &&
- classNameClass.isAssignableFrom(NotificationEmitter.class))
- return true;
-
final Class<?> resourceClass = Class.forName(resourceClassName, false, cl);
return classNameClass.isAssignableFrom(resourceClass);
} catch (Exception x) {
@@ -1513,9 +1442,8 @@
throws InstanceNotFoundException {
DynamicMBean instance = getMBean(mbeanName);
- checkMBeanPermission(mbeanServerName, instance, null, mbeanName,
- "getClassLoaderFor");
- return getResourceLoader(instance);
+ checkMBeanPermission(instance, null, mbeanName, "getClassLoaderFor");
+ return getResource(instance).getClass().getClassLoader();
}
/**
@@ -1529,13 +1457,12 @@
throws InstanceNotFoundException {
if (loaderName == null) {
- checkMBeanPermission(mbeanServerName, (String) null, null, null, "getClassLoader");
+ checkMBeanPermission((String) null, null, null, "getClassLoader");
return server.getClass().getClassLoader();
}
DynamicMBean instance = getMBean(loaderName);
- checkMBeanPermission(mbeanServerName, instance, null, loaderName,
- "getClassLoader");
+ checkMBeanPermission(instance, null, loaderName, "getClassLoader");
Object resource = getResource(instance);
@@ -1757,6 +1684,49 @@
}
}
+ public Object instantiate(String className) throws ReflectionException,
+ MBeanException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Object instantiate(String className, ObjectName loaderName) throws ReflectionException,
+ MBeanException,
+ InstanceNotFoundException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Object instantiate(String className, Object[] params,
+ String[] signature) throws ReflectionException, MBeanException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Object instantiate(String className, ObjectName loaderName,
+ Object[] params, String[] signature) throws ReflectionException,
+ MBeanException,
+ InstanceNotFoundException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public ObjectInputStream deserialize(ObjectName name, byte[] data) throws InstanceNotFoundException,
+ OperationsException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public ObjectInputStream deserialize(String className, byte[] data) throws OperationsException,
+ ReflectionException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public ObjectInputStream deserialize(String className, ObjectName loaderName,
+ byte[] data) throws InstanceNotFoundException, OperationsException,
+ ReflectionException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public ClassLoaderRepository getClassLoaderRepository() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
private static class ListenerWrapper implements NotificationListener {
ListenerWrapper(NotificationListener l, ObjectName name,
Object mbean) {
@@ -1834,30 +1804,26 @@
return mbean.getMBeanInfo().getClassName();
}
- private static void checkMBeanPermission(String mbeanServerName,
- DynamicMBean mbean,
+ private static void checkMBeanPermission(DynamicMBean mbean,
String member,
ObjectName objectName,
String actions) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- checkMBeanPermission(mbeanServerName,
- safeGetClassName(mbean),
+ checkMBeanPermission(safeGetClassName(mbean),
member,
objectName,
actions);
}
}
- private static void checkMBeanPermission(String mbeanServerName,
- String classname,
+ private static void checkMBeanPermission(String classname,
String member,
ObjectName objectName,
String actions) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- Permission perm = new MBeanPermission(mbeanServerName,
- classname,
+ Permission perm = new MBeanPermission(classname,
member,
objectName,
actions);
@@ -1923,12 +1889,6 @@
throws InstanceAlreadyExistsException,
MBeanRegistrationException {
- // this will throw an exception if the pair (resource, logicalName)
- // violates namespace conventions - for instance, if logicalName
- // ends with // but resource is not a JMXNamespace.
- //
- checkResourceObjectNameConstraints(resource, logicalName);
-
// Creates a registration context, if needed.
//
final ResourceContext context =
@@ -1996,56 +1956,6 @@
/**
- * Checks that the ObjectName is legal with regards to the
- * type of the MBean resource.
- * If the MBean name is domain:type=JMXDomain, the
- * MBean must be a JMXDomain.
- * If the MBean name is namespace//:type=JMXNamespace, the
- * MBean must be a JMXNamespace.
- * If the MBean is a JMXDomain, its name
- * must be domain:type=JMXDomain.
- * If the MBean is a JMXNamespace, its name
- * must be namespace//:type=JMXNamespace.
- */
- private void checkResourceObjectNameConstraints(Object resource,
- ObjectName logicalName)
- throws MBeanRegistrationException {
- try {
- dispatcher.checkLocallyRegistrable(resource, logicalName);
- } catch (Throwable x) {
- DefaultMBeanServerInterceptor.throwMBeanRegistrationException(x, "validating ObjectName");
- }
- }
-
- /**
- * Registers a JMXNamespace with the dispatcher.
- * This method is called by the ResourceContext from within the
- * repository lock.
- * @param namespace The JMXNamespace
- * @param logicalName The JMXNamespaceMBean ObjectName
- * @param postQueue A queue that will be processed after postRegister.
- */
- private void addJMXNamespace(JMXNamespace namespace,
- final ObjectName logicalName,
- final Queue<Runnable> postQueue) {
- dispatcher.addInterceptorFor(logicalName, namespace, postQueue);
- }
-
- /**
- * Unregisters a JMXNamespace from the dispatcher.
- * This method is called by the ResourceContext from within the
- * repository lock.
- * @param namespace The JMXNamespace
- * @param logicalName The JMXNamespaceMBean ObjectName
- * @param postQueue A queue that will be processed after postDeregister.
- */
- private void removeJMXNamespace(JMXNamespace namespace,
- final ObjectName logicalName,
- final Queue<Runnable> postQueue) {
- dispatcher.removeInterceptorFor(logicalName, namespace, postQueue);
- }
-
- /**
* Registers a ClassLoader with the CLR.
* This method is called by the ResourceContext from within the
* repository lock.
@@ -2100,51 +2010,6 @@
/**
- * Creates a ResourceContext for a JMXNamespace MBean.
- * The resource context makes it possible to add the JMXNamespace to
- * (ResourceContext.registering) or resp. remove the JMXNamespace from
- * (ResourceContext.unregistered) the NamespaceDispatchInterceptor
- * when the associated MBean is added to or resp. removed from the
- * repository.
- * Note: JMXDomains are special sub classes of JMXNamespaces and
- * are also handled by this object.
- *
- * @param namespace The JMXNamespace MBean being registered or
- * unregistered.
- * @param logicalName The name of the JMXNamespace MBean.
- * @return a ResourceContext that takes in charge the addition or removal
- * of the namespace to or from the NamespaceDispatchInterceptor.
- */
- private ResourceContext createJMXNamespaceContext(
- final JMXNamespace namespace,
- final ObjectName logicalName) {
- final Queue<Runnable> doneTaskQueue = new LinkedList<Runnable>();
- return new ResourceContext() {
-
- public void registering() {
- addJMXNamespace(namespace, logicalName, doneTaskQueue);
- }
-
- public void unregistered() {
- removeJMXNamespace(namespace, logicalName,
- doneTaskQueue);
- }
-
- public void done() {
- for (Runnable r : doneTaskQueue) {
- try {
- r.run();
- } catch (RuntimeException x) {
- MBEANSERVER_LOGGER.log(Level.FINE,
- "Failed to process post queue for "+
- logicalName, x);
- }
- }
- }
- };
- }
-
- /**
* Creates a ResourceContext for a ClassLoader MBean.
* The resource context makes it possible to add the ClassLoader to
* (ResourceContext.registering) or resp. remove the ClassLoader from
@@ -2180,8 +2045,7 @@
* Creates a ResourceContext for the given resource.
* If the resource does not need a ResourceContext, returns
* ResourceContext.NONE.
- * At this time, only JMXNamespaces and ClassLoaders need a
- * ResourceContext.
+ * At this time, only ClassLoaders need a ResourceContext.
*
* @param resource The resource being registered or unregistered.
* @param logicalName The name of the associated MBean.
@@ -2189,10 +2053,6 @@
*/
private ResourceContext makeResourceContextFor(Object resource,
ObjectName logicalName) {
- if (resource instanceof JMXNamespace) {
- return createJMXNamespaceContext((JMXNamespace) resource,
- logicalName);
- }
if (resource instanceof ClassLoader) {
return createClassLoaderContext((ClassLoader) resource,
logicalName);
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,551 +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 java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.namespace.JMXNamespace;
-
-/**
- * A dispatcher that dispatches to MBeanServers.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @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
- <T extends MBeanServer, N extends JMXNamespace>
- extends MBeanServerInterceptorSupport {
-
- /**
- * This is an abstraction which allows us to handle queryNames
- * and queryMBeans with the same algorithm. There are some subclasses
- * where we need to override both queryNames & queryMBeans to apply
- * the same transformation (usually aggregation of results when
- * several namespaces/domains are impacted) to both algorithms.
- * Usually the only thing that varies between the algorithm of
- * queryNames & the algorithm of queryMBean is the type of objects
- * in the returned Set. By using a QueryInvoker we can implement the
- * transformation only once and apply it to both queryNames &
- * queryMBeans.
- * @see QueryInterceptor below, and its subclass in
- * {@link DomainDispatcher}.
- **/
- static abstract class QueryInvoker<T> {
- abstract Set<T> query(MBeanServer mbs,
- ObjectName pattern, QueryExp query);
- }
-
- /**
- * Used to perform queryNames. A QueryInvoker that invokes
- * queryNames on an MBeanServer.
- **/
- final static QueryInvoker<ObjectName> queryNamesInvoker =
- new QueryInvoker<ObjectName>() {
- Set<ObjectName> query(MBeanServer mbs,
- ObjectName pattern, QueryExp query) {
- return mbs.queryNames(pattern,query);
- }
- };
-
- /**
- * Used to perform queryMBeans. A QueryInvoker that invokes
- * queryMBeans on an MBeanServer.
- **/
- final static QueryInvoker<ObjectInstance> queryMBeansInvoker =
- new QueryInvoker<ObjectInstance>() {
- Set<ObjectInstance> query(MBeanServer mbs,
- ObjectName pattern, QueryExp query) {
- return mbs.queryMBeans(pattern,query);
- }
- };
-
- /**
- * We use this class to intercept queries.
- * There's a special case for JMXNamespace MBeans, because
- * "namespace//*:*" matches both "namespace//domain:k=v" and
- * "namespace//:type=JMXNamespace".
- * Therefore, queries may need to be forwarded to more than
- * on interceptor and the results aggregated...
- */
- static class QueryInterceptor {
- final MBeanServer wrapped;
- QueryInterceptor(MBeanServer mbs) {
- wrapped = mbs;
- }
- <X> Set<X> query(ObjectName pattern, QueryExp query,
- QueryInvoker<X> invoker, MBeanServer server) {
- return invoker.query(server, pattern, query);
- }
-
- public Set<ObjectName> queryNames(ObjectName pattern, QueryExp query) {
- return query(pattern,query,queryNamesInvoker,wrapped);
- }
-
- public Set<ObjectInstance> queryMBeans(ObjectName pattern,
- QueryExp query) {
- return query(pattern,query,queryMBeansInvoker,wrapped);
- }
- }
-
- // We don't need a ConcurrentHashMap here because getkeys() returns
- // an array of keys. Therefore there's no risk to have a
- // ConcurrentModificationException. We must however take into
- // account the fact that there can be no interceptor for
- // some of the returned keys if the map is being modified by
- // another thread, or by a callback within the same thread...
- // See getKeys() in this class and query() in DomainDispatcher.
- //
- private final Map<String,T> handlerMap =
- Collections.synchronizedMap(
- new HashMap<String,T>());
-
- // The key at which an interceptor for accessing the named MBean can be
- // found in the handlerMap. Note: there doesn't need to be an interceptor
- // for that key in the Map.
- //
- abstract String getHandlerKey(ObjectName name);
-
- // Returns an interceptor for that name, or null if there's no interceptor
- // for that name.
- abstract MBeanServer getInterceptorOrNullFor(ObjectName name);
-
- // Returns a QueryInterceptor for that pattern.
- abstract QueryInterceptor getInterceptorForQuery(ObjectName pattern);
-
- // Returns the ObjectName of the JMXNamespace (or JMXDomain) for that
- // key (a namespace or a domain name).
- abstract ObjectName getHandlerNameFor(String key);
-
- // Creates an interceptor for the given key, name, JMXNamespace (or
- // JMXDomain). Note: this will be either a NamespaceInterceptor
- // wrapping a JMXNamespace, if this object is an instance of
- // NamespaceDispatchInterceptor, or a DomainInterceptor wrapping a
- // JMXDomain, if this object is an instance of DomainDispatchInterceptor.
- abstract T createInterceptorFor(String key, ObjectName name,
- N jmxNamespace, Queue<Runnable> postRegisterQueue);
- //
- // The next interceptor in the chain.
- //
- // For the NamespaceDispatchInterceptor, this the DomainDispatchInterceptor.
- // For the DomainDispatchInterceptor, this is the
- // DefaultMBeanServerInterceptor.
- //
- // The logic of when to invoke the next interceptor in the chain depends
- // on the logic of the concrete dispatcher class.
- //
- // For instance, the NamespaceDispatchInterceptor invokes the next
- // interceptor when the object name doesn't contain any namespace.
- //
- // On the other hand, the DomainDispatchInterceptor invokes the
- // next interceptor when there's no interceptor for the accessed domain.
- //
- abstract MBeanServer getNextInterceptor();
-
- // hook for cleanup in subclasses.
- void interceptorReleased(T interceptor,
- Queue<Runnable> postDeregisterQueue) {
- // hook
- }
-
- // Hook for subclasses.
- MBeanServer getInterceptorForCreate(ObjectName name)
- throws MBeanRegistrationException {
- final MBeanServer ns = getInterceptorOrNullFor(name);
- if (ns == null) // name cannot be null here.
- throw new MBeanRegistrationException(
- new IllegalArgumentException("No such MBean handler: " +
- getHandlerKey(name) + " for " +name));
- return ns;
- }
-
- // Hook for subclasses.
- MBeanServer getInterceptorForInstance(ObjectName name)
- throws InstanceNotFoundException {
- final MBeanServer ns = getInterceptorOrNullFor(name);
- if (ns == null) // name cannot be null here.
- throw new InstanceNotFoundException(String.valueOf(name));
- return ns;
- }
-
- // sanity checks
- void validateHandlerNameFor(String key, ObjectName name) {
- if (key == null || key.equals(""))
- throw new IllegalArgumentException("invalid key for "+name+": "+key);
- 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
- // of JMXNamespace (or a subclass of it) is registered as an MBean.
- // This method is usually invoked from within the repository lock,
- // hence the necessity of the postRegisterQueue.
- public void addInterceptorFor(ObjectName name, N jmxNamespace,
- Queue<Runnable> postRegisterQueue) {
- final String key = getHandlerKey(name);
- validateHandlerNameFor(key,name);
- synchronized (handlerMap) {
- final T exists =
- handlerMap.get(key);
- if (exists != null)
- throw new IllegalArgumentException(key+
- ": handler already exists");
-
- final T ns = createInterceptorFor(key,name,jmxNamespace,
- postRegisterQueue);
- handlerMap.put(key,ns);
- }
- }
-
- // Called by the DefaultMBeanServerInterceptor when an instance
- // of JMXNamespace (or a subclass of it) is deregistered.
- // This method is usually invoked from within the repository lock,
- // hence the necessity of the postDeregisterQueue.
- public void removeInterceptorFor(ObjectName name, N jmxNamespace,
- Queue<Runnable> postDeregisterQueue) {
- final String key = getHandlerKey(name);
- final T ns;
- synchronized(handlerMap) {
- ns = handlerMap.remove(key);
- }
- interceptorReleased(ns,postDeregisterQueue);
- }
-
- // Get the interceptor for that key.
- T getInterceptor(String key) {
- synchronized (handlerMap) {
- return handlerMap.get(key);
- }
- }
-
- // We return an array of keys, which makes it possible to make
- // concurrent modifications of the handlerMap, provided that
- // the code which loops over the keys is prepared to handle null
- // interceptors.
- // See declaration of handlerMap above, and see also query() in
- // DomainDispatcher
- //
- public String[] getKeys() {
- synchronized (handlerMap) {
- final int size = handlerMap.size();
- return handlerMap.keySet().toArray(new String[size]);
- }
- }
-
- // From MBeanServer
- public final ObjectInstance createMBean(String className, ObjectName name)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- return getInterceptorForCreate(name).createMBean(className,name);
- }
-
- // From MBeanServer
- public final ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException{
- return getInterceptorForCreate(name).createMBean(className,name,loaderName);
- }
-
- // From MBeanServer
- public final ObjectInstance createMBean(String className, ObjectName name,
- Object params[], String signature[])
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException{
- return getInterceptorForCreate(name).
- createMBean(className,name,params,signature);
- }
-
- // From MBeanServer
- public final ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName, Object params[],
- String signature[])
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException{
- return getInterceptorForCreate(name).createMBean(className,name,loaderName,
- params,signature);
- }
-
- // From MBeanServer
- public final ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException, MBeanRegistrationException,
- NotCompliantMBeanException {
- return getInterceptorForCreate(name).registerMBean(object,name);
- }
-
- // From MBeanServer
- public final void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException {
- getInterceptorForInstance(name).unregisterMBean(name);
- }
-
- // From MBeanServer
- public final ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- return getInterceptorForInstance(name).getObjectInstance(name);
- }
-
- // From MBeanServer
- public final Set<ObjectInstance> queryMBeans(ObjectName name,
- QueryExp query) {
- final QueryInterceptor queryInvoker =
- getInterceptorForQuery(name);
- if (queryInvoker == null) return Collections.emptySet();
- else return queryInvoker.queryMBeans(name,query);
- }
-
- // From MBeanServer
- public final Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- final QueryInterceptor queryInvoker =
- getInterceptorForQuery(name);
- if (queryInvoker == null) return Collections.emptySet();
- else return queryInvoker.queryNames(name,query);
- }
-
- // From MBeanServer
- public final boolean isRegistered(ObjectName name) {
- final MBeanServer mbs = getInterceptorOrNullFor(name);
- if (mbs == null) return false;
- else return mbs.isRegistered(name);
- }
-
- // From MBeanServer
- public Integer getMBeanCount() {
- return getNextInterceptor().getMBeanCount();
- }
-
- // From MBeanServer
- public final Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException,
- InstanceNotFoundException, ReflectionException {
- return getInterceptorForInstance(name).getAttribute(name,attribute);
- }
-
- // From MBeanServer
- public final AttributeList getAttributes(ObjectName name,
- String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- return getInterceptorForInstance(name).getAttributes(name,attributes);
- }
-
- // From MBeanServer
- public final void setAttribute(ObjectName name, Attribute attribute)
- throws InstanceNotFoundException, AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- getInterceptorForInstance(name).setAttribute(name,attribute);
- }
-
- // From MBeanServer
- public final AttributeList setAttributes(ObjectName name,
- AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- return getInterceptorForInstance(name).setAttributes(name,attributes);
- }
-
- // From MBeanServer
- public final Object invoke(ObjectName name, String operationName,
- Object params[], String signature[])
- throws InstanceNotFoundException, MBeanException,
- ReflectionException {
- return getInterceptorForInstance(name).invoke(name,operationName,params,
- signature);
- }
-
- // From MBeanServer
- public String getDefaultDomain() {
- return getNextInterceptor().getDefaultDomain();
- }
-
- /**
- * Returns the list of domains in which any MBean is currently
- * registered.
- */
- public abstract String[] getDomains();
-
- // From MBeanServer
- public final void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- getInterceptorForInstance(name).
- addNotificationListener(name,listener,filter,
- handback);
- }
-
-
- // From MBeanServer
- public final void addNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- getInterceptorForInstance(name).
- addNotificationListener(name,listener,filter,
- handback);
- }
-
- // From MBeanServer
- public final void removeNotificationListener(ObjectName name,
- ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- getInterceptorForInstance(name).
- removeNotificationListener(name,listener);
- }
-
- // From MBeanServer
- public final void removeNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- getInterceptorForInstance(name).
- removeNotificationListener(name,listener,filter,
- handback);
- }
-
-
- // From MBeanServer
- public final void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- getInterceptorForInstance(name).
- removeNotificationListener(name,listener);
- }
-
- // From MBeanServer
- public final void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- getInterceptorForInstance(name).
- removeNotificationListener(name,listener,filter,
- handback);
- }
-
- // From MBeanServer
- public final MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, IntrospectionException,
- ReflectionException {
- return getInterceptorForInstance(name).getMBeanInfo(name);
- }
-
-
- // From MBeanServer
- public final boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- return getInterceptorForInstance(name).isInstanceOf(name,className);
- }
-
- // From MBeanServer
- public final ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- return getInterceptorForInstance(mbeanName).
- getClassLoaderFor(mbeanName);
- }
-
- // From MBeanServer
- public final ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- return getInterceptorForInstance(loaderName).
- getClassLoader(loaderName);
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,350 +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.DomainInterceptor;
-import java.util.Queue;
-import java.util.Set;
-
-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.QueryExp;
-import javax.management.namespace.JMXDomain;
-import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
-
-/**
- * A dispatcher that dispatch incoming MBeanServer requests to
- * DomainInterceptors.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-//
-// See comments in DispatchInterceptor.
-//
-class DomainDispatchInterceptor
- extends DispatchInterceptor<DomainInterceptor, JMXDomain> {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- private static final ObjectName ALL_DOMAINS =
- JMXDomain.getDomainObjectName("*");
-
-
- /**
- * A QueryInterceptor that perform & aggregates queries spanning several
- * domains.
- */
- final static class AggregatingQueryInterceptor extends QueryInterceptor {
-
- private final DomainDispatchInterceptor parent;
- AggregatingQueryInterceptor(DomainDispatchInterceptor dispatcher) {
- super(dispatcher.nextInterceptor);
- parent = dispatcher;
- }
-
- /**
- * Perform queryNames or queryMBeans, depending on which QueryInvoker
- * is passed as argument. This is closures without closures.
- **/
- @Override
- <T> Set<T> query(ObjectName pattern, QueryExp query,
- QueryInvoker<T> invoker, MBeanServer localNamespace) {
- final Set<T> local = invoker.query(localNamespace, pattern, query);
-
- // Add all matching MBeans from local namespace.
- final Set<T> res = Util.cloneSet(local);
-
- if (pattern == null) pattern = ObjectName.WILDCARD;
- final boolean all = pattern.getDomain().equals("*");
-
- final String domain = pattern.getDomain();
-
- // If there's no domain pattern, just include the pattern's domain.
- // Otherwiae, loop over all virtual domains (parent.getKeys()).
- final String[] keys =
- (pattern.isDomainPattern() ?
- parent.getKeys() : new String[]{domain});
-
- // Add all matching MBeans from each virtual domain
- //
- for (String key : keys) {
- // Only invoke those virtual domain which are selected
- // by the domain pattern
- //
- if (!all && !Util.isDomainSelected(key, domain))
- continue;
-
- try {
- final MBeanServer mbs = parent.getInterceptor(key);
-
- // mbs can be null if the interceptor was removed
- // concurrently...
- // See handlerMap and getKeys() in DispatchInterceptor
- //
- if (mbs == null) continue;
-
- // If the domain is selected, we can replace the pattern
- // by the actual domain. This is safer if we want to avoid
- // a domain (which could be backed up by an MBeanServer) to
- // return names from outside the domain.
- // So instead of asking the domain handler for "foo" to
- // return all names which match "?o*:type=Bla,*" we're
- // going to ask it to return all names which match
- // "foo:type=Bla,*"
- //
- final ObjectName subPattern = pattern.withDomain(key);
- res.addAll(invoker.query(mbs, subPattern, query));
- } catch (Exception x) {
- LOG.finest("Ignoring exception " +
- "when attempting to query namespace "+key+": "+x);
- continue;
- }
- }
- return res;
- }
- }
-
- private final DefaultMBeanServerInterceptor nextInterceptor;
- private final String mbeanServerName;
- private final MBeanServerDelegate delegate;
-
- /**
- * Creates a DomainDispatchInterceptor with the specified
- * repository instance.
- *
- * @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 DomainDispatchInterceptor(MBeanServer outer,
- MBeanServerDelegate delegate,
- MBeanInstantiator instantiator,
- Repository repository,
- NamespaceDispatchInterceptor namespaces) {
- nextInterceptor = new DefaultMBeanServerInterceptor(outer,
- delegate, instantiator,repository,namespaces);
- mbeanServerName = Util.getMBeanServerSecurityName(delegate);
- this.delegate = delegate;
- }
-
- final boolean isLocalHandlerNameFor(String domain,
- ObjectName handlerName) {
- if (domain == null) return true;
- return handlerName.getDomain().equals(domain) &&
- JMXDomain.TYPE_ASSIGNMENT.equals(
- handlerName.getKeyPropertyListString());
- }
-
- @Override
- void validateHandlerNameFor(String key, ObjectName name) {
- super.validateHandlerNameFor(key,name);
- final String[] domains = nextInterceptor.getDomains();
- for (int i=0;i<domains.length;i++) {
- if (domains[i].equals(key))
- throw new IllegalArgumentException("domain "+key+
- " is not empty");
- }
- }
-
- @Override
- final MBeanServer getInterceptorOrNullFor(ObjectName name) {
-
- if (name == null) return nextInterceptor;
-
- final String domain = name.getDomain();
- if (domain.endsWith(NAMESPACE_SEPARATOR))
- return nextInterceptor; // This can be a namespace handler.
- if (domain.contains(NAMESPACE_SEPARATOR))
- return null; // shouldn't reach here.
- if (isLocalHandlerNameFor(domain,name)) {
- // This is the name of a JMXDomain MBean. Return nextInterceptor.
- LOG.finer("dispatching to local namespace");
- return nextInterceptor;
- }
-
- final DomainInterceptor ns = getInterceptor(domain);
- if (ns == null) {
- // no JMXDomain found for that domain - return nextInterceptor.
- if (LOG.isLoggable(Level.FINER)) {
- LOG.finer("dispatching to local namespace: " + domain);
- }
- return getNextInterceptor();
- }
-
- if (LOG.isLoggable(Level.FINER)) {
- LOG.finer("dispatching to domain: " + domain);
- }
- return ns;
- }
-
- // This method returns true if the given pattern must be evaluated against
- // several interceptors. This happens when either:
- //
- // a) the pattern can select several domains (it's null, or it's a
- // domain pattern)
- // or b) it's not a domain pattern, but it might select the name of a
- // JMXDomain MBean in charge of that domain. Since the JMXDomain
- // MBean is located in the nextInterceptor, the pattern might need
- // to be evaluated on two interceptors.
- //
- // 1. When this method returns false, the query is evaluated on a single
- // interceptor:
- // The interceptor for pattern.getDomain(), if there is one,
- // or the next interceptor, if there is none.
- //
- // 2. When this method returns true, we loop over all the domain
- // interceptors:
- // in the list, and if the domain pattern matches the interceptor domain
- // we evaluate the query on that interceptor and aggregate the results.
- // Eventually we also evaluate the pattern against the next interceptor.
- //
- // See getInterceptorForQuery below.
- //
- private boolean multipleQuery(ObjectName pattern) {
- // case a) above
- if (pattern == null) return true;
- if (pattern.isDomainPattern()) return true;
-
- // 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;
- }
-
- @Override
- final QueryInterceptor getInterceptorForQuery(ObjectName pattern) {
-
- // Check if we need to aggregate.
- if (multipleQuery(pattern))
- return new AggregatingQueryInterceptor(this);
-
- // We don't need to aggregate: do the "simple" thing...
- final String domain = pattern.getDomain();
-
- // Do we have a virtual domain?
- final DomainInterceptor ns = getInterceptor(domain);
- if (ns != null) {
- if (LOG.isLoggable(Level.FINER))
- LOG.finer("dispatching to domain: " + domain);
- return new QueryInterceptor(ns);
- }
-
- // We don't have a virtual domain. Send to local domains.
- if (LOG.isLoggable(Level.FINER))
- LOG.finer("dispatching to local namespace: " + domain);
- return new QueryInterceptor(nextInterceptor);
- }
-
- @Override
- final ObjectName getHandlerNameFor(String key) {
- return JMXDomain.getDomainObjectName(key);
- }
-
- @Override
- final public String getHandlerKey(ObjectName name) {
- return name.getDomain();
- }
-
- @Override
- final DomainInterceptor createInterceptorFor(String key,
- ObjectName name, JMXDomain handler,
- Queue<Runnable> postRegisterQueue) {
- final DomainInterceptor ns =
- new DomainInterceptor(mbeanServerName,handler,key);
- ns.addPostRegisterTask(postRegisterQueue, delegate);
- if (LOG.isLoggable(Level.FINER)) {
- LOG.finer("DomainInterceptor created: "+ns);
- }
- return ns;
- }
-
- @Override
- final void interceptorReleased(DomainInterceptor interceptor,
- Queue<Runnable> postDeregisterQueue) {
- interceptor.addPostDeregisterTask(postDeregisterQueue, delegate);
- }
-
- @Override
- final DefaultMBeanServerInterceptor getNextInterceptor() {
- return nextInterceptor;
- }
-
- /**
- * Returns the list of domains in which any MBean is currently
- * registered.
- */
- @Override
- public String[] getDomains() {
- // A JMXDomain is registered in its own domain.
- // Therefore, nextInterceptor.getDomains() contains all domains.
- // In addition, nextInterceptor will perform the necessary
- // MBeanPermission checks for getDomains().
- //
- return nextInterceptor.getDomains();
- }
-
- /**
- * Returns the number of MBeans registered in the MBean server.
- */
- @Override
- public Integer getMBeanCount() {
- int count = getNextInterceptor().getMBeanCount();
- final String[] keys = getKeys();
- for (String key:keys) {
- final MBeanServer mbs = getInterceptor(key);
- if (mbs == null) continue;
- count += mbs.getMBeanCount();
- }
- return count;
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptorSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +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 java.io.ObjectInputStream;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanException;
-import javax.management.ObjectName;
-import javax.management.OperationsException;
-import javax.management.ReflectionException;
-import javax.management.loading.ClassLoaderRepository;
-
-/**
- * An abstract class for MBeanServerInterceptorSupport.
- * Some methods in MBeanServerInterceptor should never be called.
- * This base class provides an implementation of these methods that simply
- * throw an {@link UnsupportedOperationException}.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @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.");
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public class NamespaceDispatchInterceptor
- extends DispatchInterceptor<NamespaceInterceptor, JMXNamespace> {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- 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;
-
- /**
- * Creates a NamespaceDispatchInterceptor with the specified
- * repository instance.
- * <p>Do not forget to call <code>initialize(outer,delegate)</code>
- * 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:
- * <pre>
- * 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 -> ""
- *
- * </pre>
- **/
- 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<Runnable> postRegisterQueue) {
- final NamespaceInterceptor ns =
- new NamespaceInterceptor(serverName,handler,key);
- if (LOG.isLoggable(Level.FINER)) {
- LOG.finer("NamespaceInterceptor created: "+ns);
- }
- return ns;
- }
-
- @Override
- final DomainDispatchInterceptor getNextInterceptor() {
- return nextInterceptor;
- }
-
- /**
- * Returns the list of domains in which any MBean is currently
- * registered.
- */
- @Override
- public String[] getDomains() {
- return nextInterceptor.getDomains();
- }
-
- @Override
- public void addInterceptorFor(ObjectName name, JMXNamespace handler,
- Queue<Runnable> postRegisterQueue) {
- if (handler instanceof JMXDomain)
- nextInterceptor.addInterceptorFor(name,
- (JMXDomain)handler,postRegisterQueue);
- else super.addInterceptorFor(name,handler,postRegisterQueue);
- }
-
- @Override
- public void removeInterceptorFor(ObjectName name, JMXNamespace handler,
- Queue<Runnable> postDeregisterQueue) {
- if (handler instanceof JMXDomain)
- nextInterceptor.removeInterceptorFor(name,(JMXDomain)handler,
- postDeregisterQueue);
- else super.removeInterceptorFor(name,handler,postDeregisterQueue);
- }
-
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,442 +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.mbeanserver.Util;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.MBeanServerSupport;
-import javax.management.remote.IdentityMBeanServerForwarder;
-
-/**
- * <p>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.</p>
- */
-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 Set<ObjectName> getNames() {
- return Collections.singleton(mbeanName);
- }
-
- @Override
- public NotificationEmitter getNotificationEmitterFor(
- ObjectName name) {
- if (mbean instanceof NotificationEmitter)
- return (NotificationEmitter) mbean;
- return null;
- }
-
- // This will only be called if mbeanName has an empty domain.
- // In that case a getAttribute (e.g.) of that name will have the
- // domain replaced by MBeanServerSupport with the default domain,
- // so we must be sure that the default domain is empty too.
- @Override
- public String getDefaultDomain() {
- return mbeanName.getDomain();
- }
- };
-
- public SingleMBeanForwarder(
- ObjectName mbeanName, DynamicMBean mbean, boolean visible) {
- this.mbeanName = mbeanName;
- this.visible = visible;
- setSingleMBean(mbean);
- }
-
- protected void setSingleMBean(DynamicMBean mbean) {
- this.mbean = mbean;
- }
-
- @Override
- public void addNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- if (mbeanName.equals(name))
- mbeanMBS.addNotificationListener(name, listener, filter, handback);
- else
- super.addNotificationListener(name, listener, filter, handback);
- }
-
- @Override
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- if (mbeanName.equals(name))
- mbeanMBS.addNotificationListener(name, listener, filter, handback);
- else
- super.addNotificationListener(name, listener, filter, handback);
- }
-
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName, Object[] params,
- String[] signature)
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException {
- if (mbeanName.equals(name))
- throw new InstanceAlreadyExistsException(mbeanName.toString());
- else
- return super.createMBean(className, name, loaderName, params, signature);
- }
-
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- if (mbeanName.equals(name))
- throw new InstanceAlreadyExistsException(mbeanName.toString());
- return super.createMBean(className, name, params, signature);
- }
-
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName)
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException {
- if (mbeanName.equals(name))
- throw new InstanceAlreadyExistsException(mbeanName.toString());
- return super.createMBean(className, name, loaderName);
- }
-
- @Override
- public ObjectInstance createMBean(String className, ObjectName name)
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException {
- if (mbeanName.equals(name))
- throw new InstanceAlreadyExistsException(mbeanName.toString());
- return super.createMBean(className, name);
- }
-
- @Override
- public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException,
- AttributeNotFoundException,
- InstanceNotFoundException,
- ReflectionException {
- if (mbeanName.equals(name))
- return mbeanMBS.getAttribute(name, attribute);
- else
- return super.getAttribute(name, attribute);
- }
-
- @Override
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- if (mbeanName.equals(name))
- return mbeanMBS.getAttributes(name, attributes);
- else
- return super.getAttributes(name, attributes);
- }
-
- @Override
- public ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- if (mbeanName.equals(loaderName))
- return mbeanMBS.getClassLoader(loaderName);
- else
- return super.getClassLoader(loaderName);
- }
-
- @Override
- public ClassLoader getClassLoaderFor(ObjectName name)
- throws InstanceNotFoundException {
- if (mbeanName.equals(name))
- return mbeanMBS.getClassLoaderFor(name);
- else
- return super.getClassLoaderFor(name);
- }
-
- @Override
- public String[] getDomains() {
- String[] domains = super.getDomains();
- if (!visible)
- return domains;
- TreeSet<String> domainSet = new TreeSet<String>(Arrays.asList(domains));
- domainSet.add(mbeanName.getDomain());
- return domainSet.toArray(new String[domainSet.size()]);
- }
-
- @Override
- public Integer getMBeanCount() {
- Integer count = super.getMBeanCount();
- if (visible && !super.isRegistered(mbeanName))
- count++;
- return count;
- }
-
- @Override
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException,
- IntrospectionException,
- ReflectionException {
- if (mbeanName.equals(name))
- return mbeanMBS.getMBeanInfo(name);
- else
- return super.getMBeanInfo(name);
- }
-
- @Override
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- if (mbeanName.equals(name))
- return mbeanMBS.getObjectInstance(name);
- else
- return super.getObjectInstance(name);
- }
-
- @Override
- public Object invoke(ObjectName name, String operationName, Object[] params,
- String[] signature)
- throws InstanceNotFoundException,
- MBeanException,
- ReflectionException {
- if (mbeanName.equals(name))
- return mbeanMBS.invoke(name, operationName, params, signature);
- else
- return super.invoke(name, operationName, params, signature);
- }
-
- @Override
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- if (mbeanName.equals(name))
- return mbeanMBS.isInstanceOf(name, className);
- else
- return super.isInstanceOf(name, className);
- }
-
- @Override
- public boolean isRegistered(ObjectName name) {
- if (mbeanName.equals(name))
- return true;
- else
- return super.isRegistered(name);
- }
-
- /**
- * This is a ugly hack. Although jmx.context//*:* matches jmx.context//:*
- * queryNames(jmx.context//*:*,null) must not return jmx.context//:*
- * @param pattern the pattern to match against. must not be null.
- * @return true if mbeanName can be included, false if it must not.
- */
- private boolean applies(ObjectName pattern) {
- // we know pattern is not null.
- if (!visible || !pattern.apply(mbeanName))
- return false;
-
- final String dompat = pattern.getDomain();
- if (!dompat.contains(JMXNamespaces.NAMESPACE_SEPARATOR))
- return true; // We already checked that patterns apply.
-
- if (mbeanName.getDomain().endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) {
- // only matches if pattern ends with //
- return dompat.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR);
- }
-
- // should not come here, unless mbeanName contains a // in the
- // middle of its domain, which would be weird.
- // let query on mbeanMBS proceed and take care of that.
- //
- return true;
- }
-
- @Override
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- Set<ObjectInstance> names = super.queryMBeans(name, query);
- if (visible) {
- if (name == null || applies(name) ) {
- // Don't assume mbs.queryNames returns a writable set.
- names = Util.cloneSet(names);
- names.addAll(mbeanMBS.queryMBeans(name, query));
- }
- }
- return names;
- }
-
- @Override
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- Set<ObjectName> names = super.queryNames(name, query);
- if (visible) {
- if (name == null || applies(name)) {
- // Don't assume mbs.queryNames returns a writable set.
- names = Util.cloneSet(names);
- names.addAll(mbeanMBS.queryNames(name, query));
- }
- }
- return names;
- }
-
-
- @Override
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException,
- MBeanRegistrationException,
- NotCompliantMBeanException {
- if (mbeanName.equals(name))
- throw new InstanceAlreadyExistsException(mbeanName.toString());
- else
- return super.registerMBean(object, name);
- }
-
- @Override
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- ListenerNotFoundException {
- if (mbeanName.equals(name))
- mbeanMBS.removeNotificationListener(name, listener, filter, handback);
- else
- super.removeNotificationListener(name, listener, filter, handback);
- }
-
- @Override
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- if (mbeanName.equals(name))
- mbeanMBS.removeNotificationListener(name, listener);
- else
- super.removeNotificationListener(name, listener);
- }
-
- @Override
- public void removeNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- ListenerNotFoundException {
- if (mbeanName.equals(name))
- mbeanMBS.removeNotificationListener(name, listener, filter, handback);
- else
- super.removeNotificationListener(name, listener, filter, handback);
- }
-
- @Override
- public void removeNotificationListener(ObjectName name, ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- if (mbeanName.equals(name))
- mbeanMBS.removeNotificationListener(name, listener);
- else
- super.removeNotificationListener(name, listener);
- }
-
- @Override
- public void setAttribute(ObjectName name, Attribute attribute)
- throws InstanceNotFoundException,
- AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException {
- if (mbeanName.equals(name))
- mbeanMBS.setAttribute(name, attribute);
- else
- super.setAttribute(name, attribute);
- }
-
- @Override
- public AttributeList setAttributes(ObjectName name,
- AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- if (mbeanName.equals(name))
- return mbeanMBS.setAttributes(name, attributes);
- else
- return super.setAttributes(name, attributes);
- }
-
- @Override
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException,
- MBeanRegistrationException {
- if (mbeanName.equals(name))
- mbeanMBS.unregisterMBean(name);
- else
- super.unregisterMBean(name);
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java Wed Oct 21 16:50:44 2009 +0100
@@ -31,15 +31,13 @@
import javax.management.Descriptor;
import javax.management.MBeanException;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingFactory;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
final class ConvertingMethod {
- static ConvertingMethod from(Method m, MXBeanMappingFactory mappingFactory) {
+ static ConvertingMethod from(Method m) {
try {
- return new ConvertingMethod(m, mappingFactory);
+ return new ConvertingMethod(m);
} catch (OpenDataException ode) {
final String msg = "Method " + m.getDeclaringClass().getName() +
"." + m.getName() + " has parameter or return type that " +
@@ -53,7 +51,7 @@
}
Descriptor getDescriptor() {
- return Introspector.descriptorForElement(method, false);
+ return Introspector.descriptorForElement(method);
}
Type getGenericReturnType() {
@@ -206,9 +204,9 @@
return method.getDeclaringClass() + "." + method.getName();
}
- private ConvertingMethod(Method m, MXBeanMappingFactory mappingFactory)
- throws OpenDataException {
+ private ConvertingMethod(Method m) throws OpenDataException {
this.method = m;
+ MXBeanMappingFactory mappingFactory = MXBeanMappingFactory.DEFAULT;
returnMapping =
mappingFactory.mappingForType(m.getGenericReturnType(), mappingFactory);
Type[] params = m.getGenericParameterTypes();
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Oct 21 16:50:44 2009 +0100
@@ -28,8 +28,6 @@
import static com.sun.jmx.mbeanserver.Util.*;
import static com.sun.jmx.mbeanserver.MXBeanIntrospector.typeName;
-import javax.management.openmbean.MXBeanMappingClass;
-
import static javax.management.openmbean.SimpleType.*;
import com.sun.jmx.remote.util.EnvHelp;
@@ -69,8 +67,6 @@
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeDataView;
import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingFactory;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
@@ -165,34 +161,29 @@
private static final class Mappings
extends WeakHashMap<Type, WeakReference<MXBeanMapping>> {}
- private static final Map<MXBeanMappingFactory, Mappings> factoryMappings =
- new WeakHashMap<MXBeanMappingFactory, Mappings>();
-
- private static final Map<Type, MXBeanMapping> permanentMappings = newMap();
+ private static final Mappings mappings = new Mappings();
- private static synchronized MXBeanMapping getMapping(
- Type type, MXBeanMappingFactory factory) {
- Mappings mappings = factoryMappings.get(factory);
- if (mappings == null) {
- mappings = new Mappings();
- factoryMappings.put(factory, mappings);
- }
+ /** Following List simply serves to keep a reference to predefined
+ MXBeanMappings so they don't get garbage collected. */
+ private static final List<MXBeanMapping> permanentMappings = newList();
+
+ private static synchronized MXBeanMapping getMapping(Type type) {
WeakReference<MXBeanMapping> wr = mappings.get(type);
return (wr == null) ? null : wr.get();
}
- private static synchronized void putMapping(
- Type type, MXBeanMapping mapping, MXBeanMappingFactory factory) {
- Mappings mappings = factoryMappings.get(factory);
- if (mappings == null) {
- mappings = new Mappings();
- factoryMappings.put(factory, mappings);
- }
+ private static synchronized void putMapping(Type type, MXBeanMapping mapping) {
WeakReference<MXBeanMapping> wr =
new WeakReference<MXBeanMapping>(mapping);
mappings.put(type, wr);
}
+ private static synchronized void putPermanentMapping(
+ Type type, MXBeanMapping mapping) {
+ putMapping(type, mapping);
+ permanentMappings.add(mapping);
+ }
+
static {
/* Set up the mappings for Java types that map to SimpleType. */
@@ -213,7 +204,7 @@
throw new Error(e);
}
final MXBeanMapping mapping = new IdentityMapping(c, t);
- permanentMappings.put(c, mapping);
+ putPermanentMapping(c, mapping);
if (c.getName().startsWith("java.lang.")) {
try {
@@ -221,7 +212,7 @@
final Class<?> primitiveType = (Class<?>) typeField.get(null);
final MXBeanMapping primitiveMapping =
new IdentityMapping(primitiveType, t);
- permanentMappings.put(primitiveType, primitiveMapping);
+ putPermanentMapping(primitiveType, primitiveMapping);
if (primitiveType != void.class) {
final Class<?> primitiveArrayType =
Array.newInstance(primitiveType, 0).getClass();
@@ -230,8 +221,8 @@
final MXBeanMapping primitiveArrayMapping =
new IdentityMapping(primitiveArrayType,
primitiveArrayOpenType);
- permanentMappings.put(primitiveArrayType,
- primitiveArrayMapping);
+ putPermanentMapping(primitiveArrayType,
+ primitiveArrayMapping);
}
} catch (NoSuchFieldException e) {
// OK: must not be a primitive wrapper
@@ -255,7 +246,7 @@
MXBeanMapping mapping;
- mapping = getMapping(objType, null);
+ mapping = getMapping(objType);
if (mapping != null)
return mapping;
@@ -268,7 +259,7 @@
inProgress.remove(objType);
}
- putMapping(objType, mapping, factory);
+ putMapping(objType, mapping);
return mapping;
}
@@ -278,14 +269,6 @@
/* It's not yet worth formalizing these tests by having for example
an array of factory classes, each of which says whether it
recognizes the Type (Chain of Responsibility pattern). */
- MXBeanMapping mapping = permanentMappings.get(objType);
- if (mapping != null)
- return mapping;
- Class<?> erasure = erasure(objType);
- MXBeanMappingClass mappingClass =
- erasure.getAnnotation(MXBeanMappingClass.class);
- if (mappingClass != null)
- return makeAnnotationMapping(mappingClass, objType, factory);
if (objType instanceof GenericArrayType) {
Type componentType =
((GenericArrayType) objType).getGenericComponentType();
@@ -313,51 +296,6 @@
throw new OpenDataException("Cannot map type: " + objType);
}
- private static MXBeanMapping
- makeAnnotationMapping(MXBeanMappingClass mappingClass,
- Type objType,
- MXBeanMappingFactory factory)
- throws OpenDataException {
- Class<? extends MXBeanMapping> c = mappingClass.value();
- Constructor<? extends MXBeanMapping> cons;
- try {
- cons = c.getConstructor(Type.class);
- } catch (NoSuchMethodException e) {
- final String msg =
- "Annotation @" + MXBeanMappingClass.class.getName() +
- " must name a class with a public constructor that has a " +
- "single " + Type.class.getName() + " argument";
- OpenDataException ode = new OpenDataException(msg);
- ode.initCause(e);
- throw ode;
- }
- try {
- return cons.newInstance(objType);
- } catch (Exception e) {
- final String msg =
- "Could not construct a " + c.getName() + " for @" +
- MXBeanMappingClass.class.getName();
- OpenDataException ode = new OpenDataException(msg);
- ode.initCause(e);
- throw ode;
- }
- }
-
- private static Class<?> erasure(Type t) {
- if (t instanceof Class<?>)
- return (Class<?>) t;
- if (t instanceof ParameterizedType)
- return erasure(((ParameterizedType) t).getRawType());
- /* Other cases: GenericArrayType, TypeVariable, WildcardType.
- * Returning the erasure of GenericArrayType is not necessary because
- * anyway we will be recursing on the element type, and we'll erase
- * then. Returning the erasure of the other two would mean returning
- * the type bound (e.g. Foo in <T extends Foo> or <? extends Foo>)
- * and since we don't treat this as Foo elsewhere we shouldn't here.
- */
- return Object.class;
- }
-
private static <T extends Enum<T>> MXBeanMapping
makeEnumMapping(Class<?> enumClass, Class<T> fake) {
return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005 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
@@ -25,7 +25,7 @@
package com.sun.jmx.mbeanserver;
-import javax.management.DynamicWrapperMBean;
+import javax.management.DynamicMBean;
import javax.management.MBeanServer;
import javax.management.ObjectName;
@@ -35,7 +35,17 @@
*
* @since 1.6
*/
-public interface DynamicMBean2 extends DynamicWrapperMBean {
+public interface DynamicMBean2 extends DynamicMBean {
+ /**
+ * The resource corresponding to this MBean. This is the object whose
+ * class name should be reflected by the MBean's
+ * getMBeanInfo().getClassName() for example. For a "plain"
+ * DynamicMBean it will be "this". For an MBean that wraps another
+ * object, like javax.management.StandardMBean, it will be the wrapped
+ * object.
+ */
+ public Object getResource();
+
/**
* The name of this MBean's class, as used by permission checks.
* This is typically equal to getResource().getClass().getName().
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,14 +25,9 @@
package com.sun.jmx.mbeanserver;
-import com.sun.jmx.remote.util.EnvHelp;
-import java.beans.BeanInfo;
-import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
@@ -40,39 +35,21 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-import java.util.logging.Level;
-import javax.management.AttributeNotFoundException;
-import javax.management.Description;
import javax.management.Descriptor;
-import javax.management.DescriptorFields;
import javax.management.DescriptorKey;
import javax.management.DynamicMBean;
import javax.management.ImmutableDescriptor;
-import javax.management.MBean;
import javax.management.MBeanInfo;
-import javax.management.MXBean;
import javax.management.NotCompliantMBeanException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.MXBeanMappingFactory;
-import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
-import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.remote.util.EnvHelp;
import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.management.AttributeNotFoundException;
-import javax.management.JMX;
-import javax.management.ObjectName;
-import javax.management.ObjectNameTemplate;
import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.MXBeanMappingFactory;
/**
* This class contains the methods for performing all the tests needed to verify
@@ -82,13 +59,7 @@
*/
public class Introspector {
- /**
- * Pattern used to extract Attribute Names from ObjectNameTemplate Annotation
- * For example, in the following example, the Name attribute value is
- * retrieved : ":type=MyType, name={Name}"
- */
- private static Pattern OBJECT_NAME_PATTERN_TEMPLATE =
- Pattern.compile("(\\{[^\\}]+\\})|(=\"\\{[^\\}]+\\}\")");
+
/*
* ------------------------------------------
* PRIVATE CONSTRUCTORS
@@ -164,10 +135,6 @@
public static void checkCompliance(Class<?> mbeanClass)
throws NotCompliantMBeanException {
-
- // Check that @Resource is used correctly (if it used).
- MBeanInjector.validate(mbeanClass);
-
// Is DynamicMBean?
//
if (DynamicMBean.class.isAssignableFrom(mbeanClass))
@@ -190,36 +157,16 @@
} catch (NotCompliantMBeanException e) {
mxbeanException = e;
}
- // Is @MBean or @MXBean class?
- // In fact we find @MBean or @MXBean as a hacky variant of
- // getStandardMBeanInterface or getMXBeanInterface. If we get here
- // then nothing worked.
final String msg =
"MBean class " + mbeanClass.getName() + " does not implement " +
- "DynamicMBean; does not follow the Standard MBean conventions (" +
- mbeanException.toString() + "); does not follow the MXBean conventions (" +
- mxbeanException.toString() + "); and does not have or inherit the @" +
- MBean.class.getSimpleName() + " or @" + MXBean.class.getSimpleName() +
- " annotation";
+ "DynamicMBean, and neither follows the Standard MBean conventions (" +
+ mbeanException.toString() + ") nor the MXBean conventions (" +
+ mxbeanException.toString() + ")";
throw new NotCompliantMBeanException(msg);
}
- /**
- * <p>Make 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}.</p>
- * @param mbean the object to convert to a DynamicMBean.
- * @param <T> a type parameter defined for implementation convenience
- * (which would have to be removed if this method were part of the public
- * API).
- * @return the converted DynamicMBean.
- * @throws NotCompliantMBeanException if {@code mbean} is not a compliant
- * MBean object, including the case where it is null.
- */
public static <T> DynamicMBean makeDynamicMBean(T mbean)
- throws NotCompliantMBeanException {
- if (mbean == null)
- throw new NotCompliantMBeanException("Null MBean object");
+ throws NotCompliantMBeanException {
if (mbean instanceof DynamicMBean)
return (DynamicMBean) mbean;
final Class<?> mbeanClass = mbean.getClass();
@@ -240,18 +187,8 @@
// to be an MBean or an MXBean. We will call checkCompliance()
// to generate the appropriate exception.
}
- if (c != null) {
- MXBeanMappingFactory factory;
- try {
- factory = MXBeanMappingFactory.forInterface(c);
- } catch (IllegalArgumentException e) {
- NotCompliantMBeanException ncmbe =
- new NotCompliantMBeanException(e.getMessage());
- ncmbe.initCause(e);
- throw ncmbe;
- }
- return new MXBeanSupport(mbean, c, factory);
- }
+ if (c != null)
+ return new MXBeanSupport(mbean, c);
checkCompliance(mbeanClass);
throw new NotCompliantMBeanException("Not compliant"); // not reached
}
@@ -280,10 +217,9 @@
return testCompliance(baseClass, null);
}
- public static void testComplianceMXBeanInterface(Class<?> interfaceClass,
- MXBeanMappingFactory factory)
+ public static void testComplianceMXBeanInterface(Class<?> interfaceClass)
throws NotCompliantMBeanException {
- MXBeanIntrospector.getInstance(factory).getAnalyzer(interfaceClass);
+ MXBeanIntrospector.getInstance().getAnalyzer(interfaceClass);
}
/**
@@ -352,8 +288,6 @@
*/
public static <T> Class<? super T> getStandardMBeanInterface(Class<T> baseClass)
throws NotCompliantMBeanException {
- if (baseClass.isAnnotationPresent(MBean.class))
- return baseClass;
Class<? super T> current = baseClass;
Class<? super T> mbeanInterface = null;
while (current != null) {
@@ -384,8 +318,6 @@
*/
public static <T> Class<? super T> getMXBeanInterface(Class<T> baseClass)
throws NotCompliantMBeanException {
- if (hasMXBeanAnnotation(baseClass))
- return baseClass;
try {
return MXBeanSupport.findMXBeanInterface(baseClass);
} catch (Exception e) {
@@ -393,61 +325,12 @@
}
}
- public static <T> Class<? super T> getStandardOrMXBeanInterface(
- Class<T> baseClass, boolean mxbean)
- throws NotCompliantMBeanException {
- if (mxbean)
- return getMXBeanInterface(baseClass);
- else
- return getStandardMBeanInterface(baseClass);
- }
-
- public static ObjectName templateToObjectName(Descriptor descriptor,
- DynamicMBean mbean)
- throws NotCompliantMBeanException {
- String template = (String)
- descriptor.getFieldValue(JMX.OBJECT_NAME_TEMPLATE);
- if(template == null) return null;
- try {
- Matcher m = OBJECT_NAME_PATTERN_TEMPLATE.matcher(template);
- while (m.find()){
- String grp = m.group();
- System.out.println("GROUP " + grp);
- String attributeName = null;
- boolean quote = false;
- if(grp.startsWith("=\"{")) {
- attributeName = grp.substring(3, grp.length() - 2);
- quote = true;
- } else
- attributeName = grp.substring(1, grp.length() - 1);
-
- Object attributeValue = mbean.getAttribute(attributeName);
- String validValue = quote ?
- "=" + ObjectName.quote(attributeValue.toString()) :
- attributeValue.toString();
- template = template.replace(grp, validValue);
- }
- return new ObjectName(template);
- }catch(Exception ex) {
- NotCompliantMBeanException ncex = new
- NotCompliantMBeanException(ObjectNameTemplate.class.
- getSimpleName() + " annotation value [" + template + "] " +
- "is invalid. " + ex);
- ncex.initCause(ex);
- throw ncex;
- }
- }
-
/*
* ------------------------------------------
* PRIVATE METHODS
* ------------------------------------------
*/
- static boolean hasMXBeanAnnotation(Class<?> c) {
- MXBean m = c.getAnnotation(MXBean.class);
- return (m != null && m.value());
- }
/**
* Try to find the MBean interface corresponding to the class aName
@@ -469,77 +352,11 @@
return null;
}
- public static String descriptionForElement(AnnotatedElement elmt) {
- if (elmt == null)
- return null;
- Description d = elmt.getAnnotation(Description.class);
- if (d == null)
- return null;
- return d.value();
- }
-
- public static String descriptionForParameter(
- Annotation[] parameterAnnotations) {
- for (Annotation a : parameterAnnotations) {
- if (a instanceof Description)
- return ((Description) a).value();
- }
- return null;
- }
-
- public static String nameForParameter(
- Annotation[] parameterAnnotations) {
- for (Annotation a : parameterAnnotations) {
- Class<? extends Annotation> ac = a.annotationType();
- // You'd really have to go out of your way to have more than
- // one @Name annotation, so we don't check for that.
- if (ac.getSimpleName().equals("Name")) {
- try {
- Method value = ac.getMethod("value");
- if (value.getReturnType() == String.class &&
- value.getParameterTypes().length == 0) {
- return (String) value.invoke(a);
- }
- } catch (Exception e) {
- MBEANSERVER_LOGGER.log(
- Level.WARNING,
- "Unexpected exception getting @" + ac.getName(),
- e);
- }
- }
- }
- return null;
- }
-
- public static Descriptor descriptorForElement(final AnnotatedElement elmt,
- boolean isSetter) {
+ public static Descriptor descriptorForElement(final AnnotatedElement elmt) {
if (elmt == null)
return ImmutableDescriptor.EMPTY_DESCRIPTOR;
final Annotation[] annots = elmt.getAnnotations();
- Descriptor descr = descriptorForAnnotations(annots);
- String[] exceptions = {};
- if(elmt instanceof Method)
- exceptions = getAllExceptions(((Method) elmt).getExceptionTypes());
- else
- if(elmt instanceof Constructor<?>)
- exceptions = getAllExceptions(((Constructor<?>) elmt).
- getExceptionTypes());
-
- if(exceptions.length > 0 ) {
- String fieldName = isSetter ? JMX.SET_EXCEPTIONS_FIELD :
- JMX.EXCEPTIONS_FIELD;
-
- String[] fieldNames = {fieldName};
- Object[] fieldValues = {exceptions};
- descr = ImmutableDescriptor.union(descr,
- new ImmutableDescriptor(fieldNames, fieldValues));
- }
-
- return descr;
- }
-
- public static Descriptor descriptorForAnnotation(Annotation annot) {
- return descriptorForAnnotations(new Annotation[] {annot});
+ return descriptorForAnnotations(annots);
}
public static Descriptor descriptorForAnnotations(Annotation[] annots) {
@@ -547,9 +364,36 @@
return ImmutableDescriptor.EMPTY_DESCRIPTOR;
Map<String, Object> descriptorMap = new HashMap<String, Object>();
for (Annotation a : annots) {
- if (a instanceof DescriptorFields)
- addDescriptorFieldsToMap(descriptorMap, (DescriptorFields) a);
- addAnnotationFieldsToMap(descriptorMap, a);
+ Class<? extends Annotation> c = a.annotationType();
+ Method[] elements = c.getMethods();
+ for (Method element : elements) {
+ DescriptorKey key = element.getAnnotation(DescriptorKey.class);
+ if (key != null) {
+ String name = key.value();
+ Object value;
+ try {
+ value = element.invoke(a);
+ } catch (RuntimeException e) {
+ // we don't expect this - except for possibly
+ // security exceptions?
+ // RuntimeExceptions shouldn't be "UndeclaredThrowable".
+ // anyway...
+ //
+ throw e;
+ } catch (Exception e) {
+ // we don't expect this
+ throw new UndeclaredThrowableException(e);
+ }
+ value = annotationToField(value);
+ Object oldValue = descriptorMap.put(name, value);
+ if (oldValue != null && !equals(oldValue, value)) {
+ final String msg =
+ "Inconsistent values for descriptor field " + name +
+ " from annotations: " + value + " :: " + oldValue;
+ throw new IllegalArgumentException(msg);
+ }
+ }
+ }
}
if (descriptorMap.isEmpty())
@@ -559,76 +403,6 @@
}
/**
- * Array of thrown excepions.
- * @param exceptions can be null;
- * @return An Array of Exception class names. Size is 0 if method is null.
- */
- private static String[] getAllExceptions(Class<?>[] exceptions) {
- Set<String> set = new LinkedHashSet<String>();
- for(Class<?>ex : exceptions)
- set.add(ex.getName());
-
- String[] arr = new String[set.size()];
- return set.toArray(arr);
- }
-
- private static void addDescriptorFieldsToMap(
- Map<String, Object> descriptorMap, DescriptorFields df) {
- for (String field : df.value()) {
- int eq = field.indexOf('=');
- if (eq < 0) {
- throw new IllegalArgumentException(
- "@DescriptorFields string must contain '=': " +
- field);
- }
- String name = field.substring(0, eq);
- String value = field.substring(eq + 1);
- addToMap(descriptorMap, name, value);
- }
- }
-
- private static void addAnnotationFieldsToMap(
- Map<String, Object> descriptorMap, Annotation a) {
- Class<? extends Annotation> c = a.annotationType();
- Method[] elements = c.getMethods();
- for (Method element : elements) {
- DescriptorKey key = element.getAnnotation(DescriptorKey.class);
- if (key != null) {
- String name = key.value();
- Object value;
- try {
- value = element.invoke(a);
- } catch (RuntimeException e) {
- // we don't expect this - except for possibly
- // security exceptions?
- // RuntimeExceptions shouldn't be "UndeclaredThrowable".
- // anyway...
- throw e;
- } catch (Exception e) {
- // we don't expect this
- throw new UndeclaredThrowableException(e);
- }
- if (!key.omitIfDefault() ||
- !equals(value, element.getDefaultValue())) {
- value = annotationToField(value);
- addToMap(descriptorMap, name, value);
- }
- }
- }
- }
-
- private static void addToMap(
- Map<String, Object> descriptorMap, String name, Object value) {
- Object oldValue = descriptorMap.put(name, value);
- if (oldValue != null && !equals(oldValue, value)) {
- final String msg =
- "Inconsistent values for descriptor field " + name +
- " from annotations: " + value + " :: " + oldValue;
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
* Throws a NotCompliantMBeanException or a SecurityException.
* @param notCompliant the class which was under examination
* @param cause the raeson why NotCompliantMBeanException should
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,14 +25,14 @@
package com.sun.jmx.mbeanserver;
+import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor;
+import com.sun.jmx.interceptor.MBeanServerInterceptor;
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
-import com.sun.jmx.interceptor.NamespaceDispatchInterceptor;
import java.io.ObjectInputStream;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedExceptionAction;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -108,8 +108,6 @@
/** The MBeanServerDelegate object representing the MBean Server */
private final MBeanServerDelegate mBeanServerDelegateObject;
- private final String mbeanServerName;
-
/**
* <b>Package:</b> Creates an MBeanServer with the
* specified default domain name, outer interface, and delegate.
@@ -241,10 +239,9 @@
final Repository repository = new Repository(domain);
this.mbsInterceptor =
- new NamespaceDispatchInterceptor(outer, delegate, instantiator,
+ new DefaultMBeanServerInterceptor(outer, delegate, instantiator,
repository);
this.interceptorsEnabled = interceptors;
- this.mbeanServerName = Util.getMBeanServerSecurityName(delegate);
initialize();
}
@@ -940,8 +937,7 @@
throws ReflectionException, MBeanException {
/* Permission check */
- checkMBeanPermission(mbeanServerName, className, null, null,
- "instantiate");
+ checkMBeanPermission(className, null, null, "instantiate");
return instantiator.instantiate(className);
}
@@ -978,8 +974,7 @@
InstanceNotFoundException {
/* Permission check */
- checkMBeanPermission(mbeanServerName, className, null,
- null, "instantiate");
+ checkMBeanPermission(className, null, null, "instantiate");
ClassLoader myLoader = outerShell.getClass().getClassLoader();
return instantiator.instantiate(className, loaderName, myLoader);
@@ -1017,8 +1012,7 @@
throws ReflectionException, MBeanException {
/* Permission check */
- checkMBeanPermission(mbeanServerName, className, null, null,
- "instantiate");
+ checkMBeanPermission(className, null, null, "instantiate");
ClassLoader myLoader = outerShell.getClass().getClassLoader();
return instantiator.instantiate(className, params, signature,
@@ -1061,8 +1055,7 @@
InstanceNotFoundException {
/* Permission check */
- checkMBeanPermission(mbeanServerName, className, null,
- null, "instantiate");
+ checkMBeanPermission(className, null, null, "instantiate");
ClassLoader myLoader = outerShell.getClass().getClassLoader();
return instantiator.instantiate(className,loaderName,params,signature,
@@ -1333,8 +1326,7 @@
**/
public ClassLoaderRepository getClassLoaderRepository() {
/* Permission check */
- checkMBeanPermission(mbeanServerName, null, null,
- null, "getClassLoaderRepository");
+ checkMBeanPermission(null, null, null, "getClassLoaderRepository");
return secureClr;
}
@@ -1487,16 +1479,14 @@
// SECURITY CHECKS
//----------------
- private static void checkMBeanPermission(String serverName,
- String classname,
+ private static void checkMBeanPermission(String classname,
String member,
ObjectName objectName,
String actions)
throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- Permission perm = new MBeanPermission(serverName,
- classname,
+ Permission perm = new MBeanPermission(classname,
member,
objectName,
actions);
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java Wed Oct 21 16:50:44 2009 +0100
@@ -33,10 +33,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.management.MBean;
-import javax.management.MXBean;
-import javax.management.ManagedAttribute;
-import javax.management.ManagedOperation;
import javax.management.NotCompliantMBeanException;
/**
@@ -55,15 +51,15 @@
*/
class MBeanAnalyzer<M> {
- static interface MBeanVisitor<M, X extends Exception> {
+ static interface MBeanVisitor<M> {
public void visitAttribute(String attributeName,
M getter,
- M setter) throws X;
+ M setter);
public void visitOperation(String operationName,
- M operation) throws X;
+ M operation);
}
- <X extends Exception> void visit(MBeanVisitor<M, X> visitor) throws X {
+ void visit(MBeanVisitor<M> visitor) {
// visit attributes
for (Map.Entry<String, AttrMethods<M>> entry : attrMap.entrySet()) {
String name = entry.getKey();
@@ -108,7 +104,10 @@
private MBeanAnalyzer(Class<?> mbeanType,
MBeanIntrospector<M> introspector)
throws NotCompliantMBeanException {
- introspector.checkCompliance(mbeanType);
+ if (!mbeanType.isInterface()) {
+ throw new NotCompliantMBeanException("Not an interface: " +
+ mbeanType.getName());
+ }
try {
initMaps(mbeanType, introspector);
@@ -129,26 +128,18 @@
for (Method m : methods) {
final String name = m.getName();
final int nParams = m.getParameterTypes().length;
- final boolean managedOp = m.isAnnotationPresent(ManagedOperation.class);
- final boolean managedAttr = m.isAnnotationPresent(ManagedAttribute.class);
- if (managedOp && managedAttr) {
- throw new NotCompliantMBeanException("Method " + name +
- " has both @ManagedOperation and @ManagedAttribute");
- }
final M cm = introspector.mFrom(m);
String attrName = "";
- if (!managedOp) {
- if (name.startsWith("get"))
- attrName = name.substring(3);
- else if (name.startsWith("is")
- && m.getReturnType() == boolean.class)
- attrName = name.substring(2);
- }
+ if (name.startsWith("get"))
+ attrName = name.substring(3);
+ else if (name.startsWith("is")
+ && m.getReturnType() == boolean.class)
+ attrName = name.substring(2);
if (attrName.length() != 0 && nParams == 0
- && m.getReturnType() != void.class && !managedOp) {
+ && m.getReturnType() != void.class) {
// It's a getter
// Check we don't have both isX and getX
AttrMethods<M> am = attrMap.get(attrName);
@@ -165,7 +156,7 @@
attrMap.put(attrName, am);
} else if (name.startsWith("set") && name.length() > 3
&& nParams == 1 &&
- m.getReturnType() == void.class && !managedOp) {
+ m.getReturnType() == void.class) {
// It's a setter
attrName = name.substring(3);
AttrMethods<M> am = attrMap.get(attrName);
@@ -178,9 +169,6 @@
}
am.setter = cm;
attrMap.put(attrName, am);
- } else if (managedAttr) {
- throw new NotCompliantMBeanException("Method " + name +
- " has @ManagedAttribute but is not a valid getter or setter");
} else {
// It's an operation
List<M> cms = opMap.get(name);
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,295 +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.mbeanserver;
-
-import java.lang.ref.WeakReference;
-import java.security.PrivilegedAction;
-import java.util.Map;
-import java.util.WeakHashMap;
-import javax.annotation.Resource;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-
-import static com.sun.jmx.mbeanserver.Util.newMap;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.management.SendNotification;
-
-public class MBeanInjector {
- // There are no instances of this class
- private MBeanInjector() {
- }
-
- private static Class<?>[] injectedClasses = {
- MBeanServer.class, ObjectName.class, SendNotification.class,
- };
-
- public static void inject(Object mbean, MBeanServer mbs, ObjectName name)
- throws Exception {
- ClassInjector injector = injectorForClass(mbean.getClass());
- injector.inject(mbean, MBeanServer.class, mbs);
- injector.inject(mbean, ObjectName.class, name);
- }
-
- public static boolean injectsSendNotification(Object mbean)
- throws NotCompliantMBeanException {
- ClassInjector injector = injectorForClass(mbean.getClass());
- return injector.injects(SendNotification.class);
- }
-
- public static void injectSendNotification(Object mbean, SendNotification sn)
- throws Exception {
- ClassInjector injector = injectorForClass(mbean.getClass());
- injector.inject(mbean, SendNotification.class, sn);
- }
-
- public static void validate(Class<?> c) throws NotCompliantMBeanException {
- injectorForClass(c);
- }
-
- private static class ClassInjector {
- private Map<Class<?>, List<Field>> fields;
- private Map<Class<?>, List<Method>> methods;
-
- ClassInjector(Class<?> c) throws NotCompliantMBeanException {
- fields = newMap();
- methods = newMap();
-
- Class<?> sup = c.getSuperclass();
- ClassInjector supInjector;
- if (sup == null) {
- supInjector = null;
- } else {
- supInjector = injectorForClass(sup);
- fields.putAll(supInjector.fields);
- methods.putAll(supInjector.methods);
- }
-
- addMembers(c);
- eliminateOverriddenMethods();
-
- // If we haven't added any new fields or methods to what we
- // inherited, then we can share the parent's maps.
- if (supInjector != null) {
- if (fields.equals(supInjector.fields))
- fields = supInjector.fields;
- if (methods.equals(supInjector.methods))
- methods = supInjector.methods;
- }
- }
-
- boolean injects(Class<?> c) {
- return (fields.get(c) != null || methods.get(c) != null);
- }
-
- <T> void inject(Object instance, Class<T> type, T resource)
- throws Exception {
- List<Field> fs = fields.get(type);
- if (fs != null) {
- for (Field f : fs)
- f.set(instance, resource);
- }
- List<Method> ms = methods.get(type);
- if (ms != null) {
- for (Method m : ms) {
- try {
- m.invoke(instance, resource);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof Error)
- throw (Error) cause;
- else
- throw (Exception) cause;
- }
- }
- }
- }
-
- private void eliminateOverriddenMethods() {
- /* Covariant overriding is unlikely, but it is possible that the
- * parent has a @Resource method that we override with another
- * @Resource method. We don't want to invoke both methods,
- * because polymorphism means we would actually invoke the same
- * method twice.
- */
- for (Map.Entry<Class<?>, List<Method>> entry : methods.entrySet()) {
- List<Method> list = entry.getValue();
- list = MBeanAnalyzer.eliminateCovariantMethods(list);
- entry.setValue(list);
- }
- }
-
- /*
- * Find Fields or Methods within the given Class that we can inject
- * resource references into. Suppose we want to know if a Field can get
- * a reference to an ObjectName. We'll accept fields like this:
- *
- * @Resource
- * private transient ObjectName name;
- *
- * or like this:
- *
- * @Resource(type = ObjectName.class)
- * private transient Object name;
- *
- * but not like this:
- *
- * @Resource
- * private transient Object name;
- *
- * (Plain @Resource is equivalent to @Resource(type = Object.class).)
- *
- * We don't want to inject into everything that might possibly accept
- * an ObjectName reference, because examples like the last one above
- * could also accept an MBeanServer reference or any other sort of
- * reference.
- *
- * So we accept a Field if it has a @Resource annotation and either
- * (a) its type is exactly ObjectName and its @Resource type is
- * compatible with ObjectName (e.g. it is Object); or
- * (b) its type is compatible with ObjectName and its @Resource type
- * is exactly ObjectName. Fields that meet these criteria will not
- * meet the same criteria with respect to other types such as MBeanServer.
- *
- * The same logic applies mutatis mutandis to Methods such as this:
- *
- * @Resource
- * private void setObjectName1(ObjectName name)
- * @Resource(type = Object.class)
- * private void setObjectName2(Object name)
- */
- private void addMembers(final Class<?> c)
- throws NotCompliantMBeanException {
- AccessibleObject[][] memberArrays =
- AccessController.doPrivileged(
- new PrivilegedAction<AccessibleObject[][]>() {
- public AccessibleObject[][] run() {
- return new AccessibleObject[][] {
- c.getDeclaredFields(), c.getDeclaredMethods()
- };
- }
- });
- for (AccessibleObject[] members : memberArrays) {
- for (final AccessibleObject member : members) {
- Resource res = member.getAnnotation(Resource.class);
- if (res == null)
- continue;
-
- final Field field;
- final Method method;
- final Class<?> memberType;
- final int modifiers;
- if (member instanceof Field) {
- field = (Field) member;
- memberType = field.getType();
- modifiers = field.getModifiers();
- method = null;
- } else {
- field = null;
- method = (Method) member;
- Class<?>[] paramTypes = method.getParameterTypes();
- if (paramTypes.length != 1) {
- throw new NotCompliantMBeanException(
- "@Resource method must have exactly 1 " +
- "parameter: " + method);
- }
- if (method.getReturnType() != void.class) {
- throw new NotCompliantMBeanException(
- "@Resource method must return void: " +
- method);
- }
- memberType = paramTypes[0];
- modifiers = method.getModifiers();
- }
-
- if (Modifier.isStatic(modifiers)) {
- throw new NotCompliantMBeanException(
- "@Resource method or field cannot be static: " +
- member);
- }
-
- for (Class<?> injectedClass : injectedClasses) {
- Class<?>[] types = {memberType, res.type()};
- boolean accept = false;
- for (int i = 0; i < 2; i++) {
- if (types[i] == injectedClass &&
- types[1 - i].isAssignableFrom(injectedClass)) {
- accept = true;
- break;
- }
- }
- if (accept) {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- member.setAccessible(true);
- return null;
- }
- });
- addToMap(fields, injectedClass, field);
- addToMap(methods, injectedClass, method);
- }
- }
- }
- }
- }
-
- private static <K, V> void addToMap(Map<K, List<V>> map, K key, V value) {
- if (value == null)
- return;
- List<V> list = map.get(key);
- if (list == null)
- list = Collections.singletonList(value);
- else {
- if (list.size() == 1)
- list = new ArrayList<V>(list);
- list.add(value);
- }
- map.put(key, list);
- }
- }
-
- private static synchronized ClassInjector injectorForClass(Class<?> c)
- throws NotCompliantMBeanException {
- WeakReference<ClassInjector> wr = injectorMap.get(c);
- ClassInjector ci = (wr == null) ? null : wr.get();
- if (ci == null) {
- ci = new ClassInjector(c);
- injectorMap.put(c, new WeakReference<ClassInjector>(ci));
- }
- return ci;
- }
-
- private static Map<Class<?>, WeakReference<ClassInjector>> injectorMap =
- new WeakHashMap<Class<?>, WeakReference<ClassInjector>>();
-}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Wed Oct 21 16:50:44 2009 +0100
@@ -614,15 +614,6 @@
}
/**
- * Returns the class of a primitive type.
- * @param name The type for which we the associated class.
- * @return the class, or null if name is not primitive.
- */
- public static Class<?> primitiveType(String name) {
- return primitiveClasses.get(name);
- }
-
- /**
* Load a class with the specified loader, or with this object
* class loader if the specified loader is null.
**/
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java Wed Oct 21 16:50:44 2009 +0100
@@ -36,28 +36,20 @@
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.WeakHashMap;
-import javax.management.Description;
import javax.management.Descriptor;
import javax.management.ImmutableDescriptor;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
-import javax.management.MBean;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
-import javax.management.MXBean;
-import javax.management.ManagedAttribute;
-import javax.management.ManagedOperation;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;
-import javax.management.NotificationInfo;
-import javax.management.NotificationInfos;
import javax.management.ReflectionException;
/**
@@ -79,7 +71,7 @@
* ancestor with ConvertingMethod. But that would mean an extra object
* for every Method in every Standard MBean interface.
*/
-public abstract class MBeanIntrospector<M> {
+abstract class MBeanIntrospector<M> {
static final class PerInterfaceMap<M>
extends WeakHashMap<Class<?>, WeakReference<PerInterface<M>>> {}
@@ -159,27 +151,7 @@
* may be null.
*/
abstract MBeanAttributeInfo getMBeanAttributeInfo(String attributeName,
- M getter, M setter) throws IntrospectionException;
-
- final String getAttributeDescription(
- String attributeName, String defaultDescription,
- Method getter, Method setter) throws IntrospectionException {
- String g = Introspector.descriptionForElement(getter);
- String s = Introspector.descriptionForElement(setter);
- if (g == null) {
- if (s == null)
- return defaultDescription;
- else
- return s;
- } else if (s == null || g.equals(s)) {
- return g;
- } else {
- throw new IntrospectionException(
- "Inconsistent @Description on getter and setter for " +
- "attribute " + attributeName);
- }
- }
-
+ M getter, M setter);
/**
* Construct an MBeanOperationInfo for the given operation based on
* the M it was derived from.
@@ -201,36 +173,10 @@
abstract Descriptor getMBeanDescriptor(Class<?> resourceClass);
/**
- * Get any additional Descriptor entries for this introspector instance.
- * If there is a non-default MXBeanMappingFactory, it will appear in
- * this Descriptor.
- * @return Additional Descriptor entries, or an empty Descriptor if none.
- */
- Descriptor getSpecificMBeanDescriptor() {
- return ImmutableDescriptor.EMPTY_DESCRIPTOR;
- }
-
- void checkCompliance(Class<?> mbeanType) throws NotCompliantMBeanException {
- if (!mbeanType.isInterface() &&
- !mbeanType.isAnnotationPresent(MBean.class) &&
- !Introspector.hasMXBeanAnnotation(mbeanType)) {
- throw new NotCompliantMBeanException("Not an interface and " +
- "does not have @" + MBean.class.getSimpleName() +
- " or @" + MXBean.class.getSimpleName() + " annotation: " +
- mbeanType.getName());
- }
- }
-
- /**
* Get the methods to be analyzed to build the MBean interface.
*/
List<Method> getMethods(final Class<?> mbeanType) throws Exception {
- if (mbeanType.isInterface())
- return Arrays.asList(mbeanType.getMethods());
-
- final List<Method> methods = newList();
- getAnnotatedMethods(mbeanType, methods);
- return methods;
+ return Arrays.asList(mbeanType.getMethods());
}
final PerInterface<M> getPerInterface(Class<?> mbeanInterface)
@@ -265,14 +211,11 @@
* the MBeanInfo's Descriptor.
*/
private MBeanInfo makeInterfaceMBeanInfo(Class<?> mbeanInterface,
- MBeanAnalyzer<M> analyzer) throws IntrospectionException {
+ MBeanAnalyzer<M> analyzer) {
final MBeanInfoMaker maker = new MBeanInfoMaker();
analyzer.visit(maker);
- final String defaultDescription =
+ final String description =
"Information on the management interface of the MBean";
- String description = Introspector.descriptionForElement(mbeanInterface);
- if (description == null)
- description = defaultDescription;
return maker.makeMBeanInfo(mbeanInterface, description);
}
@@ -370,11 +313,11 @@
/** A visitor that constructs the per-interface MBeanInfo. */
private class MBeanInfoMaker
- implements MBeanAnalyzer.MBeanVisitor<M, IntrospectionException> {
+ implements MBeanAnalyzer.MBeanVisitor<M> {
public void visitAttribute(String attributeName,
M getter,
- M setter) throws IntrospectionException {
+ M setter) {
MBeanAttributeInfo mbai =
getMBeanAttributeInfo(attributeName, getter, setter);
@@ -403,7 +346,7 @@
new ImmutableDescriptor(interfaceClassName);
final Descriptor mbeanDescriptor = getBasicMBeanDescriptor();
final Descriptor annotatedDescriptor =
- Introspector.descriptorForElement(mbeanInterface, false);
+ Introspector.descriptorForElement(mbeanInterface);
final Descriptor descriptor =
DescriptorCache.getInstance().union(
classNameDescriptor,
@@ -442,32 +385,20 @@
* Return the MBeanInfo for the given resource, based on the given
* per-interface data.
*/
- final MBeanInfo getMBeanInfo(Object resource, PerInterface<M> perInterface)
- throws NotCompliantMBeanException {
+ final MBeanInfo getMBeanInfo(Object resource, PerInterface<M> perInterface) {
MBeanInfo mbi =
getClassMBeanInfo(resource.getClass(), perInterface);
- MBeanNotificationInfo[] notifs;
- try {
- notifs = findNotifications(resource);
- } catch (RuntimeException e) {
- NotCompliantMBeanException x =
- new NotCompliantMBeanException(e.getMessage());
- x.initCause(e);
- throw x;
- }
- Descriptor d = getSpecificMBeanDescriptor();
- boolean anyNotifs = (notifs != null && notifs.length > 0);
- if (!anyNotifs && ImmutableDescriptor.EMPTY_DESCRIPTOR.equals(d))
+ MBeanNotificationInfo[] notifs = findNotifications(resource);
+ if (notifs == null || notifs.length == 0)
return mbi;
else {
- d = ImmutableDescriptor.union(d, mbi.getDescriptor());
return new MBeanInfo(mbi.getClassName(),
mbi.getDescription(),
mbi.getAttributes(),
mbi.getConstructors(),
mbi.getOperations(),
notifs,
- d);
+ mbi.getDescriptor());
}
}
@@ -507,145 +438,29 @@
}
}
- /*
- * Add to "methods" every public method that has the @ManagedAttribute
- * or @ManagedOperation annotation, in the given class or any of
- * its superclasses or superinterfaces.
- *
- * We always add superclass or superinterface methods first, so that
- * the stable sort used by eliminateCovariantMethods will put the
- * method from the most-derived class last. This means that we will
- * see the version of the @ManagedAttribute (or ...Operation) annotation
- * from that method, which might have a different description or whatever.
- */
- public static void getAnnotatedMethods(Class<?> c, List<Method> methods)
- throws Exception {
- Class<?> sup = c.getSuperclass();
- if (sup != null)
- getAnnotatedMethods(sup, methods);
- Class<?>[] intfs = c.getInterfaces();
- for (Class<?> intf : intfs)
- getAnnotatedMethods(intf, methods);
- for (Method m : c.getMethods()) {
- // We are careful not to add m if it is inherited from a parent
- // class or interface, because duplicate methods lead to nasty
- // behaviour in eliminateCovariantMethods.
- if (m.getDeclaringClass() == c &&
- (m.isAnnotationPresent(ManagedAttribute.class) ||
- m.isAnnotationPresent(ManagedOperation.class)))
- methods.add(m);
- }
- }
-
- /*
- * Return the array of MBeanNotificationInfo for the given MBean object.
- * If the object implements NotificationBroadcaster and its
- * getNotificationInfo() method returns a non-empty array, then that
- * is the result. Otherwise, if the object has a @NotificationInfo
- * or @NotificationInfos annotation, then its contents form the result.
- * Otherwise, the result is null.
- */
static MBeanNotificationInfo[] findNotifications(Object moi) {
- if (moi instanceof NotificationBroadcaster) {
- MBeanNotificationInfo[] mbn =
- ((NotificationBroadcaster) moi).getNotificationInfo();
- if (mbn != null && mbn.length > 0) {
- MBeanNotificationInfo[] result =
- new MBeanNotificationInfo[mbn.length];
- for (int i = 0; i < mbn.length; i++) {
- MBeanNotificationInfo ni = mbn[i];
- if (ni.getClass() != MBeanNotificationInfo.class)
- ni = (MBeanNotificationInfo) ni.clone();
- result[i] = ni;
- }
- return result;
- }
- } else {
- try {
- if (!MBeanInjector.injectsSendNotification(moi))
- return null;
- } catch (NotCompliantMBeanException e) {
- throw new RuntimeException(e);
- }
+ if (!(moi instanceof NotificationBroadcaster))
+ return null;
+ MBeanNotificationInfo[] mbn =
+ ((NotificationBroadcaster) moi).getNotificationInfo();
+ if (mbn == null)
+ return null;
+ MBeanNotificationInfo[] result =
+ new MBeanNotificationInfo[mbn.length];
+ for (int i = 0; i < mbn.length; i++) {
+ MBeanNotificationInfo ni = mbn[i];
+ if (ni.getClass() != MBeanNotificationInfo.class)
+ ni = (MBeanNotificationInfo) ni.clone();
+ result[i] = ni;
}
- return findNotificationsFromAnnotations(moi.getClass());
- }
-
- public static MBeanNotificationInfo[] findNotificationsFromAnnotations(
- Class<?> mbeanClass) {
- Class<?> c = getAnnotatedNotificationInfoClass(mbeanClass);
- if (c == null)
- return null;
- NotificationInfo ni = c.getAnnotation(NotificationInfo.class);
- NotificationInfos nis = c.getAnnotation(NotificationInfos.class);
- List<NotificationInfo> list = newList();
- if (ni != null)
- list.add(ni);
- if (nis != null)
- list.addAll(Arrays.asList(nis.value()));
- if (list.isEmpty())
- return null;
- List<MBeanNotificationInfo> mbnis = newList();
- for (NotificationInfo x : list) {
- // The Descriptor includes any fields explicitly specified by
- // x.descriptorFields(), plus any fields from the contained
- // @Description annotation.
- Descriptor d = new ImmutableDescriptor(x.descriptorFields());
- d = ImmutableDescriptor.union(
- d, Introspector.descriptorForAnnotation(x.description()));
- MBeanNotificationInfo mbni = new MBeanNotificationInfo(
- x.types(), x.notificationClass().getName(),
- x.description().value(), d);
- mbnis.add(mbni);
- }
- return mbnis.toArray(new MBeanNotificationInfo[mbnis.size()]);
- }
-
- private static final Map<Class<?>, WeakReference<Class<?>>>
- annotatedNotificationInfoClasses = newWeakHashMap();
-
- private static Class<?> getAnnotatedNotificationInfoClass(Class<?> baseClass) {
- synchronized (annotatedNotificationInfoClasses) {
- WeakReference<Class<?>> wr =
- annotatedNotificationInfoClasses.get(baseClass);
- if (wr != null)
- return wr.get();
- Class<?> c = null;
- if (baseClass.isAnnotationPresent(NotificationInfo.class) ||
- baseClass.isAnnotationPresent(NotificationInfos.class)) {
- c = baseClass;
- } else {
- Class<?>[] intfs = baseClass.getInterfaces();
- for (Class<?> intf : intfs) {
- Class<?> c1 = getAnnotatedNotificationInfoClass(intf);
- if (c1 != null) {
- if (c != null) {
- throw new IllegalArgumentException(
- "Class " + baseClass.getName() + " inherits " +
- "@NotificationInfo(s) from both " +
- c.getName() + " and " + c1.getName());
- }
- c = c1;
- }
- }
- }
- // Record the result of the search. If no @NotificationInfo(s)
- // were found, c is null, and we store a WeakReference(null).
- // This prevents us from having to search again and fail again.
- annotatedNotificationInfoClasses.put(baseClass,
- new WeakReference<Class<?>>(c));
- return c;
- }
+ return result;
}
private static MBeanConstructorInfo[] findConstructors(Class<?> c) {
Constructor<?>[] cons = c.getConstructors();
MBeanConstructorInfo[] mbc = new MBeanConstructorInfo[cons.length];
for (int i = 0; i < cons.length; i++) {
- String descr = "Public constructor of the MBean";
- Description d = cons[i].getAnnotation(Description.class);
- if (d != null)
- descr = d.value();
+ final String descr = "Public constructor of the MBean";
mbc[i] = new MBeanConstructorInfo(descr, cons[i]);
}
return mbc;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -37,7 +37,7 @@
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-import javax.management.openmbean.MXBeanMappingFactory;
+import com.sun.jmx.mbeanserver.MXBeanMappingFactory;
/**
* Base class for MBeans. There is one instance of this class for
@@ -121,8 +121,7 @@
public abstract class MBeanSupport<M>
implements DynamicMBean2, MBeanRegistration {
- <T> MBeanSupport(T resource, Class<T> mbeanInterfaceType,
- MXBeanMappingFactory mappingFactory)
+ <T> MBeanSupport(T resource, Class<T> mbeanInterfaceType)
throws NotCompliantMBeanException {
if (mbeanInterfaceType == null)
throw new NotCompliantMBeanException("Null MBean interface");
@@ -133,14 +132,13 @@
throw new NotCompliantMBeanException(msg);
}
this.resource = resource;
- MBeanIntrospector<M> introspector = getMBeanIntrospector(mappingFactory);
+ MBeanIntrospector<M> introspector = getMBeanIntrospector();
this.perInterface = introspector.getPerInterface(mbeanInterfaceType);
this.mbeanInfo = introspector.getMBeanInfo(resource, perInterface);
}
/** Return the appropriate introspector for this type of MBean. */
- abstract MBeanIntrospector<M>
- getMBeanIntrospector(MXBeanMappingFactory mappingFactory);
+ abstract MBeanIntrospector<M> getMBeanIntrospector();
/**
* Return a cookie for this MBean. This cookie will be passed to
@@ -262,14 +260,10 @@
return resource.getClass().getName();
}
- public final Object getWrappedObject() {
+ public final Object getResource() {
return resource;
}
- public final ClassLoader getWrappedClassLoader() {
- return resource.getClass().getClassLoader();
- }
-
public final Class<?> getMBeanInterface() {
return perInterface.getMBeanInterface();
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java Wed Oct 21 16:50:44 2009 +0100
@@ -28,26 +28,18 @@
import com.sun.jmx.mbeanserver.MBeanIntrospector.MBeanInfoMap;
import com.sun.jmx.mbeanserver.MBeanIntrospector.PerInterfaceMap;
import java.lang.annotation.Annotation;
-import java.lang.ref.WeakReference;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.util.Map;
-import java.util.WeakHashMap;
-import javax.management.Description;
import javax.management.Descriptor;
import javax.management.ImmutableDescriptor;
-import javax.management.IntrospectionException;
-import javax.management.JMX;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
-import javax.management.ManagedOperation;
import javax.management.NotCompliantMBeanException;
-import javax.management.openmbean.MXBeanMappingFactory;
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
import javax.management.openmbean.OpenMBeanOperationInfoSupport;
import javax.management.openmbean.OpenMBeanParameterInfo;
@@ -60,36 +52,10 @@
* @since 1.6
*/
class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
- /* We keep one MXBeanIntrospector per MXBeanMappingFactory, since the results
- * of the introspection depend on the factory. The MXBeanIntrospector
- * has a reference back to the factory, so we wrap it in a WeakReference.
- * It will be strongly referenced by any MXBeanSupport instances using it;
- * if there are none then it is OK to gc it.
- */
- private static final
- Map<MXBeanMappingFactory, WeakReference<MXBeanIntrospector>> map =
- new WeakHashMap<MXBeanMappingFactory, WeakReference<MXBeanIntrospector>>();
+ private static final MXBeanIntrospector instance = new MXBeanIntrospector();
- static MXBeanIntrospector getInstance(MXBeanMappingFactory factory) {
- if (factory == null)
- factory = MXBeanMappingFactory.DEFAULT;
- synchronized (map) {
- MXBeanIntrospector intro;
- WeakReference<MXBeanIntrospector> wr = map.get(factory);
- if (wr != null) {
- intro = wr.get();
- if (intro != null)
- return intro;
- }
- intro = new MXBeanIntrospector(factory);
- wr = new WeakReference<MXBeanIntrospector>(intro);
- map.put(factory, wr);
- return intro;
- }
- }
-
- private MXBeanIntrospector(MXBeanMappingFactory factory) {
- this.mappingFactory = factory;
+ static MXBeanIntrospector getInstance() {
+ return instance;
}
@Override
@@ -115,7 +81,7 @@
@Override
ConvertingMethod mFrom(Method m) {
- return ConvertingMethod.from(m, mappingFactory);
+ return ConvertingMethod.from(m);
}
@Override
@@ -176,17 +142,13 @@
@Override
MBeanAttributeInfo getMBeanAttributeInfo(String attributeName,
- ConvertingMethod getter, ConvertingMethod setter)
- throws IntrospectionException {
+ ConvertingMethod getter, ConvertingMethod setter) {
final boolean isReadable = (getter != null);
final boolean isWritable = (setter != null);
final boolean isIs = isReadable && getName(getter).startsWith("is");
- final String description = getAttributeDescription(
- attributeName, attributeName,
- getter == null ? null : getter.getMethod(),
- setter == null ? null : setter.getMethod());
+ final String description = attributeName;
final OpenType<?> openType;
final Type originalType;
@@ -235,17 +197,13 @@
MBeanOperationInfo getMBeanOperationInfo(String operationName,
ConvertingMethod operation) {
final Method method = operation.getMethod();
- String description = operationName;
+ final String description = operationName;
/* Ideally this would be an empty string, but
- OMBOperationInfo constructor forbids that. */
- Description d = method.getAnnotation(Description.class);
- if (d != null)
- description = d.value();
+ OMBOperationInfo constructor forbids that. Also, we
+ could consult an annotation to get a useful
+ description. */
- int impact = MBeanOperationInfo.UNKNOWN;
- ManagedOperation annot = method.getAnnotation(ManagedOperation.class);
- if (annot != null)
- impact = annot.impact().getCode();
+ final int impact = MBeanOperationInfo.UNKNOWN;
final OpenType<?> returnType = operation.getOpenReturnType();
final Type originalReturnType = operation.getGenericReturnType();
@@ -257,15 +215,8 @@
boolean openParameterTypes = true;
Annotation[][] annots = method.getParameterAnnotations();
for (int i = 0; i < paramTypes.length; i++) {
- String paramName = Introspector.nameForParameter(annots[i]);
- if (paramName == null)
- paramName = "p" + i;
-
- String paramDescription =
- Introspector.descriptionForParameter(annots[i]);
- if (paramDescription == null)
- paramDescription = paramName;
-
+ final String paramName = "p" + i;
+ final String paramDescription = paramName;
final OpenType<?> openType = paramTypes[i];
final Type originalType = originalParamTypes[i];
Descriptor descriptor =
@@ -292,7 +243,7 @@
Descriptor descriptor =
typeDescriptor(returnType, originalReturnType);
descriptor = ImmutableDescriptor.union(descriptor,
- Introspector.descriptorForElement(method, false));
+ Introspector.descriptorForElement(method));
final MBeanOperationInfo oi;
if (openReturnType && openParameterTypes) {
/* If the return value and all the parameters can be faithfully
@@ -343,17 +294,6 @@
return ImmutableDescriptor.EMPTY_DESCRIPTOR;
}
- @Override
- Descriptor getSpecificMBeanDescriptor() {
- if (mappingFactory == MXBeanMappingFactory.DEFAULT)
- return ImmutableDescriptor.EMPTY_DESCRIPTOR;
- else {
- return new ImmutableDescriptor(
- JMX.MXBEAN_MAPPING_FACTORY_CLASS_FIELD + "=" +
- mappingFactory.getClass().getName());
- }
- }
-
private static Descriptor typeDescriptor(OpenType<?> openType,
Type originalType) {
return new ImmutableDescriptor(
@@ -421,7 +361,5 @@
private final PerInterfaceMap<ConvertingMethod>
perInterfaceMap = new PerInterfaceMap<ConvertingMethod>();
- private final MBeanInfoMap mbeanInfoMap = new MBeanInfoMap();
-
- private final MXBeanMappingFactory mappingFactory;
+ private static final MBeanInfoMap mbeanInfoMap = new MBeanInfoMap();
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,8 +25,6 @@
package com.sun.jmx.mbeanserver;
-import com.sun.jmx.remote.util.EnvHelp;
-import java.io.InvalidObjectException;
import static com.sun.jmx.mbeanserver.Util.*;
import java.util.Map;
import java.lang.ref.WeakReference;
@@ -85,181 +83,87 @@
*
* From the above, it is clear that the logic for getX on an MXBean is
* the same as for setX on a proxy, and vice versa.
- *
- * The above describes the logic for "plain" MXBeanLookup, represented
- * by MXBeanLookup.Plain. When namespaces enter the picture, we see
- * MXBeanLookup.Prefix. Here, the idea is that the name of the ModuleMXBean
- * might be a//m:m=m. In this case, we don't accept a reference to
- * an MXBean object, since that would require different namespaces to know
- * each others' objects. We only accept proxies. Suppose you have a proxy
- * for a//m:m=m, call it moduleProxy, and you call
- * moduleProxy.setProduct(productProxy). Then if productProxy is for
- * a//p:p=p we should convert this to just p:p=p. If productProxy is for
- * a//b//p:p=p we should convert it to b//p:p=p. Conversely, if getProduct
- * returns an ObjectName like b//p:p=p then we should convert it into a proxy
- * for a//b//p:p=p.
*/
-public abstract class MXBeanLookup {
+public class MXBeanLookup {
private MXBeanLookup(MBeanServerConnection mbsc) {
this.mbsc = mbsc;
}
- static MXBeanLookup lookupFor(MBeanServerConnection mbsc, String prefix) {
- if (prefix == null)
- return Plain.lookupFor(mbsc);
- else
- return new Prefix(mbsc, prefix);
- }
-
- abstract <T> T objectNameToMXBean(ObjectName name, Class<T> type)
- throws InvalidObjectException;
-
- abstract ObjectName mxbeanToObjectName(Object mxbean)
- throws OpenDataException;
-
- static class Plain extends MXBeanLookup {
- Plain(MBeanServerConnection mbsc) {
- super(mbsc);
- }
-
- static Plain lookupFor(MBeanServerConnection mbsc) {
- synchronized (mbscToLookup) {
- WeakReference<Plain> weakLookup = mbscToLookup.get(mbsc);
- Plain lookup = (weakLookup == null) ? null : weakLookup.get();
- if (lookup == null) {
- lookup = new Plain(mbsc);
- mbscToLookup.put(mbsc, new WeakReference<Plain>(lookup));
- }
- return lookup;
- }
- }
-
- @Override
- synchronized <T> T objectNameToMXBean(ObjectName name, Class<T> type) {
- WeakReference<Object> wr = objectNameToProxy.get(name);
- if (wr != null) {
- Object proxy = wr.get();
- if (type.isInstance(proxy))
- return type.cast(proxy);
- }
- T proxy = JMX.newMXBeanProxy(mbsc, name, type);
- objectNameToProxy.put(name, new WeakReference<Object>(proxy));
- return proxy;
- }
-
- @Override
- synchronized ObjectName mxbeanToObjectName(Object mxbean)
- throws OpenDataException {
- String wrong;
- if (mxbean instanceof Proxy) {
- InvocationHandler ih = Proxy.getInvocationHandler(mxbean);
- if (ih instanceof MBeanServerInvocationHandler) {
- MBeanServerInvocationHandler mbsih =
- (MBeanServerInvocationHandler) ih;
- if (mbsih.getMBeanServerConnection().equals(mbsc))
- return mbsih.getObjectName();
- else
- wrong = "proxy for a different MBeanServer";
- } else
- wrong = "not a JMX proxy";
- } else {
- ObjectName name = mxbeanToObjectName.get(mxbean);
- if (name != null)
- return name;
- wrong = "not an MXBean registered in this MBeanServer";
+ static MXBeanLookup lookupFor(MBeanServerConnection mbsc) {
+ synchronized (mbscToLookup) {
+ WeakReference<MXBeanLookup> weakLookup = mbscToLookup.get(mbsc);
+ MXBeanLookup lookup = (weakLookup == null) ? null : weakLookup.get();
+ if (lookup == null) {
+ lookup = new MXBeanLookup(mbsc);
+ mbscToLookup.put(mbsc, new WeakReference<MXBeanLookup>(lookup));
}
- String s = (mxbean == null) ?
- "null" : "object of type " + mxbean.getClass().getName();
- throw new OpenDataException(
- "Could not convert " + s + " to an ObjectName: " + wrong);
- // Message will be strange if mxbean is null but it is not
- // supposed to be.
- }
-
- synchronized void addReference(ObjectName name, Object mxbean)
- throws InstanceAlreadyExistsException {
- ObjectName existing = mxbeanToObjectName.get(mxbean);
- if (existing != null) {
- String multiname = AccessController.doPrivileged(
- new GetPropertyAction("jmx.mxbean.multiname"));
- if (!"true".equalsIgnoreCase(multiname)) {
- throw new InstanceAlreadyExistsException(
- "MXBean already registered with name " + existing);
- }
- }
- mxbeanToObjectName.put(mxbean, name);
- }
-
- synchronized boolean removeReference(ObjectName name, Object mxbean) {
- if (name.equals(mxbeanToObjectName.get(mxbean))) {
- mxbeanToObjectName.remove(mxbean);
- return true;
- } else
- return false;
- /* removeReference can be called when the above condition fails,
- * notably if you try to register the same MXBean twice.
- */
- }
-
- private final WeakIdentityHashMap<Object, ObjectName>
- mxbeanToObjectName = WeakIdentityHashMap.make();
- private final Map<ObjectName, WeakReference<Object>>
- objectNameToProxy = newMap();
- private static WeakIdentityHashMap<MBeanServerConnection,
- WeakReference<Plain>>
- mbscToLookup = WeakIdentityHashMap.make();
- }
-
- private static class Prefix extends MXBeanLookup {
- private final String prefix;
-
- Prefix(MBeanServerConnection mbsc, String prefix) {
- super(mbsc);
- this.prefix = prefix;
- }
-
- @Override
- <T> T objectNameToMXBean(ObjectName name, Class<T> type)
- throws InvalidObjectException {
- String domain = prefix + name.getDomain();
- try {
- name = name.withDomain(domain);
- } catch (IllegalArgumentException e) {
- throw EnvHelp.initCause(
- new InvalidObjectException(e.getMessage()), e);
- }
- return JMX.newMXBeanProxy(mbsc, name, type);
- }
-
- @Override
- ObjectName mxbeanToObjectName(Object mxbean)
- throws OpenDataException {
- ObjectName name = proxyToObjectName(mxbean);
- String domain = name.getDomain();
- if (!domain.startsWith(prefix)) {
- throw new OpenDataException(
- "Proxy's name does not start with " +
- prefix + ": " + name);
- }
- try {
- name = name.withDomain(domain.substring(prefix.length()));
- } catch (IllegalArgumentException e) {
- throw EnvHelp.initCause(
- new OpenDataException(e.getMessage()), e);
- }
- return name;
+ return lookup;
}
}
- ObjectName proxyToObjectName(Object proxy) {
- InvocationHandler ih = Proxy.getInvocationHandler(proxy);
- if (ih instanceof MBeanServerInvocationHandler) {
- MBeanServerInvocationHandler mbsih =
- (MBeanServerInvocationHandler) ih;
- if (mbsih.getMBeanServerConnection().equals(mbsc))
- return mbsih.getObjectName();
+ synchronized <T> T objectNameToMXBean(ObjectName name, Class<T> type) {
+ WeakReference<Object> wr = objectNameToProxy.get(name);
+ if (wr != null) {
+ Object proxy = wr.get();
+ if (type.isInstance(proxy))
+ return type.cast(proxy);
+ }
+ T proxy = JMX.newMXBeanProxy(mbsc, name, type);
+ objectNameToProxy.put(name, new WeakReference<Object>(proxy));
+ return proxy;
+ }
+
+ synchronized ObjectName mxbeanToObjectName(Object mxbean)
+ throws OpenDataException {
+ String wrong;
+ if (mxbean instanceof Proxy) {
+ InvocationHandler ih = Proxy.getInvocationHandler(mxbean);
+ if (ih instanceof MBeanServerInvocationHandler) {
+ MBeanServerInvocationHandler mbsih =
+ (MBeanServerInvocationHandler) ih;
+ if (mbsih.getMBeanServerConnection().equals(mbsc))
+ return mbsih.getObjectName();
+ else
+ wrong = "proxy for a different MBeanServer";
+ } else
+ wrong = "not a JMX proxy";
+ } else {
+ ObjectName name = mxbeanToObjectName.get(mxbean);
+ if (name != null)
+ return name;
+ wrong = "not an MXBean registered in this MBeanServer";
}
- return null;
+ String s = (mxbean == null) ?
+ "null" : "object of type " + mxbean.getClass().getName();
+ throw new OpenDataException(
+ "Could not convert " + s + " to an ObjectName: " + wrong);
+ // Message will be strange if mxbean is null but it is not
+ // supposed to be.
+ }
+
+ synchronized void addReference(ObjectName name, Object mxbean)
+ throws InstanceAlreadyExistsException {
+ ObjectName existing = mxbeanToObjectName.get(mxbean);
+ if (existing != null) {
+ String multiname = AccessController.doPrivileged(
+ new GetPropertyAction("jmx.mxbean.multiname"));
+ if (!"true".equalsIgnoreCase(multiname)) {
+ throw new InstanceAlreadyExistsException(
+ "MXBean already registered with name " + existing);
+ }
+ }
+ mxbeanToObjectName.put(mxbean, name);
+ }
+
+ synchronized boolean removeReference(ObjectName name, Object mxbean) {
+ if (name.equals(mxbeanToObjectName.get(mxbean))) {
+ mxbeanToObjectName.remove(mxbean);
+ return true;
+ } else
+ return false;
+ /* removeReference can be called when the above condition fails,
+ * notably if you try to register the same MXBean twice.
+ */
}
static MXBeanLookup getLookup() {
@@ -273,5 +177,12 @@
private static final ThreadLocal<MXBeanLookup> currentLookup =
new ThreadLocal<MXBeanLookup>();
- final MBeanServerConnection mbsc;
+ private final MBeanServerConnection mbsc;
+ private final WeakIdentityHashMap<Object, ObjectName>
+ mxbeanToObjectName = WeakIdentityHashMap.make();
+ private final Map<ObjectName, WeakReference<Object>>
+ objectNameToProxy = newMap();
+ private static final WeakIdentityHashMap<MBeanServerConnection,
+ WeakReference<MXBeanLookup>>
+ mbscToLookup = WeakIdentityHashMap.make();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanMapping.java Wed Oct 21 16:50:44 2009 +0100
@@ -0,0 +1,210 @@
+/*
+ * 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.mbeanserver;
+
+import java.io.InvalidObjectException;
+import java.lang.reflect.Type;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+
+/**
+ * <p>A custom mapping between Java types and Open types for use in MXBeans.
+ * To define such a mapping, subclass this class and define at least the
+ * {@link #fromOpenValue fromOpenValue} and {@link #toOpenValue toOpenValue}
+ * methods, and optionally the {@link #checkReconstructible} method.
+ * Then either use an {@link MXBeanMappingClass} annotation on your custom
+ * Java types, or include this MXBeanMapping in an
+ * {@link MXBeanMappingFactory}.</p>
+ *
+ * <p>For example, suppose we have a class {@code MyLinkedList}, which looks
+ * like this:</p>
+ *
+ * <pre>
+ * public class MyLinkedList {
+ * public MyLinkedList(String name, MyLinkedList next) {...}
+ * public String getName() {...}
+ * public MyLinkedList getNext() {...}
+ * }
+ * </pre>
+ *
+ * <p>This is not a valid type for MXBeans, because it contains a
+ * self-referential property "next" defined by the {@code getNext()}
+ * method. MXBeans do not support recursive types. So we would like
+ * to specify a mapping for {@code MyLinkedList} explicitly. When an
+ * MXBean interface contains {@code MyLinkedList}, that will be mapped
+ * into a {@code String[]}, which is a valid Open Type.</p>
+ *
+ * <p>To define this mapping, we first subclass {@code MXBeanMapping}:</p>
+ *
+ * <pre>
+ * public class MyLinkedListMapping extends MXBeanMapping {
+ * public MyLinkedListMapping(Type type) throws OpenDataException {
+ * super(MyLinkedList.class, ArrayType.getArrayType(SimpleType.STRING));
+ * if (type != MyLinkedList.class)
+ * throw new OpenDataException("Mapping only valid for MyLinkedList");
+ * }
+ *
+ * {@literal @Override}
+ * public Object fromOpenValue(Object openValue) throws InvalidObjectException {
+ * String[] array = (String[]) openValue;
+ * MyLinkedList list = null;
+ * for (int i = array.length - 1; i >= 0; i--)
+ * list = new MyLinkedList(array[i], list);
+ * return list;
+ * }
+ *
+ * {@literal @Override}
+ * public Object toOpenValue(Object javaValue) throws OpenDataException {
+ * ArrayList<String> array = new ArrayList<String>();
+ * for (MyLinkedList list = (MyLinkedList) javaValue; list != null;
+ * list = list.getNext())
+ * array.add(list.getName());
+ * return array.toArray(new String[0]);
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The call to the superclass constructor specifies what the
+ * original Java type is ({@code MyLinkedList.class}) and what Open
+ * Type it is mapped to ({@code
+ * ArrayType.getArrayType(SimpleType.STRING)}). The {@code
+ * fromOpenValue} method says how we go from the Open Type ({@code
+ * String[]}) to the Java type ({@code MyLinkedList}), and the {@code
+ * toOpenValue} method says how we go from the Java type to the Open
+ * Type.</p>
+ *
+ * <p>With this mapping defined, we can annotate the {@code MyLinkedList}
+ * class appropriately:</p>
+ *
+ * <pre>
+ * {@literal @MXBeanMappingClass}(MyLinkedListMapping.class)
+ * public class MyLinkedList {...}
+ * </pre>
+ *
+ * <p>Now we can use {@code MyLinkedList} in an MXBean interface and it
+ * will work.</p>
+ *
+ * <p>If we are unable to modify the {@code MyLinkedList} class,
+ * we can define an {@link MXBeanMappingFactory}. See the documentation
+ * of that class for further details.</p>
+ *
+ * @see <a href="../MXBean.html#custom">MXBean specification, section
+ * "Custom MXBean type mappings"</a>
+ */
+public abstract class MXBeanMapping {
+ private final Type javaType;
+ private final OpenType<?> openType;
+ private final Class<?> openClass;
+
+ /**
+ * <p>Construct a mapping between the given Java type and the given
+ * Open Type.</p>
+ *
+ * @param javaType the Java type (for example, {@code MyLinkedList}).
+ * @param openType the Open Type (for example, {@code
+ * ArrayType.getArrayType(SimpleType.STRING)})
+ *
+ * @throws NullPointerException if either argument is null.
+ */
+ protected MXBeanMapping(Type javaType, OpenType<?> openType) {
+ if (javaType == null || openType == null)
+ throw new NullPointerException("Null argument");
+ this.javaType = javaType;
+ this.openType = openType;
+ this.openClass = makeOpenClass(javaType, openType);
+ }
+
+ /**
+ * <p>The Java type that was supplied to the constructor.</p>
+ * @return the Java type that was supplied to the constructor.
+ */
+ public final Type getJavaType() {
+ return javaType;
+ }
+
+ /**
+ * <p>The Open Type that was supplied to the constructor.</p>
+ * @return the Open Type that was supplied to the constructor.
+ */
+ public final OpenType<?> getOpenType() {
+ return openType;
+ }
+
+ /**
+ * <p>The Java class that corresponds to instances of the
+ * {@linkplain #getOpenType() Open Type} for this mapping.</p>
+ * @return the Java class that corresponds to instances of the
+ * Open Type for this mapping.
+ * @see OpenType#getClassName
+ */
+ public final Class<?> getOpenClass() {
+ return openClass;
+ }
+
+ private static Class<?> makeOpenClass(Type javaType, OpenType<?> openType) {
+ if (javaType instanceof Class<?> && ((Class<?>) javaType).isPrimitive())
+ return (Class<?>) javaType;
+ try {
+ String className = openType.getClassName();
+ return Class.forName(className, false, null);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e); // should not happen
+ }
+ }
+
+ /**
+ * <p>Convert an instance of the Open Type into the Java type.
+ * @param openValue the value to be converted.
+ * @return the converted value.
+ * @throws InvalidObjectException if the value cannot be converted.
+ */
+ public abstract Object fromOpenValue(Object openValue)
+ throws InvalidObjectException;
+
+ /**
+ * <p>Convert an instance of the Java type into the Open Type.
+ * @param javaValue the value to be converted.
+ * @return the converted value.
+ * @throws OpenDataException if the value cannot be converted.
+ */
+ public abstract Object toOpenValue(Object javaValue)
+ throws OpenDataException;
+
+
+ /**
+ * <p>Throw an appropriate InvalidObjectException if we will not
+ * be able to convert back from the open data to the original Java
+ * object. The {@link #fromOpenValue fromOpenValue} throws an
+ * exception if a given open data value cannot be converted. This
+ * method throws an exception if <em>no</em> open data values can
+ * be converted. The default implementation of this method never
+ * throws an exception. Subclasses can override it as
+ * appropriate.</p>
+ * @throws InvalidObjectException if {@code fromOpenValue} will throw
+ * an exception no matter what its argument is.
+ */
+ public void checkReconstructible() throws InvalidObjectException {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanMappingFactory.java Wed Oct 21 16:50:44 2009 +0100
@@ -0,0 +1,124 @@
+/*
+ * 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.mbeanserver;
+
+import javax.management.openmbean.*;
+import com.sun.jmx.mbeanserver.MXBeanMapping;
+import com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory;
+import java.lang.reflect.Type;
+
+/**
+ * <p>Defines how types are mapped for a given MXBean or set of MXBeans.
+ * An {@code MXBeanMappingFactory} can be specified either through the
+ * {@link MXBeanMappingFactoryClass} annotation, or through the
+ * {@link javax.management.JMX.MBeanOptions JMX.MBeanOptions} argument to a
+ * {@link javax.management.StandardMBean StandardMBean} constructor or MXBean
+ * proxy.</p>
+ *
+ * <p>An {@code MXBeanMappingFactory} must return an {@code MXBeanMapping}
+ * for any Java type that appears in the MXBeans that the factory is being
+ * used for. Usually it does that by handling any custom types, and
+ * forwarding everything else to the {@linkplain #DEFAULT default mapping
+ * factory}.</p>
+ *
+ * <p>Consider the {@code MyLinkedList} example from the {@link MXBeanMapping}
+ * documentation. If we are unable to change the {@code MyLinkedList} class
+ * to add an {@link MXBeanMappingClass} annotation, we could achieve the same
+ * effect by defining {@code MyLinkedListMappingFactory} as follows:</p>
+ *
+ * <pre>
+ * public class MyLinkedListMappingFactory extends MXBeanMappingFactory {
+ * public MyLinkedListMappingFactory() {}
+ *
+ * public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
+ * throws OpenDataException {
+ * if (t == MyLinkedList.class)
+ * return new MyLinkedListMapping(t);
+ * else
+ * return MXBeanMappingFactory.DEFAULT.mappingForType(t, f);
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The mapping factory handles only the {@code MyLinkedList} class.
+ * Every other type is forwarded to the default mapping factory.
+ * This includes types such as {@code MyLinkedList[]} and
+ * {@code List<MyLinkedList>}; the default mapping factory will recursively
+ * invoke {@code MyLinkedListMappingFactory} to map the contained
+ * {@code MyLinkedList} type.</p>
+ *
+ * <p>Once we have defined {@code MyLinkedListMappingFactory}, we can use
+ * it in an MXBean interface like this:</p>
+ *
+ * <pre>
+ * {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
+ * public interface SomethingMXBean {
+ * public MyLinkedList getSomething();
+ * }
+ * </pre>
+ *
+ * <p>Alternatively we can annotate the package that {@code SomethingMXBean}
+ * appears in, or we can supply the factory to a {@link
+ * javax.management.StandardMBean StandardMBean} constructor or MXBean
+ * proxy.</p>
+ *
+ * @see <a href="../MXBean.html#custom">MXBean specification, section
+ * "Custom MXBean type mappings"</a>
+ */
+public abstract class MXBeanMappingFactory {
+ /**
+ * <p>Construct an instance of this class.</p>
+ */
+ protected MXBeanMappingFactory() {}
+
+ /**
+ * <p>Mapping factory that applies the default rules for MXBean
+ * mappings, as described in the <a
+ * href="../MXBean.html#MXBean-spec">MXBean specification</a>.</p>
+ */
+ public static final MXBeanMappingFactory DEFAULT =
+ new DefaultMXBeanMappingFactory();
+
+ /**
+ * <p>Return the mapping for the given Java type. Typically, a
+ * mapping factory will return mappings for types it handles, and
+ * forward other types to another mapping factory, most often
+ * the {@linkplain #DEFAULT default one}.</p>
+ * @param t the Java type to be mapped.
+ * @param f the original mapping factory that was consulted to do
+ * the mapping. A mapping factory should pass this parameter intact
+ * if it forwards a type to another mapping factory. In the example,
+ * this is how {@code MyLinkedListMappingFactory} works for types
+ * like {@code MyLinkedList[]} and {@code List<MyLinkedList>}.
+ * @return the mapping for the given type.
+ * @throws OpenDataException if this type cannot be mapped. This
+ * exception is appropriate if the factory is supposed to handle
+ * all types of this sort (for example, all linked lists), but
+ * cannot handle this particular type.
+ */
+ public abstract MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
+ throws OpenDataException;
+}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanProxy.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanProxy.java Wed Oct 21 16:50:44 2009 +0100
@@ -32,10 +32,8 @@
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
-import javax.management.openmbean.MXBeanMappingFactory;
/**
<p>Helper class for an {@link InvocationHandler} that forwards methods from an
@@ -47,7 +45,7 @@
@since 1.6
*/
public class MXBeanProxy {
- public MXBeanProxy(Class<?> mxbeanInterface, MXBeanMappingFactory factory) {
+ public MXBeanProxy(Class<?> mxbeanInterface) {
if (mxbeanInterface == null)
throw new IllegalArgumentException("Null parameter");
@@ -55,7 +53,7 @@
final MBeanAnalyzer<ConvertingMethod> analyzer;
try {
analyzer =
- MXBeanIntrospector.getInstance(factory).getAnalyzer(mxbeanInterface);
+ MXBeanIntrospector.getInstance().getAnalyzer(mxbeanInterface);
} catch (NotCompliantMBeanException e) {
throw new IllegalArgumentException(e);
}
@@ -63,7 +61,7 @@
}
private class Visitor
- implements MBeanAnalyzer.MBeanVisitor<ConvertingMethod, RuntimeException> {
+ implements MBeanAnalyzer.MBeanVisitor<ConvertingMethod> {
public void visitAttribute(String attributeName,
ConvertingMethod getter,
ConvertingMethod setter) {
@@ -161,8 +159,7 @@
Handler handler = handlerMap.get(method);
ConvertingMethod cm = handler.getConvertingMethod();
- String prefix = extractPrefix(name);
- MXBeanLookup lookup = MXBeanLookup.lookupFor(mbsc, prefix);
+ MXBeanLookup lookup = MXBeanLookup.lookupFor(mbsc);
MXBeanLookup oldLookup = MXBeanLookup.getLookup();
try {
MXBeanLookup.setLookup(lookup);
@@ -174,17 +171,5 @@
}
}
- private static String extractPrefix(ObjectName name)
- throws MalformedObjectNameException {
- String domain = name.getDomain();
- int slashslash = domain.lastIndexOf("//");
- if (slashslash > 0 && domain.charAt(slashslash - 1) == '/')
- slashslash--;
- if (slashslash >= 0)
- return domain.substring(0, slashslash + 2);
- else
- return null;
- }
-
private final Map<Method, Handler> handlerMap = newMap();
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -35,7 +35,6 @@
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
-import javax.management.openmbean.MXBeanMappingFactory;
/**
* Base class for MXBeans.
@@ -62,16 +61,14 @@
if it does not implement the class {@code mxbeanInterface} or if
that class is not a valid MXBean interface.
*/
- public <T> MXBeanSupport(T resource, Class<T> mxbeanInterface,
- MXBeanMappingFactory mappingFactory)
+ public <T> MXBeanSupport(T resource, Class<T> mxbeanInterface)
throws NotCompliantMBeanException {
- super(resource, mxbeanInterface, mappingFactory);
+ super(resource, mxbeanInterface);
}
@Override
- MBeanIntrospector<ConvertingMethod>
- getMBeanIntrospector(MXBeanMappingFactory mappingFactory) {
- return MXBeanIntrospector.getInstance(mappingFactory);
+ MBeanIntrospector<ConvertingMethod> getMBeanIntrospector() {
+ return MXBeanIntrospector.getInstance();
}
@Override
@@ -159,8 +156,8 @@
// eventually we could have some logic to supply a default name
synchronized (lock) {
- this.mxbeanLookup = MXBeanLookup.Plain.lookupFor(server);
- this.mxbeanLookup.addReference(name, getWrappedObject());
+ this.mxbeanLookup = MXBeanLookup.lookupFor(server);
+ this.mxbeanLookup.addReference(name, getResource());
this.objectName = name;
}
}
@@ -169,19 +166,13 @@
public void unregister() {
synchronized (lock) {
if (mxbeanLookup != null) {
- if (mxbeanLookup.removeReference(objectName, getWrappedObject()))
+ if (mxbeanLookup.removeReference(objectName, getResource()))
objectName = null;
}
- // XXX: need to revisit the whole register/unregister logic in
- // the face of wrapping. The mxbeanLookup!=null test is a hack.
- // If you wrap an MXBean in a MyWrapperMBean and register it,
- // the lookup table should contain the wrapped object. But that
- // implies that MyWrapperMBean calls register, which today it
- // can't within the public API.
}
}
private final Object lock = new Object(); // for mxbeanLookup and objectName
- private MXBeanLookup.Plain mxbeanLookup;
+ private MXBeanLookup mxbeanLookup;
private ObjectName objectName;
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +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.mbeanserver;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.openmbean.MXBeanMappingFactory;
-
-/**
- * <p>A variant of {@code StandardMBeanSupport} where the only
- * methods included are public getters. This is used by
- * {@code QueryNotificationFilter} to pretend that a Notification is
- * an MBean so it can have a query evaluated on it. Standard queries
- * never set attributes or invoke methods but custom queries could and
- * we don't want to allow that. Also we don't want to fail if a
- * Notification happens to have inconsistent types in a pair of getX and
- * setX methods, and we want to include the Object.getClass() method.
- */
-public class NotificationMBeanSupport extends StandardMBeanSupport {
- public <T extends Notification> NotificationMBeanSupport(T n)
- throws NotCompliantMBeanException {
- super(n, Util.<Class<T>>cast(n.getClass()));
- }
-
- @Override
- MBeanIntrospector<Method> getMBeanIntrospector(MXBeanMappingFactory ignored) {
- return introspector;
- }
-
- private static class Introspector extends StandardMBeanIntrospector {
- @Override
- void checkCompliance(Class<?> mbeanType) {}
-
- @Override
- List<Method> getMethods(final Class<?> mbeanType)
- throws Exception {
- List<Method> methods = new ArrayList<Method>();
- for (Method m : mbeanType.getMethods()) {
- String name = m.getName();
- Class<?> ret = m.getReturnType();
- if (m.getParameterTypes().length == 0) {
- if ((name.startsWith("is") && name.length() > 2 &&
- ret == boolean.class) ||
- (name.startsWith("get") && name.length() > 3 &&
- ret != void.class)) {
- methods.add(m);
- }
- }
- }
- return methods;
- }
-
- }
- private static final MBeanIntrospector<Method> introspector =
- new Introspector();
-}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +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.mbeanserver;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.DynamicWrapperMBean;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-
-/**
- * Create wrappers for DynamicMBean that implement NotificationEmitter
- * and SendNotification.
- */
-public class NotifySupport
- implements DynamicMBean2, NotificationEmitter, MBeanRegistration {
-
- private final DynamicMBean mbean;
- private final NotificationBroadcasterSupport nbs;
-
- public static DynamicMBean wrap(
- DynamicMBean mbean, NotificationBroadcasterSupport nbs) {
- return new NotifySupport(mbean, nbs);
- }
-
- private NotifySupport(DynamicMBean mbean, NotificationBroadcasterSupport nbs) {
- this.mbean = mbean;
- this.nbs = nbs;
- }
-
- public static NotificationBroadcasterSupport getNB(DynamicMBean mbean) {
- if (mbean instanceof NotifySupport)
- return ((NotifySupport) mbean).nbs;
- else
- return null;
- }
-
- public String getClassName() {
- if (mbean instanceof DynamicMBean2)
- return ((DynamicMBean2) mbean).getClassName();
- Object w = mbean;
- if (w instanceof DynamicWrapperMBean)
- w = ((DynamicWrapperMBean) w).getWrappedObject();
- return w.getClass().getName();
- }
-
- public void preRegister2(MBeanServer mbs, ObjectName name) throws Exception {
- if (mbean instanceof DynamicMBean2)
- ((DynamicMBean2) mbean).preRegister2(mbs, name);
- }
-
- public void registerFailed() {
- if (mbean instanceof DynamicMBean2)
- ((DynamicMBean2) mbean).registerFailed();
- }
-
- public Object getWrappedObject() {
- if (mbean instanceof DynamicWrapperMBean)
- return ((DynamicWrapperMBean) mbean).getWrappedObject();
- else
- return mbean;
- }
-
- public ClassLoader getWrappedClassLoader() {
- if (mbean instanceof DynamicWrapperMBean)
- return ((DynamicWrapperMBean) mbean).getWrappedClassLoader();
- else
- return mbean.getClass().getClassLoader();
- }
-
- public Object getAttribute(String attribute) throws AttributeNotFoundException,
- MBeanException,
- ReflectionException {
- return mbean.getAttribute(attribute);
- }
-
- public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException {
- mbean.setAttribute(attribute);
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- return mbean.setAttributes(attributes);
- }
-
- public Object invoke(String actionName, Object[] params, String[] signature)
- throws MBeanException, ReflectionException {
- return mbean.invoke(actionName, params, signature);
- }
-
- public MBeanInfo getMBeanInfo() {
- return mbean.getMBeanInfo();
- }
-
- public AttributeList getAttributes(String[] attributes) {
- return mbean.getAttributes(attributes);
- }
-
- public void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback) throws ListenerNotFoundException {
- nbs.removeNotificationListener(listener, filter, handback);
- }
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- nbs.removeNotificationListener(listener);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return nbs.getNotificationInfo();
- }
-
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
- nbs.addNotificationListener(listener, filter, handback);
- }
-
- public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
- if (mbr() != null)
- return mbr().preRegister(server, name);
- else
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- if (mbr() != null)
- mbr().postRegister(registrationDone);
- }
-
- public void preDeregister() throws Exception {
- if (mbr() != null)
- mbr().preDeregister();
- }
-
- public void postDeregister() {
- if (mbr() != null)
- mbr().postDeregister();
- }
-
- private MBeanRegistration mbr() {
- if (mbean instanceof MBeanRegistration)
- return (MBeanRegistration) mbean;
- else
- return null;
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/PerInterface.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/PerInterface.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2006 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
@@ -231,7 +231,7 @@
/**
* Visitor that sets up the method maps (operations, getters, setters).
*/
- private class InitMaps implements MBeanAnalyzer.MBeanVisitor<M, RuntimeException> {
+ private class InitMaps implements MBeanAnalyzer.MBeanVisitor<M> {
public void visitAttribute(String attributeName,
M getter,
M setter) {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/PerThreadGroupPool.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright 1999-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.mbeanserver;
-
-import java.lang.ref.WeakReference;
-import java.util.concurrent.ThreadPoolExecutor;
-
-/**
- * <p>A factory for ThreadPoolExecutor objects that allows the same object to
- * be shared by all users of the factory that are in the same ThreadGroup.</p>
- */
-// We return a ThreadPoolExecutor rather than the more general ExecutorService
-// because we need to be able to call allowCoreThreadTimeout so that threads in
-// the pool will eventually be destroyed when the pool is no longer in use.
-// Otherwise these threads would keep the ThreadGroup alive forever.
-public class PerThreadGroupPool<T extends ThreadPoolExecutor> {
- private final WeakIdentityHashMap<ThreadGroup, WeakReference<T>> map =
- WeakIdentityHashMap.make();
-
- public static interface Create<T extends ThreadPoolExecutor> {
- public T createThreadPool(ThreadGroup group);
- }
-
- private PerThreadGroupPool() {}
-
- public static <T extends ThreadPoolExecutor> PerThreadGroupPool<T> make() {
- return new PerThreadGroupPool<T>();
- }
-
- public synchronized T getThreadPoolExecutor(Create<T> create) {
- // Find out if there's already an existing executor for the calling
- // thread and reuse it. Otherwise, create a new one and store it in
- // the executors map. If there is a SecurityManager, the group of
- // System.getSecurityManager() is used, else the group of the calling
- // thread.
- SecurityManager s = System.getSecurityManager();
- ThreadGroup group = (s != null) ? s.getThreadGroup() :
- Thread.currentThread().getThreadGroup();
- WeakReference<T> wr = map.get(group);
- T executor = (wr == null) ? null : wr.get();
- if (executor == null) {
- executor = create.createThreadPool(group);
- executor.allowCoreThreadTimeOut(true);
- map.put(group, new WeakReference<T>(executor));
- }
- return executor;
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java Wed Oct 21 16:50:44 2009 +0100
@@ -396,7 +396,7 @@
// Set domain to default if domain is empty and not already set
if (dom.length() == 0)
- name = ObjectName.valueOf(domain + name.toString());
+ name = Util.newObjectName(domain + name.toString());
// Do we have default domain ?
if (dom == domain) { // ES: OK (dom & domain are interned)
@@ -573,7 +573,7 @@
// Pattern matching in the domain name (*, ?)
final String dom2Match = name.getDomain();
for (String dom : domainTb.keySet()) {
- if (Util.wildpathmatch(dom, dom2Match)) {
+ if (Util.wildmatch(dom, dom2Match)) {
final Map<String,NamedObject> moiTb = domainTb.get(dom);
if (allNames)
result.addAll(moiTb.values());
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005 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
@@ -35,7 +35,6 @@
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanOperationInfo;
-import javax.management.ManagedOperation;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;
import javax.management.NotificationBroadcasterSupport;
@@ -119,32 +118,22 @@
@Override
MBeanAttributeInfo getMBeanAttributeInfo(String attributeName,
- Method getter, Method setter) throws IntrospectionException {
+ Method getter, Method setter) {
- String description = getAttributeDescription(
- attributeName, "Attribute exposed for management",
- getter, setter);
- return new MBeanAttributeInfo(attributeName, description,
- getter, setter);
+ final String description = "Attribute exposed for management";
+ try {
+ return new MBeanAttributeInfo(attributeName, description,
+ getter, setter);
+ } catch (IntrospectionException e) {
+ throw new RuntimeException(e); // should not happen
+ }
}
@Override
MBeanOperationInfo getMBeanOperationInfo(String operationName,
Method operation) {
- final String defaultDescription = "Operation exposed for management";
- String description = Introspector.descriptionForElement(operation);
- if (description == null)
- description = defaultDescription;
-
- int impact = MBeanOperationInfo.UNKNOWN;
- ManagedOperation annot = operation.getAnnotation(ManagedOperation.class);
- if (annot != null)
- impact = annot.impact().getCode();
-
- MBeanOperationInfo mboi = new MBeanOperationInfo(description, operation);
- return new MBeanOperationInfo(
- mboi.getName(), mboi.getDescription(), mboi.getSignature(),
- mboi.getReturnType(), impact, mboi.getDescriptor());
+ final String description = "Operation exposed for management";
+ return new MBeanOperationInfo(description, operation);
}
@Override
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -31,7 +31,6 @@
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
-import javax.management.openmbean.MXBeanMappingFactory;
/**
* Base class for Standard MBeans.
@@ -58,11 +57,11 @@
*/
public <T> StandardMBeanSupport(T resource, Class<T> mbeanInterfaceType)
throws NotCompliantMBeanException {
- super(resource, mbeanInterfaceType, (MXBeanMappingFactory) null);
+ super(resource, mbeanInterfaceType);
}
@Override
- MBeanIntrospector<Method> getMBeanIntrospector(MXBeanMappingFactory ignored) {
+ MBeanIntrospector<Method> getMBeanIntrospector() {
return StandardMBeanIntrospector.getInstance();
}
@@ -84,14 +83,13 @@
@Override
public MBeanInfo getMBeanInfo() {
MBeanInfo mbi = super.getMBeanInfo();
- Class<?> resourceClass = getWrappedObject().getClass();
- if (!getMBeanInterface().isInterface() ||
- StandardMBeanIntrospector.isDefinitelyImmutableInfo(resourceClass))
+ Class<?> resourceClass = getResource().getClass();
+ if (StandardMBeanIntrospector.isDefinitelyImmutableInfo(resourceClass))
return mbi;
return new MBeanInfo(mbi.getClassName(), mbi.getDescription(),
mbi.getAttributes(), mbi.getConstructors(),
mbi.getOperations(),
- MBeanIntrospector.findNotifications(getWrappedObject()),
+ MBeanIntrospector.findNotifications(getResource()),
mbi.getDescriptor());
}
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,8 +25,6 @@
package com.sun.jmx.mbeanserver;
-import com.sun.jmx.defaults.JmxProperties;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -40,25 +38,18 @@
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
-import java.util.SortedSet;
import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.WeakHashMap;
-import java.util.logging.Level;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectInstance;
+import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
-import javax.management.loading.ClassLoaderRepository;
-import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
public class Util {
- private final static int NAMESPACE_SEPARATOR_LENGTH =
- NAMESPACE_SEPARATOR.length();
- public final static char[] ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?".
- toCharArray();
-
+ public static ObjectName newObjectName(String string) {
+ try {
+ return new ObjectName(string);
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
static <K, V> Map<K, V> newMap() {
return new HashMap<K, V>();
@@ -89,10 +80,6 @@
return new LinkedHashMap<K, V>();
}
- static <K, V> WeakHashMap<K, V> newWeakHashMap() {
- return new WeakHashMap<K, V>();
- }
-
static <E> Set<E> newSet() {
return new HashSet<E>();
}
@@ -251,451 +238,4 @@
public static boolean wildmatch(String str, String pat) {
return wildmatch(str,pat,0,str.length(),0,pat.length());
}
-
- /**
- * Matches a string against a pattern, as a name space path.
- * This is a special matching where * and ?? don't match //.
- * The string is split in sub-strings separated by //, and the
- * pattern is split in sub-patterns separated by //. Each sub-string
- * is matched against its corresponding sub-pattern.
- * so <elt-1>//<elt2>//...//<elt-n> matches <pat-1>//<pat-2>//...//<pat-q>
- * only if n==q and for ( i = 1 => n) elt-i matches pat-i.
- *
- * In addition, if we encounter a pattern element which is exactly
- * **, it can match any number of path-elements - but it must match at
- * least one element.
- * When we encounter such a meta-wildcard, we remember its position
- * and the position in the string path, and we advance both the pattern
- * and the string. Later, if we encounter a mismatch in pattern & string,
- * we rewind the position in pattern to just after the meta-wildcard,
- * and we backtrack the string to i+1 element after the position
- * we had when we first encountered the meta-wildcard, i being the
- * position when we last backtracked the string.
- *
- * The backtracking logic is an adaptation of the logic in wildmatch
- * above.
- * See test/javax/mangement/ObjectName/ApplyWildcardTest.java
- *
- * Note: this thing is called 'wild' - and that's for a reason ;-)
- **/
- public static boolean wildpathmatch(String str, String pat) {
- final int strlen = str.length();
- final int patlen = pat.length();
- int stri = 0;
- int pati = 0;
-
- int starstri; // index for backtrack if "**" attempt fails
- int starpati; // index for backtrack if "**" attempt fails
-
- starstri = starpati = -1;
-
- while (true) {
- // System.out.println("pati="+pati+", stri="+stri);
- final int strend = str.indexOf(NAMESPACE_SEPARATOR, stri);
- final int patend = pat.indexOf(NAMESPACE_SEPARATOR, pati);
-
- // no // remaining in either string or pattern: simple wildmatch
- // until end of string.
- if (strend == -1 && patend == -1) {
- // System.out.println("last sub pattern, last sub element...");
- // System.out.println("wildmatch("+str.substring(stri,strlen)+
- // ","+pat.substring(pati,patlen)+")");
- return wildmatch(str,pat,stri,strlen,pati,patlen);
- }
-
- // no // remaining in string, but at least one remaining in
- // pattern
- // => no match
- if (strend == -1) {
- // System.out.println("pattern has more // than string...");
- return false;
- }
-
- // strend is != -1, but patend might.
- // detect wildcard **
- if (patend == pati+2 && pat.charAt(pati)=='*' &&
- pat.charAt(pati+1)=='*') {
- // if we reach here we know that neither strend nor patend are
- // equals to -1.
- stri = strend + NAMESPACE_SEPARATOR_LENGTH;
- pati = patend + NAMESPACE_SEPARATOR_LENGTH;
- starpati = pati; // position just after **// in pattern
- starstri = stri; // we eat 1 element in string, and remember
- // the position for backtracking and eating
- // one more element if needed.
- // System.out.println("starpati="+pati);
- continue;
- }
-
- // This is a bit hacky: * can match // when // is at the end
- // of the string, so we include the // delimiter in the pattern
- // matching. Either we're in the middle of the path, so including
- // // both at the end of the pattern and at the end of the string
- // has no effect - match(*//,dfsd//) is equivalent to match(*,dfsd)
- // or we're at the end of the pattern path, in which case
- // including // at the end of the string will have the desired
- // effect (provided that we detect the end of matching correctly,
- // see further on).
- //
- final int endpat =
- ((patend > -1)?patend+NAMESPACE_SEPARATOR_LENGTH:patlen);
- final int endstr =
- ((strend > -1)?strend+NAMESPACE_SEPARATOR_LENGTH:strlen);
-
- // if we reach the end of the pattern, or if elt-i & pat-i
- // don't match, we have a mismatch.
-
- // Note: we know that strend != -1, therefore patend==-1
- // indicates a mismatch unless pattern can match
- // a // at the end, and strend+2=strlen.
- // System.out.println("wildmatch("+str.substring(stri,endstr)+","+
- // pat.substring(pati,endpat)+")");
- if (!wildmatch(str,pat,stri,endstr,pati,endpat)) {
-
- // System.out.println("nomatch");
- // if we have a mismatch and didn't encounter any meta-wildcard,
- // we return false. String & pattern don't match.
- if (starpati < 0) return false;
-
- // If we reach here, we had a meta-wildcard.
- // We need to backtrack to the wildcard, and make it eat an
- // additional string element.
- //
- stri = str.indexOf(NAMESPACE_SEPARATOR, starstri);
- // System.out.println("eating one additional element? "+stri);
-
- // If there's no more elements to eat, string and pattern
- // don't match => return false.
- if (stri == -1) return false;
-
- // Backtrack to where we were when we last matched against
- // the meta-wildcard, make it eat an additional path element,
- // remember the new positions, and continue from there...
- //
- stri = stri + NAMESPACE_SEPARATOR_LENGTH;
- starstri = stri;
- pati = starpati;
- // System.out.println("skiping to stri="+stri);
- continue;
- }
-
- // Here we know that strend > -1 but we can have patend == -1.
- //
- // So if we reach here, we know pat-i+//? has matched
- // elt-i+//
- //
- // If patend==-1, we know that there was no delimiter
- // at the end of the pattern, that we are at the last pattern,
- // and therefore that pat-i has matched elt-i+//
- //
- // In that case we can consider that we have a match only if
- // elt-i is also the last path element in the string, which is
- // equivalent to saying that strend+2==strlen.
- //
- if (patend == -1 && starpati == -1)
- return (strend+NAMESPACE_SEPARATOR_LENGTH==strlen);
-
- // patend != -1, or starpati > -1 so there remains something
- // to match.
-
- // go to next pair: elt-(i+1) pat-(i+1);
- stri = strend + NAMESPACE_SEPARATOR_LENGTH;
- pati = (patend==-1)?pati:(patend + NAMESPACE_SEPARATOR_LENGTH);
- }
- }
-
- /**
- * Returns true if the ObjectName's {@code domain} is selected by the
- * given {@code pattern}.
- */
- public static boolean isDomainSelected(String domain, String pattern) {
- if (domain == null || pattern == null)
- throw new IllegalArgumentException("null");
- return Util.wildpathmatch(domain,pattern);
- }
-
- /**
- * Filters a set of ObjectName according to a given pattern.
- *
- * @param pattern the pattern that the returned names must match.
- * @param all the set of names to filter.
- * @return a set of ObjectName from which non matching names
- * have been removed.
- */
- public static Set<ObjectName> filterMatchingNames(ObjectName pattern,
- Set<ObjectName> all) {
- // If no pattern, just return all names
- if (pattern == null
- || all.isEmpty()
- || ObjectName.WILDCARD.equals(pattern))
- return all;
-
- // If there's a pattern, do the matching.
- final Set<ObjectName> res = equivalentEmptySet(all);
- for (ObjectName n : all) if (pattern.apply(n)) res.add(n);
- return res;
- }
-
-
- /**
- * Filters a set of ObjectInstance according to a given pattern.
- *
- * @param pattern the pattern that the returned names must match.
- * @param all the set of instances to filter.
- * @return a set of ObjectInstance from which non matching instances
- * have been removed.
- */
- public static Set<ObjectInstance>
- filterMatchingInstances(ObjectName pattern,
- Set<ObjectInstance> all) {
- // If no pattern, just return all names
- if (pattern == null
- || all.isEmpty()
- || ObjectName.WILDCARD.equals(pattern))
- return all;
-
- // If there's a pattern, do the matching.
- final Set<ObjectInstance> res = equivalentEmptySet(all);
- for (ObjectInstance n : all) {
- if (n == null) continue;
- if (pattern.apply(n.getObjectName()))
- res.add(n);
- }
- return res;
- }
-
- /**
- * An abstract ClassLoaderRepository that contains a single class loader.
- **/
- private final static class SingleClassLoaderRepository
- implements ClassLoaderRepository {
- private final ClassLoader singleLoader;
-
- SingleClassLoaderRepository(ClassLoader loader) {
- this.singleLoader = loader;
- }
-
- ClassLoader getSingleClassLoader() {
- return singleLoader;
- }
-
- private Class<?> loadClass(String className, ClassLoader loader)
- throws ClassNotFoundException {
- return Class.forName(className, false, loader);
- }
-
- public Class<?> loadClass(String className)
- throws ClassNotFoundException {
- return loadClass(className, getSingleClassLoader());
- }
-
- public Class<?> loadClassWithout(ClassLoader exclude,
- String className) throws ClassNotFoundException {
- final ClassLoader loader = getSingleClassLoader();
- if (exclude != null && exclude.equals(loader))
- throw new ClassNotFoundException(className);
- return loadClass(className, loader);
- }
-
- public Class<?> loadClassBefore(ClassLoader stop, String className)
- throws ClassNotFoundException {
- return loadClassWithout(stop, className);
- }
- }
-
- /**
- * Returns a ClassLoaderRepository that contains a single class loader.
- * @param loader the class loader contained in the returned repository.
- * @return a ClassLoaderRepository that contains the single loader.
- */
- public static ClassLoaderRepository getSingleClassLoaderRepository(
- final ClassLoader loader) {
- return new SingleClassLoaderRepository(loader);
- }
-
- /**
- * Returns the name of the given MBeanServer that should be put in a
- * permission you need.
- * This corresponds to the
- * {@code *[;mbeanServerName=<mbeanServerName>[;*]]} property
- * embedded in the MBeanServerId attribute of the
- * server's {@link MBeanServerDelegate}.
- *
- * @param server The MBean server
- * @return the name of the MBeanServer, or "*" if the name couldn't be
- * obtained, or {@value MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}
- * if there was no name.
- */
- public static String getMBeanServerSecurityName(MBeanServer server) {
- final String notfound = "*";
- try {
- final String mbeanServerId = (String)
- server.getAttribute(MBeanServerDelegate.DELEGATE_NAME,
- "MBeanServerId");
- final String found = extractMBeanServerName(mbeanServerId);
- if (found.length()==0)
- return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
- return found;
- } catch (Exception x) {
- logshort("Failed to retrieve MBeanServerName for server, " +
- "using \"*\"",x);
- return notfound;
- }
- }
-
- /**
- * Returns the name of the MBeanServer embedded in the given
- * mbeanServerId. If the given mbeanServerId doesn't contain any name,
- * an empty String is returned.
- * The MBeanServerId is expected to be of the form:
- * {@code *[;mbeanServerName=<mbeanServerName>[;*]]}
- * @param mbeanServerId The MBean server ID
- * @return the name of the MBeanServer if found, or "" if the name was
- * not present in the mbeanServerId.
- */
- public static String extractMBeanServerName(String mbeanServerId) {
- if (mbeanServerId==null) return "";
- final String beginMarker=";mbeanServerName=";
- final String endMarker=";";
- final int found = mbeanServerId.indexOf(beginMarker);
- if (found < 0) return "";
- final int start = found + beginMarker.length();
- final int stop = mbeanServerId.indexOf(endMarker, start);
- return mbeanServerId.substring(start,
- (stop < 0 ? mbeanServerId.length() : stop));
- }
-
- /**
- * Insert the given mbeanServerName into the given mbeanServerId.
- * If mbeanServerName is null, empty, or equals to "-", the returned
- * mbeanServerId will not contain any mbeanServerName.
- * @param mbeanServerId The mbeanServerId in which to insert
- * mbeanServerName
- * @param mbeanServerName The mbeanServerName
- * @return an mbeanServerId containing the given mbeanServerName
- * @throws IllegalArgumentException if mbeanServerId already contains
- * a different name, or if the given mbeanServerName is not valid.
- */
- public static String insertMBeanServerName(String mbeanServerId,
- String mbeanServerName) {
- final String found = extractMBeanServerName(mbeanServerId);
- if (found.length() > 0 &&
- found.equals(checkServerName(mbeanServerName)))
- return mbeanServerId;
- if (found.length() > 0 && !isMBeanServerNameUndefined(found))
- throw new IllegalArgumentException(
- "MBeanServerName already defined");
- if (isMBeanServerNameUndefined(mbeanServerName))
- return mbeanServerId;
- final String beginMarker=";mbeanServerName=";
- return mbeanServerId+beginMarker+checkServerName(mbeanServerName);
- }
-
- /**
- * Returns true if the given mbeanServerName corresponds to an
- * undefined MBeanServerName.
- * The mbeanServerName is considered undefined if it is one of:
- * {@code null} or {@value MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}.
- * @param mbeanServerName The mbeanServerName, as returned by
- * {@link #extractMBeanServerName(String)}.
- * @return true if the given name corresponds to one of the forms that
- * denotes an undefined MBeanServerName.
- */
- public static boolean isMBeanServerNameUndefined(String mbeanServerName) {
- return mbeanServerName == null ||
- MBeanServerFactory.DEFAULT_MBEANSERVER_NAME.equals(mbeanServerName);
- }
- /**
- * Check that the provided mbeanServername is syntactically valid.
- * @param mbeanServerName An mbeanServerName, or {@code null}.
- * @return mbeanServerName, or {@value
- * MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if {@code mbeanServerName}
- * is {@code null}.
- * @throws IllegalArgumentException if mbeanServerName contains illegal
- * characters, or is empty, or is {@code "-"}.
- * Illegal characters are {@link #ILLEGAL_MBEANSERVER_NAME_CHARS}.
- */
- public static String checkServerName(String mbeanServerName) {
- if ("".equals(mbeanServerName))
- throw new IllegalArgumentException(
- "\"\" is not a valid MBean server name");
- if ("-".equals(mbeanServerName))
- throw new IllegalArgumentException(
- "\"-\" is not a valid MBean server name");
- if (isMBeanServerNameUndefined(mbeanServerName))
- return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
- for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS) {
- if (mbeanServerName.indexOf(c) >= 0)
- throw new IllegalArgumentException(
- "invalid character in MBeanServer name: "+c);
- }
- return mbeanServerName;
- }
-
- /**
- * Get the MBeanServer name that should be put in a permission you need.
- *
- * @param delegate The MBeanServerDelegate
- * @return The MBeanServer name - or {@value
- * MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if there was no name.
- */
- public static String getMBeanServerSecurityName(
- MBeanServerDelegate delegate) {
- try {
- final String serverName = delegate.getMBeanServerName();
- if (isMBeanServerNameUndefined(serverName))
- return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
- return serverName;
- } catch (Exception x) {
- logshort("Failed to retrieve MBeanServerName from delegate, " +
- "using \"*\"",x);
- return "*";
- }
- }
-
- // Log the exception and its causes without logging the stack trace.
- // Use with care - it is usually preferable to log the whole stack trace!
- // We don't want to log the whole stack trace here: logshort() is
- // called in those cases where the exception might not be abnormal.
- private static void logshort(String msg, Throwable t) {
- if (JmxProperties.MISC_LOGGER.isLoggable(Level.FINE)) {
- StringBuilder toprint = new StringBuilder(msg);
- do {
- toprint.append("\nCaused By: ").append(String.valueOf(t));
- } while ((t=t.getCause())!=null);
- JmxProperties.MISC_LOGGER.fine(toprint.toString());
- }
- }
-
- public static <T> Set<T> cloneSet(Set<T> set) {
- if (set instanceof SortedSet<?>) {
- @SuppressWarnings("unchecked")
- SortedSet<T> sset = (SortedSet<T>) set;
- set = new TreeSet<T>(sset.comparator());
- set.addAll(sset);
- } else
- set = new HashSet<T>(set);
- return set;
- }
-
- public static <T> Set<T> equivalentEmptySet(Set<T> set) {
- if (set instanceof SortedSet<?>) {
- @SuppressWarnings("unchecked")
- SortedSet<T> sset = (SortedSet<T>) set;
- set = new TreeSet<T>(sset.comparator());
- } else
- set = new HashSet<T>();
- return set;
- }
-
- // This exception is used when wrapping a class that throws IOException
- // in a class that doesn't.
- // The typical example for this are JMXNamespaces, when the sub
- // MBeanServer can be remote.
- //
- public static RuntimeException newRuntimeIOException(IOException io) {
- final String msg = "Communication failed with underlying resource: "+
- io.getMessage();
- return new RuntimeException(msg,io);
- }
}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,463 +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.namespace;
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.mbeanserver.Util;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanPermission;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerNotification;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.namespace.JMXDomain;
-
-/**
- * A DomainInterceptor wraps a JMXDomain.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
-
- // TODO: Ideally DomainInterceptor should be replaced by
- // something at Repository level.
- // The problem there will be that we may need to
- // reinstantiate the 'queryPerformedByRepos' boolean
- // [or we will need to wrap the repository in
- // a 'RepositoryInterceptor'?]
- // Also there's no real need for a DomainInterceptor to
- // extend RewritingMBeanServerConnection.
-
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- private final String domainName;
- private volatile ObjectName ALL;
- private final String serverName;
- private volatile NotificationListener mbsListener;
-
- private static class PatternNotificationFilter
- implements NotificationFilter {
-
- final ObjectName pattern;
- public PatternNotificationFilter(ObjectName pattern) {
- this.pattern = pattern==null?ObjectName.WILDCARD:pattern;
- }
-
- public boolean isNotificationEnabled(Notification notification) {
- if (!(notification instanceof MBeanServerNotification))
- return false;
- final MBeanServerNotification mbsn =
- (MBeanServerNotification) notification;
- if (pattern.apply(mbsn.getMBeanName()))
- return true;
- return false;
- }
-
- static final long serialVersionUID = 7409950927025262111L;
- }
-
- /**
- * Creates a new instance of NamespaceInterceptor
- */
- public DomainInterceptor(String serverName,
- JMXDomain handler,
- String domainName) {
- super(handler);
- this.domainName = domainName;
- this.serverName = serverName;
- ALL = ObjectName.valueOf(domainName+":*");
- }
-
- @Override
- public String toString() {
- return this.getClass().getName()+"(parent="+serverName+
- ", domain="+this.domainName+")";
- }
-
- final void connectDelegate(final MBeanServerDelegate delegate)
- throws InstanceNotFoundException {
- final NotificationFilter filter =
- new PatternNotificationFilter(getPatternFor(null));
- synchronized (this) {
- if (mbsListener == null) {
- mbsListener = new NotificationListener() {
- public void handleNotification(Notification notification,
- Object handback) {
- if (filter.isNotificationEnabled(notification))
- delegate.sendNotification(notification);
- }
- };
- }
- }
-
- getHandlerInterceptorMBean().
- addMBeanServerNotificationListener(mbsListener, filter);
- }
-
- final void disconnectDelegate()
- throws InstanceNotFoundException, ListenerNotFoundException {
- final NotificationListener l;
- synchronized (this) {
- l = mbsListener;
- if (l == null) return;
- mbsListener = null;
- }
- getHandlerInterceptorMBean().removeMBeanServerNotificationListener(l);
- }
-
- public final void addPostRegisterTask(Queue<Runnable> queue,
- final MBeanServerDelegate delegate) {
- if (queue == null)
- throw new IllegalArgumentException("task queue must not be null");
- final Runnable task1 = new Runnable() {
- public void run() {
- try {
- connectDelegate(delegate);
- } catch (Exception x) {
- throw new UnsupportedOperationException(
- "notification forwarding",x);
- }
- }
- };
- queue.add(task1);
- }
-
- public final void addPostDeregisterTask(Queue<Runnable> queue,
- final MBeanServerDelegate delegate) {
- if (queue == null)
- throw new IllegalArgumentException("task queue must not be null");
- final Runnable task1 = new Runnable() {
- public void run() {
- try {
- disconnectDelegate();
- } catch (Exception x) {
- throw new UnsupportedOperationException(
- "notification forwarding",x);
- }
- }
- };
- queue.add(task1);
- }
-
- // No name conversion for JMXDomains...
- // Throws IllegalArgumentException if targetName.getDomain() is not
- // in the domain handled.
- //
- @Override
- protected ObjectName toSource(ObjectName targetName) {
- if (targetName == null) return null;
- if (targetName.isDomainPattern()) return targetName;
- final String targetDomain = targetName.getDomain();
-
- // TODO: revisit this. RuntimeOperationsException may be better?
- //
- if (!targetDomain.equals(domainName))
- throw new IllegalArgumentException(targetName.toString());
- return targetName;
- }
-
- // No name conversion for JMXDomains...
- @Override
- protected ObjectName toTarget(ObjectName sourceName) {
- return sourceName;
- }
-
-
-
- /**
- * No rewriting: always return sources - stripping instances for which
- * the caller doesn't have permissions.
- **/
- @Override
- Set<ObjectInstance> processOutputInstances(Set<ObjectInstance> sources) {
- if (sources == null || sources.isEmpty() || !checkOn())
- return sources;
- final Set<ObjectInstance> res = Util.equivalentEmptySet(sources);
- for (ObjectInstance o : sources) {
- if (checkQuery(o.getObjectName(), "queryMBeans"))
- res.add(o);
- }
- return res;
- }
-
-
- /**
- * No rewriting: always return sourceNames - stripping names for which
- * the caller doesn't have permissions.
- **/
- @Override
- Set<ObjectName> processOutputNames(Set<ObjectName> sourceNames) {
- if (sourceNames == null || sourceNames.isEmpty() || !checkOn())
- return sourceNames;
- final Set<ObjectName> res = Util.equivalentEmptySet(sourceNames);
- for (ObjectName o : sourceNames) {
- if (checkQuery(o, "queryNames"))
- res.add(o);
- }
- return res;
- }
-
- /** No rewriting: always return source **/
- @Override
- ObjectInstance processOutputInstance(ObjectInstance source) {
- return source;
- }
-
- @Override
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- try {
- // We don't trust the wrapped JMXDomain...
- final ObjectName pattern = getPatternFor(name);
- final Set<ObjectName> res = super.queryNames(pattern,query);
- return Util.filterMatchingNames(pattern,res);
- } catch (Exception x) {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("Unexpected exception raised in queryNames: "+x);
- LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x);
- return Collections.emptySet();
- }
- }
-
- // Compute a new pattern which is a sub pattern of 'name' but only selects
- // the MBeans in domain 'domainName'
- // When we reach here, it has been verified that 'name' matches our domain
- // name (done by DomainDispatchInterceptor)
- private ObjectName getPatternFor(final ObjectName name) {
- if (name == null) return ALL;
- if (name.getDomain().equals(domainName)) return name;
- return name.withDomain(domainName);
- }
-
- @Override
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- try {
- // We don't trust the wrapped JMXDomain...
- final ObjectName pattern = getPatternFor(name);
- final Set<ObjectInstance> res = super.queryMBeans(pattern,query);
- return Util.filterMatchingInstances(pattern,res);
- } catch (Exception x) {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("Unexpected exception raised in queryNames: "+x);
- LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x);
- return Collections.emptySet();
- }
- }
-
- @Override
- public String getDefaultDomain() {
- return domainName;
- }
-
- @Override
- public String[] getDomains() {
- return new String[] {domainName};
- }
-
- // We call getMBeanCount() on the namespace rather than on the
- // source server in order to avoid counting MBeans which are not
- // in the domain.
- @Override
- public Integer getMBeanCount() {
- return getHandlerInterceptorMBean().getMBeanCount();
- }
-
- private boolean checkOn() {
- final SecurityManager sm = System.getSecurityManager();
- return (sm != null);
- }
-
- //
- // Implements permission checks.
- //
- @Override
- void check(ObjectName routingName, String member, String action) {
- if (!checkOn()) return;
- final String act = (action==null)?"-":action;
- if("queryMBeans".equals(act) || "queryNames".equals(act)) {
- // This is tricky. check with 3 parameters is called
- // by queryNames/queryMBeans before performing the query.
- // At this point we must check with no class name.
- // Therefore we pass a className of "-".
- // The filtering will be done later - processOutputNames and
- // processOutputInstance will call checkQuery.
- //
- check(routingName, "-", "-", act);
- } else {
- // This is also tricky:
- // passing null here will cause check to retrieve the classname,
- // if needed.
- check(routingName, null, member, act);
- }
- }
-
- //
- // Implements permission checks.
- //
- @Override
- void checkCreate(ObjectName routingName, String className, String action) {
- if (!checkOn()) return;
- check(routingName,className,"-",action);
- }
-
- //
- // Implements permission checks.
- //
- void check(ObjectName routingName, String className, String member,
- String action) {
- if (!checkOn()) return;
- final MBeanPermission perm;
-
- final String act = (action==null)?"-":action;
- if ("getDomains".equals(act)) { // ES: OK
- perm = new MBeanPermission(serverName,"-",member,
- routingName,act);
- } else {
- final String clazz =
- (className==null)?getClassName(routingName):className;
- perm = new MBeanPermission(serverName,clazz,member,
- routingName,act);
- }
- final SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkPermission(perm);
- }
-
- String getClassName(ObjectName routingName) {
- if (routingName == null || routingName.isPattern()) return "-";
- try {
- return getHandlerInterceptorMBean().getSourceServer().
- getObjectInstance(routingName).getClassName();
- } catch (InstanceNotFoundException ex) {
- LOG.finest("Can't get class name for "+routingName+
- ", using \"-\". Cause is: "+ex);
- return "-";
- }
- }
-
- //
- // Implements permission filters for attributes...
- //
- @Override
- AttributeList checkAttributes(ObjectName routingName,
- AttributeList attributes, String action) {
- if (!checkOn()) return attributes;
- final String className = getClassName(routingName);
- check(routingName,className,"-",action);
- if (attributes == null || attributes.isEmpty()) return attributes;
- final AttributeList res = new AttributeList();
- for (Attribute at : attributes.asList()) {
- try {
- check(routingName,className,at.getName(),action);
- res.add(at);
- } catch (SecurityException x) { // DLS: OK
- continue;
- }
- }
- return res;
- }
-
- //
- // Implements permission filters for attributes...
- //
- @Override
- String[] checkAttributes(ObjectName routingName, String[] attributes,
- String action) {
- if (!checkOn()) return attributes;
- final String className = getClassName(routingName);
- check(routingName,className,"-",action);
- if (attributes == null || attributes.length==0) return attributes;
- final List<String> res = new ArrayList<String>(attributes.length);
- for (String at : attributes) {
- try {
- check(routingName,className,at,action);
- res.add(at);
- } catch (SecurityException x) { // DLS: OK
- continue;
- }
- }
- return res.toArray(new String[res.size()]);
- }
-
- //
- // Implements permission filters for domains...
- //
- @Override
- String[] checkDomains(String[] domains, String action) {
- if (domains == null || domains.length==0 || !checkOn())
- return domains;
- int count=0;
- for (int i=0;i<domains.length;i++) {
- try {
- check(ObjectName.valueOf(domains[i]+":x=x"),"-",
- "-","getDomains");
- } catch (SecurityException x) { // DLS: OK
- count++;
- domains[i]=null;
- }
- }
- if (count == 0) return domains;
- final String[] res = new String[domains.length-count];
- count = 0;
- for (int i=0;i<domains.length;i++)
- if (domains[i]!=null) res[count++]=domains[i];
- return res;
- }
-
- //
- // Implements permission filters for queries...
- //
- @Override
- boolean checkQuery(ObjectName routingName, String action) {
- try {
- final String className = getClassName(routingName);
- check(routingName,className,"-",action);
- return true;
- } catch (SecurityException x) { // DLS: OK
- return false;
- }
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,734 +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.namespace;
-
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.interceptor.MBeanServerInterceptor;
-
-import com.sun.jmx.mbeanserver.Util;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.OperationsException;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.RuntimeOperationsException;
-import javax.management.loading.ClassLoaderRepository;
-import javax.management.namespace.JMXNamespace;
-
-/**
- * This interceptor wraps a JMXNamespace, and performs
- * {@code ObjectName} rewriting. {@code HandlerInterceptor} are
- * created and managed by a {@link NamespaceDispatchInterceptor} or a
- * {@link DomainDispatchInterceptor}.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public abstract class HandlerInterceptor<T extends JMXNamespace>
- extends RoutingMBeanServerConnection<MBeanServer>
- implements MBeanServerInterceptor {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- // The wrapped JMXNamespace
- private final T handler;
-
- /**
- * Creates a new instance of HandlerInterceptor
- */
- public HandlerInterceptor(T handler) {
- if (handler == null) throw new IllegalArgumentException("null");
- this.handler = handler;
- }
-
- //
- // The {@code source} connection is a connection to the MBeanServer
- // that contains the actual MBeans.
- // In the case of cascading, that would be a connection to the sub
- // agent. Practically, this is JMXNamespace.getSourceServer();
- //
- @Override
- protected MBeanServer source() {
- return handler.getSourceServer();
- }
-
- // The MBeanServer on which getClassLoader / getClassLoaderFor
- // will be called.
- // The NamespaceInterceptor overrides this method - so that it
- // getClassLoader / getClassLoaderFor don't trigger the loop
- // detection mechanism.
- //
- MBeanServer getServerForLoading() {
- return source();
- }
-
- // The namespace or domain handler - this either a JMXNamespace or a
- // a JMXDomain
- T getHandlerInterceptorMBean() {
- return handler;
- }
-
- // If the underlying JMXNamespace throws an IO, the IO will be
- // wrapped in a RuntimeOperationsException.
- RuntimeException handleIOException(IOException x,String fromMethodName,
- Object... params) {
- // Must do something here?
- if (LOG.isLoggable(Level.FINEST)) {
- LOG.finest("IO Exception in "+fromMethodName+": "+x+
- " - "+" rethrowing as RuntimeOperationsException.");
- }
- throw new RuntimeOperationsException(
- Util.newRuntimeIOException(x));
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- try {
- final String[] authorized =
- checkAttributes(name,attributes,"getAttribute");
- final AttributeList attrList =
- super.getAttributes(name,authorized);
- return attrList;
- } catch (IOException ex) {
- throw handleIOException(ex,"getAttributes",name,attributes);
- }
- }
-
- // From MBeanServer
- public ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- final ObjectName sourceName = toSourceOrRuntime(mbeanName);
- try {
- check(mbeanName,null,"getClassLoaderFor");
- return getServerForLoading().getClassLoaderFor(sourceName);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
-
- // From MBeanServer
- public ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- final ObjectName sourceName = toSourceOrRuntime(loaderName);
- try {
- check(loaderName,null,"getClassLoader");
- return getServerForLoading().getClassLoader(sourceName);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // From MBeanServer
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException, MBeanRegistrationException,
- NotCompliantMBeanException {
- final ObjectName sourceName = newSourceMBeanName(name);
- try {
- checkCreate(name,object.getClass().getName(),"registerMBean");
- return processOutputInstance(
- source().registerMBean(object,sourceName));
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void removeNotificationListener(ObjectName name, ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- check(name,null,"removeNotificationListener");
- super.removeNotificationListener(name,listener);
- } catch (IOException ex) {
- throw handleIOException(ex,"removeNotificationListener",name,listener);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public String getDefaultDomain() {
- try {
- return super.getDefaultDomain();
- } catch (IOException ex) {
- throw handleIOException(ex,"getDefaultDomain");
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public String[] getDomains() {
- try {
- check(null,null,"getDomains");
- final String[] domains = super.getDomains();
- return checkDomains(domains,"getDomains");
- } catch (IOException ex) {
- throw handleIOException(ex,"getDomains");
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public Integer getMBeanCount() {
- try {
- return super.getMBeanCount();
- } catch (IOException ex) {
- throw handleIOException(ex,"getMBeanCount");
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void setAttribute(ObjectName name, Attribute attribute)
- throws InstanceNotFoundException, AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- try {
- check(name,
- (attribute==null?null:attribute.getName()),
- "setAttribute");
- super.setAttribute(name,attribute);
- } catch (IOException ex) {
- throw handleIOException(ex,"setAttribute",name, attribute);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- if (name == null) name=ObjectName.WILDCARD;
- try {
- checkPattern(name,null,"queryNames");
- return super.queryNames(name,query);
- } catch (IOException ex) {
- throw handleIOException(ex,"queryNames",name, query);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- if (name == null) name=ObjectName.WILDCARD;
- try {
- checkPattern(name,null,"queryMBeans");
- return super.queryMBeans(name,query);
- } catch (IOException ex) {
- throw handleIOException(ex,"queryMBeans",name, query);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- try {
- check(name, null, "isInstanceOf");
- return super.isInstanceOf(name, className);
- } catch (IOException ex) {
- throw handleIOException(ex,"isInstanceOf",name, className);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public ObjectInstance createMBean(String className, ObjectName name)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- try {
- checkCreate(name, className, "instantiate");
- checkCreate(name, className, "registerMBean");
- return super.createMBean(className, name);
- } catch (IOException ex) {
- throw handleIOException(ex,"createMBean",className, name);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- try {
- checkCreate(name, className, "instantiate");
- checkCreate(name, className, "registerMBean");
- return super.createMBean(className, name, loaderName);
- } catch (IOException ex) {
- throw handleIOException(ex,"createMBean",className, name, loaderName);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException,
- InstanceNotFoundException, ReflectionException {
- try {
- check(name, attribute, "getAttribute");
- return super.getAttribute(name, attribute);
- } catch (IOException ex) {
- throw handleIOException(ex,"getAttribute",name, attribute);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void removeNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter, Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- check(name,null,"removeNotificationListener");
- super.removeNotificationListener(name, listener, filter, handback);
- } catch (IOException ex) {
- throw handleIOException(ex,"removeNotificationListener",name,
- listener, filter, handback);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener, NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- check(name,null,"removeNotificationListener");
- super.removeNotificationListener(name, listener, filter, handback);
- } catch (IOException ex) {
- throw handleIOException(ex,"removeNotificationListener",name,
- listener, filter, handback);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- check(name,null,"removeNotificationListener");
- super.removeNotificationListener(name, listener);
- } catch (IOException ex) {
- throw handleIOException(ex,"removeNotificationListener",name,
- listener);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void addNotificationListener(ObjectName name,
- NotificationListener listener, NotificationFilter filter,
- Object handback) throws InstanceNotFoundException {
- try {
- check(name,null,"addNotificationListener");
- super.addNotificationListener(name, listener, filter, handback);
- } catch (IOException ex) {
- throw handleIOException(ex,"addNotificationListener",name,
- listener, filter, handback);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void addNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter, Object handback)
- throws InstanceNotFoundException {
- try {
- check(name,null,"addNotificationListener");
- super.addNotificationListener(name, listener, filter, handback);
- } catch (IOException ex) {
- throw handleIOException(ex,"addNotificationListener",name,
- listener, filter, handback);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public boolean isRegistered(ObjectName name) {
- try {
- return super.isRegistered(name);
- } catch (IOException ex) {
- throw handleIOException(ex,"isRegistered",name);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException {
- try {
- check(name, null, "unregisterMBean");
- super.unregisterMBean(name);
- } catch (IOException ex) {
- throw handleIOException(ex,"unregisterMBean",name);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, IntrospectionException,
- ReflectionException {
- try {
- check(name, null, "getMBeanInfo");
- return super.getMBeanInfo(name);
- } catch (IOException ex) {
- throw handleIOException(ex,"getMBeanInfo",name);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- try {
- check(name, null, "getObjectInstance");
- return super.getObjectInstance(name);
- } catch (IOException ex) {
- throw handleIOException(ex,"getObjectInstance",name);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- try {
- checkCreate(name, className, "instantiate");
- checkCreate(name, className, "registerMBean");
- return super.createMBean(className, name, params, signature);
- } catch (IOException ex) {
- throw handleIOException(ex,"createMBean",className, name,
- params, signature);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName, Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- try {
- checkCreate(name, className, "instantiate");
- checkCreate(name, className, "registerMBean");
- return super.createMBean(className, name, loaderName, params,
- signature);
- } catch (IOException ex) {
- throw handleIOException(ex,"createMBean",className, name,loaderName,
- params, signature);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public AttributeList setAttributes(ObjectName name,AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- try {
- final AttributeList authorized =
- checkAttributes(name, attributes, "setAttribute");
- return super.setAttributes(name, authorized);
- } catch (IOException ex) {
- throw handleIOException(ex,"setAttributes",name, attributes);
- }
- }
-
- // From MBeanServerConnection: catch & handles IOException
- @Override
- public Object invoke(ObjectName name, String operationName, Object[] params,
- String[] signature)
- throws InstanceNotFoundException, MBeanException, ReflectionException {
- try {
- check(name, operationName, "invoke");
- return super.invoke(name, operationName, params, signature);
- } catch (IOException ex) {
- throw handleIOException(ex,"invoke",name, operationName,
- params, signature);
- }
- }
-
- //
- // These methods are inherited from MBeanServer....
- //
-
- /**
- * This method should never be called.
- * Throws UnsupportedOperationException.
- */
- public Object instantiate(String className)
- throws ReflectionException, MBeanException {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported instantiate method: " +
- "trowing UnsupportedOperationException");
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * This method should never be called.
- * Throws UnsupportedOperationException.
- */
- public Object instantiate(String className, ObjectName loaderName)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: instantiate(...) -" +
- "throwing UnsupportedOperationException");
- 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 {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: instantiate(...) -" +
- "throwing UnsupportedOperationException");
- 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 {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: instantiate(...) -" +
- "throwing UnsupportedOperationException");
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * This method should never be called.
- * Throws UnsupportedOperationException.
- */
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: deserialize(...) -" +
- "throwing UnsupportedOperationException");
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * This method should never be called.
- * Throws UnsupportedOperationException.
- */
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: deserialize(...) -" +
- "throwing UnsupportedOperationException");
- 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 {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: deserialize(...) -" +
- "throwing UnsupportedOperationException");
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * This method should never be called.
- * Throws UnsupportedOperationException.
- */
- public ClassLoaderRepository getClassLoaderRepository() {
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("call to unsupported method: getClassLoaderRepository() -" +
- "throwing UnsupportedOperationException");
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- static RuntimeException newUnsupportedException(String namespace) {
- return new RuntimeOperationsException(
- new UnsupportedOperationException(
- "Not supported in this namespace: "+namespace));
- }
-
- /**
- * A result might be excluded for security reasons.
- */
- @Override
- boolean excludesFromResult(ObjectName targetName, String queryMethod) {
- return !checkQuery(targetName, queryMethod);
- }
-
-
- //----------------------------------------------------------------------
- // Hooks for checking permissions
- //----------------------------------------------------------------------
-
- /**
- * This method is a hook to implement permission checking in subclasses.
- * A subclass may override this method and throw a {@link
- * SecurityException} if the permission is denied.
- *
- * @param routingName The name of the MBean in the enclosing context.
- * This is of the form {@code <namespace>//<ObjectName>}.
- * @param member The {@link
- * javax.management.namespace.JMXNamespacePermission#getMember member}
- * name.
- * @param action The {@link
- * javax.management.namespace.JMXNamespacePermission#getActions action}
- * name.
- * @throws SecurityException if the caller doesn't have the permission
- * to perform the given action on the MBean pointed to
- * by routingName.
- */
- abstract void check(ObjectName routingName,
- String member, String action);
-
- // called in createMBean and registerMBean
- abstract void checkCreate(ObjectName routingName, String className,
- String action);
-
- /**
- * This is a hook to implement permission checking in subclasses.
- *
- * Checks that the caller has sufficient permission for returning
- * information about {@code sourceName} in {@code action}.
- *
- * Subclass may override this method and return false if the caller
- * doesn't have sufficient permissions.
- *
- * @param routingName The name of the MBean to include or exclude from
- * the query, expressed in the enclosing context.
- * This is of the form {@code <namespace>//<ObjectName>}.
- * @param action one of "queryNames" or "queryMBeans"
- * @return true if {@code sourceName} can be returned.
- */
- abstract boolean checkQuery(ObjectName routingName, String action);
-
- /**
- * This method is a hook to implement permission checking in subclasses.
- *
- * @param routingName The name of the MBean in the enclosing context.
- * This is of the form {@code <namespace>//<ObjectName>}.
- * @param attributes The list of attributes to check permission for.
- * @param action one of "getAttribute" or "setAttribute"
- * @return The list of attributes for which the callers has the
- * appropriate {@link
- * javax.management.namespace.JMXNamespacePermission}.
- * @throws SecurityException if the caller doesn't have the permission
- * to perform {@code action} on the MBean pointed to by routingName.
- */
- abstract String[] checkAttributes(ObjectName routingName,
- String[] attributes, String action);
-
- /**
- * This method is a hook to implement permission checking in subclasses.
- *
- * @param routingName The name of the MBean in the enclosing context.
- * This is of the form {@code <namespace>//<ObjectName>}.
- * @param attributes The list of attributes to check permission for.
- * @param action one of "getAttribute" or "setAttribute"
- * @return The list of attributes for which the callers has the
- * appropriate {@link
- * javax.management.namespace.JMXNamespacePermission}.
- * @throws SecurityException if the caller doesn't have the permission
- * to perform {@code action} on the MBean pointed to by routingName.
- */
- abstract AttributeList checkAttributes(ObjectName routingName,
- AttributeList attributes, String action);
-
- /**
- * This method is a hook to implement permission checking in subclasses.
- * Checks that the caller as the necessary permissions to view the
- * given domain. If not remove the domains for which the caller doesn't
- * have permission from the list.
- * <p>
- * By default, this method always returns {@code domains}
- *
- * @param domains The domains to return.
- * @param action "getDomains"
- * @return a filtered list of domains.
- */
- String[] checkDomains(String[] domains, String action) {
- return domains;
- }
-
- // A priori check for queryNames/queryMBeans/
- void checkPattern(ObjectName routingPattern,
- String member, String action) {
- // pattern is checked only at posteriori by checkQuery.
- // checking it a priori usually doesn't work, because ObjectName.apply
- // does not work between two patterns.
- // We only check that we have the permission requested for 'action'.
- check(null,null,action);
- }
-
-
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +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.namespace;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespacePermission;
-
-/**
- * A NamespaceInterceptor wraps a JMXNamespace, performing
- * ObjectName rewriting.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
-
-
- // The target name space in which the NamepsaceHandler is mounted.
- private final String targetNs;
-
- private final String serverName;
-
- private final ObjectNameRouter proc;
-
- /**
- * Creates a new instance of NamespaceInterceptor
- */
- public NamespaceInterceptor(
- String serverName,
- JMXNamespace handler,
- String targetNamespace) {
- super(handler);
- this.serverName = serverName;
- this.targetNs =
- ObjectNameRouter.normalizeNamespacePath(targetNamespace,
- true, true, false);
- proc = new ObjectNameRouter(targetNamespace, "");
- }
-
- @Override
- public String toString() {
- return this.getClass().getName()+"(parent="+serverName+
- ", namespace="+this.targetNs+")";
- }
-
- /**
- * This method will send a probe to detect self-linking name spaces.
- * A self linking namespace is a namespace that links back directly
- * on itslef. Calling a method on such a name space always results
- * in an infinite loop going through:
- * [1]MBeanServer -> [2]NamespaceDispatcher -> [3]NamespaceInterceptor
- * [4]JMXNamespace -> { network // or cd // or ... } -> [5]MBeanServer
- * with exactly the same request than [1]...
- *
- * The namespace interceptor [2] tries to detect such condition the
- * *first time* that the connection is used. It does so by setting
- * a flag, and sending a queryNames() through the name space. If the
- * queryNames comes back, it knows that there's a loop.
- *
- * 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).
- */
- private MBeanServer connection() {
- final MBeanServer c = super.source();
- if (c != null) return c;
- // should not come here
- throw new NullPointerException("getMBeanServerConnection");
- }
-
-
- @Override
- protected MBeanServer source() {
- return connection();
- }
-
- @Override
- protected MBeanServer getServerForLoading() {
- // don't want to send probe on getClassLoader/getClassLoaderFor
- return super.source();
- }
-
- @Override
- protected ObjectName toSource(ObjectName targetName) {
- return proc.toSourceContext(targetName, true);
- }
-
- @Override
- protected ObjectName toTarget(ObjectName sourceName) {
- return proc.toTargetContext(sourceName, false);
- }
-
- //
- // Implements permission checks.
- //
- @Override
- void check(ObjectName routingName, String member, String action) {
- final SecurityManager sm = System.getSecurityManager();
- if (sm == null) return;
- if ("getDomains".equals(action)) return;
- final JMXNamespacePermission perm =
- new JMXNamespacePermission(serverName,member,
- routingName,action);
- sm.checkPermission(perm);
- }
-
- @Override
- void checkCreate(ObjectName routingName, String className, String action) {
- final SecurityManager sm = System.getSecurityManager();
- if (sm == null) return;
- final JMXNamespacePermission perm =
- new JMXNamespacePermission(serverName,className,
- routingName,action);
- sm.checkPermission(perm);
- }
-
- //
- // Implements permission filters for attributes...
- //
- @Override
- AttributeList checkAttributes(ObjectName routingName,
- AttributeList attributes, String action) {
- check(routingName,null,action);
- if (attributes == null || attributes.isEmpty()) return attributes;
- final SecurityManager sm = System.getSecurityManager();
- if (sm == null) return attributes;
- final AttributeList res = new AttributeList();
- for (Attribute at : attributes.asList()) {
- try {
- check(routingName,at.getName(),action);
- res.add(at);
- } catch (SecurityException x) { // DLS: OK
- continue;
- }
- }
- return res;
- }
-
- //
- // Implements permission filters for attributes...
- //
- @Override
- String[] checkAttributes(ObjectName routingName, String[] attributes,
- String action) {
- check(routingName,null,action);
- if (attributes == null || attributes.length==0) return attributes;
- final SecurityManager sm = System.getSecurityManager();
- if (sm == null) return attributes;
- final List<String> res = new ArrayList<String>(attributes.length);
- for (String at : attributes) {
- try {
- check(routingName,at,action);
- res.add(at);
- } catch (SecurityException x) { // DLS: OK
- continue;
- }
- }
- return res.toArray(new String[res.size()]);
- }
-
- //
- // Implements permission filters for domains...
- //
- @Override
- String[] checkDomains(String[] domains, String action) {
- // in principle, this method is never called because
- // getDomains() will never be called - since there's
- // no way that MBeanServer.getDomains() can be routed
- // to a NamespaceInterceptor.
- //
- // This is also why there's no getDomains() in a
- // JMXNamespacePermission...
- //
- return super.checkDomains(domains, action);
- }
-
- //
- // Implements permission filters for queries...
- //
- @Override
- boolean checkQuery(ObjectName routingName, String action) {
- try {
- check(routingName,null,action);
- return true;
- } catch (SecurityException x) { // DLS: OK
- return false;
- }
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +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.namespace;
-
-import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
-
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-/**
- * The ObjectNameRouter is used to rewrite routing object names.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public class ObjectNameRouter {
-
- private static final int NAMESPACE_SEPARATOR_LENGTH =
- NAMESPACE_SEPARATOR.length();
-
- final String targetPrefix;
- final String sourcePrefix;
- final int slen;
- final int tlen;
- final boolean identity;
-
- /** Creates a new instance of ObjectNameRouter */
- public ObjectNameRouter(final String remove, final String add) {
- this.targetPrefix = (remove==null?"":remove);
- this.sourcePrefix = (add==null?"":add);
- tlen = targetPrefix.length();
- slen = sourcePrefix.length();
- identity = targetPrefix.equals(sourcePrefix);
- }
-
- public final ObjectName toTargetContext(ObjectName sourceName,
- boolean removeLeadingSeparators) {
- if (sourceName == null) return null;
- if (identity) return sourceName;
- String srcDomain = sourceName.getDomain();
-
- // if the ObjectName starts with // and removeLeadingSeparators is
- // true, then recursively strip leading //.
- // Otherwise, do not rewrite ObjectName.
- //
- if (srcDomain.startsWith(NAMESPACE_SEPARATOR)) {
- if (!removeLeadingSeparators) return sourceName;
- else srcDomain = normalizeDomain(srcDomain,true);
- }
- if (slen != 0) {
- if (!srcDomain.startsWith(sourcePrefix) ||
- !srcDomain.startsWith(NAMESPACE_SEPARATOR,slen))
- throw new IllegalArgumentException(
- "ObjectName does not start with expected prefix "
- + sourcePrefix + ": " +
- String.valueOf(sourceName));
- srcDomain = srcDomain.substring(slen+NAMESPACE_SEPARATOR_LENGTH);
- }
- final String targetDomain =
- (tlen>0?targetPrefix+NAMESPACE_SEPARATOR+srcDomain:srcDomain);
- return sourceName.withDomain(targetDomain);
- }
-
- public final ObjectName toSourceContext(ObjectName targetName,
- boolean removeLeadingSeparators) {
- if (targetName == null) return null;
- if (identity) return targetName;
- String targetDomain = targetName.getDomain();
- if (targetDomain.startsWith(NAMESPACE_SEPARATOR)) {
- if (!removeLeadingSeparators) return targetName;
- else targetDomain =
- normalizeDomain(targetDomain,true);
- }
- if (tlen != 0) {
- if (!targetDomain.startsWith(targetPrefix) ||
- !targetDomain.startsWith(NAMESPACE_SEPARATOR,tlen))
- throw new IllegalArgumentException(
- "ObjectName does not start with expected prefix "
- + targetPrefix + ": " +
- String.valueOf(targetName));
- targetDomain = targetDomain.
- substring(tlen+NAMESPACE_SEPARATOR_LENGTH);
- }
- final String sourceDomain =
- (slen>0?sourcePrefix+NAMESPACE_SEPARATOR+targetDomain:
- targetDomain);
- return targetName.withDomain(sourceDomain);
- }
-
- public final ObjectInstance toTargetContext(ObjectInstance sourceMoi,
- boolean removeLeadingSeparators) {
- if (sourceMoi == null) return null;
- if (identity) return sourceMoi;
- return new ObjectInstance(
- toTargetContext(sourceMoi.getObjectName(),
- removeLeadingSeparators),
- sourceMoi.getClassName());
- }
-
- /**
- * Removes leading, trailing, or duplicate // in a name space path.
- **/
- public static String normalizeDomain(String domain,
- boolean removeLeadingSep) {
- return normalizeNamespacePath(domain,removeLeadingSep,false,true);
- }
-
- /**
- * Removes leading, trailing, or duplicate // in a name space path.
- **/
- public static String normalizeNamespacePath(String namespacePath,
- boolean removeLeadingSep,
- boolean removeTrailingSep,
- boolean endsWithDomain) {
- if (namespacePath.equals(""))
- return "";
- final String[] components = namespacePath.split(NAMESPACE_SEPARATOR);
- final StringBuilder b =
- new StringBuilder(namespacePath.length()+NAMESPACE_SEPARATOR_LENGTH);
- String sep = null;
- if (!removeLeadingSep && namespacePath.startsWith(NAMESPACE_SEPARATOR))
- b.append(NAMESPACE_SEPARATOR);
- int count = 0;
- for (int i=0; i<components.length; i++) {
- final String n=components[i];
- if (n.equals("")) continue;
- if (n.startsWith("/")||n.endsWith("/")) {
- // throw exception unless we're looking at the last domain
- // part of the ObjectName
- if (! (endsWithDomain && i==(components.length-1))) {
- throw new IllegalArgumentException(n+
- " is not a valid name space identifier");
- } else {
- // There's a dirty little corner case when the domain
- // part (last item) is exactly '/' - in that case we must
- // not append '//'
- //
- removeTrailingSep = removeTrailingSep || n.equals("/");
- }
- }
- if (sep != null) b.append(sep);
- b.append(n);
- sep = NAMESPACE_SEPARATOR;
- count++;
- }
- if (!removeTrailingSep && namespacePath.endsWith(NAMESPACE_SEPARATOR)
- && count > 0)
- b.append(NAMESPACE_SEPARATOR);
- return b.toString();
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +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.namespace;
-
-
-import com.sun.jmx.defaults.JmxProperties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.MBeanServerConnection;
-
-
-/**
- * A RoutingConnectionProxy is an MBeanServerConnection proxy that proxies a
- * source name space in a source MBeanServerConnection.
- * It wraps a source MBeanServerConnection, and rewrites routing
- * ObjectNames. It is used to implement
- * {@code JMXNamespaces.narrowToNamespace(MBeanServerConnection)}.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-// See class hierarchy and detailled explanations in RoutingProxy in this
-// package.
-//
-public class RoutingConnectionProxy
- extends RoutingProxy<MBeanServerConnection> {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
-
- /**
- * Creates a new instance of RoutingConnectionProxy
- */
- public RoutingConnectionProxy(MBeanServerConnection source,
- String sourceDir,
- String targetDir,
- boolean probe) {
- super(source, sourceDir, targetDir, probe);
-
- if (LOG.isLoggable(Level.FINER))
- LOG.finer("RoutingConnectionProxy for " + getSourceNamespace() +
- " created");
- }
-
- @Override
- public String toString() {
- final String targetNs = getTargetNamespace();
- final String sourceNs = getSourceNamespace();
- String wrapped = String.valueOf(source());
- if ("".equals(targetNs)) {
- return "JMXNamespaces.narrowToNamespace("+
- wrapped+", \""+
- sourceNs+"\")";
- }
- return this.getClass().getSimpleName()+"("+wrapped+", \""+
- sourceNs+"\", \""+
- targetNs+"\")";
- }
-
- static final RoutingProxyFactory
- <MBeanServerConnection,RoutingConnectionProxy>
- FACTORY = new RoutingProxyFactory
- <MBeanServerConnection,RoutingConnectionProxy>() {
-
- public RoutingConnectionProxy newInstance(MBeanServerConnection source,
- String sourcePath, String targetPath, boolean probe) {
- return new RoutingConnectionProxy(source,sourcePath,
- targetPath, probe);
- }
- };
-
- public static MBeanServerConnection cd(
- MBeanServerConnection source, String sourcePath, boolean probe) {
- return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY,
- source, sourcePath, probe);
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,556 +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.namespace;
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.mbeanserver.Util;
-import java.io.IOException;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.JMRuntimeException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServerConnection;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.RuntimeMBeanException;
-import javax.management.RuntimeOperationsException;
-
-/**
- * A RoutingMBeanServerConnection wraps a MBeanServerConnection, defining
- * abstract methods that can be implemented by subclasses to rewrite
- * routing ObjectNames. It is used to implement
- * HandlerInterceptors (wrapping JMXNamespace instances) and routing
- * proxies (used to implement cd operations).
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnection>
- implements MBeanServerConnection {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- /**
- * Creates a new instance of RoutingMBeanServerConnection
- */
- public RoutingMBeanServerConnection() {
- }
-
- /**
- * Returns the wrapped source connection. The {@code source} connection
- * is a connection to the MBeanServer that contains the actual MBean.
- * In the case of cascading, that would be a connection to the sub
- * agent.
- **/
- protected abstract T source() throws IOException;
-
- /**
- * Converts a target ObjectName to a source ObjectName.
- * The target ObjectName is the name of the MBean in the mount point
- * target. In the case of cascading, that would be the name of the
- * MBean in the master agent. So if a subagent S containing an MBean
- * named "X" is mounted in the target namespace "foo//" of a master agent M,
- * the source is S, the target is "foo//" in M, the source name is "X", and
- * the target name is "foo//X".
- * In the case of cascading - such as in NamespaceInterceptor, this method
- * will convert "foo//X" (the targetName) into "X", the source name.
- * @throws IllegalArgumentException if the name cannot be converted.
- **/
- protected abstract ObjectName toSource(ObjectName targetName);
- /**
- * Converts a source ObjectName to a target ObjectName.
- * (see description of toSource above for explanations)
- * In the case of cascading - such as in NamespaceInterceptor, this method
- * will convert "X" (the sourceName) into "foo//X", the target name.
- * @throws IllegalArgumentException if the name cannot be converted.
- **/
- protected abstract ObjectName toTarget(ObjectName sourceName);
-
- /**
- * Can be overridden by subclasses to check the validity of a new
- * ObjectName used in createMBean or registerMBean.
- * This method is typically used by subclasses which might require
- * special handling for "null";
- **/
- protected ObjectName newSourceMBeanName(ObjectName targetName)
- throws MBeanRegistrationException {
- try {
- return toSource(targetName);
- } catch (Exception x) {
- throw new MBeanRegistrationException(x,"Illegal MBean Name");
- }
- }
-
- // Calls toSource(), Wraps IllegalArgumentException.
- ObjectName toSourceOrRuntime(ObjectName targetName) {
- try {
- return toSource(targetName);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
-
- // Wraps given exception if needed.
- RuntimeException makeCompliantRuntimeException(Exception x) {
- if (x instanceof SecurityException) return (SecurityException)x;
- if (x instanceof JMRuntimeException) return (JMRuntimeException)x;
- if (x instanceof RuntimeException)
- return new RuntimeOperationsException((RuntimeException)x);
- if (x instanceof IOException)
- return Util.newRuntimeIOException((IOException)x);
- // shouldn't come here...
- final RuntimeException x2 = new UndeclaredThrowableException(x);
- return new RuntimeOperationsException(x2);
- }
-
- // from MBeanServerConnection
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().getAttributes(sourceName, attributes);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public Object invoke(ObjectName name, String operationName, Object[] params,
- String[] signature)
- throws InstanceNotFoundException, MBeanException, ReflectionException,
- IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- final Object result =
- source().invoke(sourceName,operationName,params,
- signature);
- return result;
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException,
- IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- source().unregisterMBean(sourceName);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, IntrospectionException,
- ReflectionException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().getMBeanInfo(sourceName);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return processOutputInstance(
- source().getObjectInstance(sourceName));
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public boolean isRegistered(ObjectName name) throws IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().isRegistered(sourceName);
- } catch (RuntimeMBeanException x) {
- throw new RuntimeOperationsException(x.getTargetException());
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- // from MBeanServerConnection
- public void setAttribute(ObjectName name, Attribute attribute)
- throws InstanceNotFoundException, AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- source().setAttribute(sourceName,attribute);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public ObjectInstance createMBean(String className,
- ObjectName name, ObjectName loaderName,
- Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException, IOException {
- final ObjectName sourceName = newSourceMBeanName(name);
- // Loader Name is already a sourceLoaderName.
- final ObjectName sourceLoaderName = loaderName;
- try {
- final ObjectInstance instance =
- source().createMBean(className,sourceName,
- sourceLoaderName,
- params,signature);
- return processOutputInstance(instance);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public ObjectInstance createMBean(String className, ObjectName name,
- Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, IOException {
- final ObjectName sourceName = newSourceMBeanName(name);
- try {
- return processOutputInstance(source().createMBean(className,
- sourceName,params,signature));
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException, IOException {
- final ObjectName sourceName = newSourceMBeanName(name);
- // Loader Name is already a source Loader Name.
- final ObjectName sourceLoaderName = loaderName;
- try {
- return processOutputInstance(source().createMBean(className,
- sourceName,sourceLoaderName));
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public ObjectInstance createMBean(String className, ObjectName name)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, IOException {
- final ObjectName sourceName = newSourceMBeanName(name);
- try {
- return processOutputInstance(source().
- createMBean(className,sourceName));
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException,
- InstanceNotFoundException, ReflectionException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().getAttribute(sourceName,attribute);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().isInstanceOf(sourceName,className);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public AttributeList setAttributes(ObjectName name, AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().
- setAttributes(sourceName,attributes);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // Return names in the target's context.
- Set<ObjectInstance> processOutputInstances(Set<ObjectInstance> sources) {
-
- final Set<ObjectInstance> result = Util.equivalentEmptySet(sources);
- for (ObjectInstance i : sources) {
- try {
- final ObjectInstance target = processOutputInstance(i);
- if (excludesFromResult(target.getObjectName(), "queryMBeans"))
- continue;
- result.add(target);
- } catch (Exception x) {
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Skiping returned item: " +
- "Unexpected exception while processing " +
- "ObjectInstance: " + x);
- }
- continue;
- }
- }
- return result;
- }
-
-
- // Return names in the target's context.
- ObjectInstance processOutputInstance(ObjectInstance source) {
- if (source == null) return null;
- final ObjectName sourceName = source.getObjectName();
- try {
- final ObjectName targetName = toTarget(sourceName);
- return new ObjectInstance(targetName,source.getClassName());
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- // Returns names in the target's context.
- Set<ObjectName> processOutputNames(Set<ObjectName> sourceNames) {
-
- final Set<ObjectName> names = Util.equivalentEmptySet(sourceNames);
- for (ObjectName n : sourceNames) {
- try {
- final ObjectName targetName = toTarget(n);
- if (excludesFromResult(targetName, "queryNames")) continue;
- names.add(targetName);
- } catch (Exception x) {
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Skiping returned item: " +
- "Unexpected exception while processing " +
- "ObjectInstance: " + x);
- }
- continue;
- }
- }
- return names;
- }
-
- // from MBeanServerConnection
- public Set<ObjectInstance> queryMBeans(ObjectName name,
- QueryExp query) throws IOException {
- if (name == null) name=ObjectName.WILDCARD;
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return processOutputInstances(
- source().queryMBeans(sourceName,query));
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
-
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query)
- throws IOException {
- if (name == null) name=ObjectName.WILDCARD;
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- final Set<ObjectName> tmp = source().queryNames(sourceName,query);
- final Set<ObjectName> out = processOutputNames(tmp);
- //System.err.println("queryNames: out: "+out);
- return out;
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException,
- ListenerNotFoundException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- source().removeNotificationListener(sourceName,listener);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public void addNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter, Object handback)
- throws InstanceNotFoundException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- // Listener name is already a source listener name.
- try {
- source().addNotificationListener(sourceName,listener,
- filter,handback);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public void addNotificationListener(ObjectName name,
- NotificationListener listener, NotificationFilter filter,
- Object handback) throws InstanceNotFoundException, IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- source().addNotificationListener(sourceName, listener, filter,
- handback);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
-
- // from MBeanServerConnection
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener, NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- source().removeNotificationListener(sourceName,listener,filter,
- handback);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public void removeNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter, Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- source().removeNotificationListener(sourceName,listener,
- filter,handback);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public void removeNotificationListener(ObjectName name, ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- // listener name is already a source name...
- final ObjectName sourceListener = listener;
- try {
- source().removeNotificationListener(sourceName,sourceListener);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public Integer getMBeanCount() throws IOException {
- try {
- return source().getMBeanCount();
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public String[] getDomains() throws IOException {
- try {
- return source().getDomains();
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // from MBeanServerConnection
- public String getDefaultDomain() throws IOException {
- try {
- return source().getDefaultDomain();
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- /**
- * Returns true if the given targetName must be excluded from the
- * query result.
- * In this base class, always return {@code false}.
- * By default all object names returned by the sources are
- * transmitted to the caller - there is no filtering.
- *
- * @param name A target object name expressed in the caller's
- * context. In the case of cascading, where the source
- * is a sub agent mounted on e.g. namespace "foo",
- * that would be a name prefixed by "foo//"...
- * @param queryMethod either "queryNames" or "queryMBeans".
- * @return true if the name must be excluded.
- */
- boolean excludesFromResult(ObjectName targetName, String queryMethod) {
- return false;
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +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.namespace;
-
-import com.sun.jmx.defaults.JmxProperties;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanRegistrationException;
-
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespaces;
-
-
-/**
- * A RoutingProxy narrows on a given name space in a
- * source object implementing MBeanServerConnection.
- * It is used to implement
- * {@code JMXNamespaces.narrowToNamespace(...)}.
- * This abstract class has two concrete subclasses:
- * <p>{@link RoutingConnectionProxy}: to narrow down into an
- * MBeanServerConnection.</p>
- * <p>{@link RoutingServerProxy}: to narrow down into an MBeanServer.</p>
- *
- * <p>This class can also be used to "broaden" from a namespace. The same
- * class is used for both purposes because in both cases all that happens
- * is that ObjectNames are rewritten in one way on the way in (e.g. the
- * parameter of getMBeanInfo) and another way on the way out (e.g. the
- * return value of queryNames).</p>
- *
- * <p>Specifically, if you narrow into "a//" then you want to add the
- * "a//" prefix to ObjectNames on the way in and subtract it on the way
- * out. But ClientContext uses this class to subtract the
- * "jmx.context//foo=bar//" prefix on the way in and add it back on the
- * way out.</p>
- *
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-//
-// RoutingProxies are client side objects which are used to narrow down
-// into a namespace. They are used to perform ObjectName translation,
-// adding the namespace to the routing ObjectName before sending it over
-// to the source connection, and removing that prefix from results of
-// queries, createMBean, registerMBean, and getObjectInstance.
-// This translation is the opposite to that which is performed by
-// NamespaceInterceptors.
-//
-// There is however a special case where routing proxies are used on the
-// 'server' side to remove a namespace - rather than to add it:
-// This the case of ClientContext.
-// When an ObjectName like "jmx.context//c1=v1,c2=v2//D:k=v" reaches the
-// jmx.context namespace, a routing proxy is used to remove the prefix
-// c1=v1,c2=v2// from the routing objectname.
-//
-// For a RoutingProxy used in a narrowDownToNamespace operation, we have:
-// targetNs="" // targetNS is the namespace 'to remove'
-// sourceNS=<namespace-we-narrow-down-to> // namespace 'to add'
-//
-// For a RoutingProxy used in a ClientContext operation, we have:
-// targetNs=<encoded-context> // context must be removed from object name
-// sourceNs="" // nothing to add...
-//
-// Finally, in order to avoid too many layers of wrapping,
-// RoutingConnectionProxy and RoutingServerProxy can be created through a
-// factory method that can concatenate namespace paths in order to
-// return a single RoutingProxy - rather than wrapping a RoutingProxy inside
-// another RoutingProxy. See RoutingConnectionProxy.cd and
-// RoutingServerProxy.cd
-//
-// The class hierarchy is as follows:
-//
-// RoutingMBeanServerConnection
-// [abstract class for all routing interceptors,
-// such as RoutingProxies and HandlerInterceptors]
-// / \
-// / \
-// RoutingProxy HandlerInterceptor
-// [base class for [base class for server side
-// client-side objects used objects, created by
-// in narrowDownTo] DispatchInterceptors]
-// / \ | \
-// RoutingConnectionProxy \ | NamespaceInterceptor
-// [wraps MBeanServerConnection \ | [used to remove
-// objects] \ | namespace prefix and
-// RoutingServerProxy | wrap JMXNamespace]
-// [wraps MBeanServer |
-// Objects] |
-// DomainInterceptor
-// [used to wrap JMXDomain]
-//
-// RoutingProxies also differ from HandlerInterceptors in that they transform
-// calls to MBeanServerConnection operations that do not have any parameters
-// into a call to the underlying JMXNamespace MBean.
-// So for instance a call to:
-// JMXNamespaces.narrowDownToNamespace(conn,"foo").getDomains()
-// is transformed into
-// conn.getAttribute("foo//type=JMXNamespace","Domains");
-//
-public abstract class RoutingProxy<T extends MBeanServerConnection>
- extends RoutingMBeanServerConnection<T> {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- // The source MBeanServerConnection
- private final T source;
-
- // The name space we're narrowing to (usually some name space in
- // the source MBeanServerConnection), e.g. "a" for the namespace
- // "a//". This is empty in the case of ClientContext described above.
- private final String sourceNs;
-
- // The name space we pretend to be mounted in. This is empty except
- // in the case of ClientContext described above (where it will be
- // something like "jmx.context//foo=bar".
- private final String targetNs;
-
- // The name of the JMXNamespace that handles the source name space
- private final ObjectName handlerName;
- private final ObjectNameRouter router;
- private volatile String defaultDomain = null;
-
- /**
- * Creates a new instance of RoutingProxy
- */
- protected RoutingProxy(T source,
- String sourceNs,
- String targetNs,
- boolean probe) {
- if (source == null) throw new IllegalArgumentException("null");
- this.sourceNs = JMXNamespaces.normalizeNamespaceName(sourceNs);
-
- // Usually sourceNs is not null, except when implementing
- // Client Contexts
- //
- if (sourceNs.equals("")) {
- this.handlerName = null;
- } else {
- // System.err.println("sourceNs: "+sourceNs);
- this.handlerName =
- JMXNamespaces.getNamespaceObjectName(this.sourceNs);
- if (probe) {
- try {
- if (!source.isRegistered(handlerName)) {
- InstanceNotFoundException infe =
- new InstanceNotFoundException(handlerName);
- throw new IllegalArgumentException(sourceNs +
- ": no such name space", infe);
- }
- } catch (IOException x) {
- throw new IllegalArgumentException("source stale: "+x,x);
- }
- }
- }
- this.source = source;
- this.targetNs = (targetNs==null?"":
- JMXNamespaces.normalizeNamespaceName(targetNs));
- this.router =
- new ObjectNameRouter(this.targetNs,this.sourceNs);
-
- if (LOG.isLoggable(Level.FINER))
- LOG.finer("RoutingProxy for " + this.sourceNs + " created");
- }
-
- @Override
- public T source() { return source; }
-
- @Override
- public ObjectName toSource(ObjectName targetName) {
- if (targetName == null) return null;
- if (targetName.getDomain().equals("") && targetNs.equals("")) {
- try {
- if (defaultDomain == null)
- defaultDomain = getDefaultDomain();
- } catch(Exception x) {
- LOG.log(Level.FINEST,"Failed to get default domain",x);
- }
- if (defaultDomain != null)
- targetName = targetName.withDomain(defaultDomain);
- }
- return router.toSourceContext(targetName,true);
- }
-
- @Override
- protected ObjectName newSourceMBeanName(ObjectName targetName)
- throws MBeanRegistrationException {
- if (targetName != null) return super.newSourceMBeanName(targetName);
-
- // OK => we can accept null if sourceNs is empty.
- if (sourceNs.equals("")) return null;
-
- throw new MBeanRegistrationException(
- new IllegalArgumentException(
- "Can't use null ObjectName with namespaces"));
- }
-
- @Override
- public ObjectName toTarget(ObjectName sourceName) {
- if (sourceName == null) return null;
- return router.toTargetContext(sourceName,false);
- }
-
- private Object getAttributeFromHandler(String attributeName)
- throws IOException {
-
- try {
- return source().getAttribute(handlerName,attributeName);
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- } catch (IOException x) {
- throw x;
- } catch (MBeanException ex) {
- throw new IOException("Failed to get "+attributeName+": "+
- ex.getCause(),
- ex.getCause());
- } catch (Exception ex) {
- throw new IOException("Failed to get "+attributeName+": "+
- ex,ex);
- }
- }
-
- // We cannot call getMBeanCount() on the underlying
- // MBeanServerConnection, because it would return the number of
- // 'top-level' MBeans, not the number of MBeans in the name space
- // we are narrowing to. Instead we're calling getMBeanCount() on
- // the JMXNamespace that handles the source name space.
- //
- // There is however one particular case when the sourceNs is empty.
- // In that case, there's no handler - and the 'source' is the top
- // level namespace. In that particular case, handlerName will be null,
- // and we directly invoke the top level source().
- // This later complex case is only used when implementing ClientContexts.
- //
- @Override
- public Integer getMBeanCount() throws IOException {
- try {
- if (handlerName == null) return source().getMBeanCount();
- return (Integer) getAttributeFromHandler("MBeanCount");
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // We cannot call getDomains() on the underlying
- // MBeanServerConnection, because it would return the domains of
- // 'top-level' MBeans, not the domains of MBeans in the name space
- // we are narrowing to. Instead we're calling getDomains() on
- // the JMXNamespace that handles the source name space.
- //
- // There is however one particular case when the sourceNs is empty.
- // In that case, there's no handler - and the 'source' is the top
- // level namespace. In that particular case, handlerName will be null,
- // and we directly invoke the top level source().
- // This later complex case is only used when implementing ClientContexts.
- //
- @Override
- public String[] getDomains() throws IOException {
- try {
- if (handlerName == null) return source().getDomains();
- return (String[]) getAttributeFromHandler("Domains");
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- // We cannot call getDefaultDomain() on the underlying
- // MBeanServerConnection, because it would return the default domain of
- // 'top-level' namespace, not the default domain in the name space
- // we are narrowing to. Instead we're calling getDefaultDomain() on
- // the JMXNamespace that handles the source name space.
- //
- // There is however one particular case when the sourceNs is empty.
- // In that case, there's no handler - and the 'source' is the top
- // level namespace. In that particular case, handlerName will be null,
- // and we directly invoke the top level source().
- // This later complex case is only used when implementing ClientContexts.
- //
- @Override
- public String getDefaultDomain() throws IOException {
- try {
- if (handlerName == null) {
- defaultDomain = source().getDefaultDomain();
- } else {
- defaultDomain =(String)
- getAttributeFromHandler("DefaultDomain");
- }
- return defaultDomain;
- } catch (RuntimeException ex) {
- throw makeCompliantRuntimeException(ex);
- }
- }
-
- public String getSourceNamespace() {
- return sourceNs;
- }
-
- public String getTargetNamespace() {
- return targetNs;
- }
-
- @Override
- public String toString() {
- return super.toString()+", sourceNs="+
- sourceNs + (targetNs.equals("")?"":
- (" mounted on targetNs="+targetNs));
- }
-
- // Creates an instance of a subclass 'R' of RoutingProxy<T>
- // RoutingServerProxy and RoutingConnectionProxy have their own factory
- // instance.
- static interface RoutingProxyFactory<T extends MBeanServerConnection,
- R extends RoutingProxy<T>> {
- public R newInstance(
- T source, String sourcePath, String targetPath, boolean probe);
- }
-
- // Performs a narrowDownToNamespace operation.
- // This method will attempt to merge two RoutingProxies in a single
- // one if they are of the same class.
- //
- // This method is never called directly - it should be called only by
- // subclasses of RoutingProxy.
- //
- // As for now it is called by:
- // RoutingServerProxy.cd and RoutingConnectionProxy.cd.
- //
- static <T extends MBeanServerConnection, R extends RoutingProxy<T>>
- R cd(Class<R> routingProxyClass,
- RoutingProxyFactory<T,R> factory,
- T source, String sourcePath, boolean probe) {
- if (source == null) throw new IllegalArgumentException("null");
- if (source.getClass().equals(routingProxyClass)) {
- // cast is OK here, but findbugs complains unless we use class.cast
- final R other = routingProxyClass.cast(source);
- final String target = other.getTargetNamespace();
-
- // Avoid multiple layers of serialization.
- //
- // We construct a new proxy from the original source instead of
- // stacking a new proxy on top of the old one.
- // - that is we replace
- // cd ( cd ( x, dir1), dir2);
- // by
- // cd (x, dir1//dir2);
- //
- // We can do this only when the source class is exactly
- // RoutingServerProxy.
- //
- if (target == null || target.equals("")) {
- final String path =
- JMXNamespaces.concat(other.getSourceNamespace(),
- sourcePath);
- return factory.newInstance(other.source(), path, "", probe);
- }
- // Note: we could do possibly something here - but it would involve
- // removing part of targetDir, and possibly adding
- // something to sourcePath.
- // Too complex to bother! => simply default to stacking...
- }
- return factory.newInstance(source, sourcePath, "", probe);
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +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.namespace;
-
-
-import com.sun.jmx.mbeanserver.Util;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.Collections;
-import java.util.Set;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.OperationsException;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.loading.ClassLoaderRepository;
-
-/**
- * A RoutingServerProxy is an MBeanServer proxy that proxies a
- * source name space in a source MBeanServer.
- * It wraps a source MBeanServer, and rewrites routing ObjectNames.
- * It is typically use for implementing 'cd' operations, and
- * will add the source name space to routing ObjectNames at input,
- * and remove it at output.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- *
- * @since 1.7
- */
-// See class hierarchy and detailled explanations in RoutingProxy in this
-// package.
-//
-public class RoutingServerProxy
- extends RoutingProxy<MBeanServer>
- implements MBeanServer {
-
- public RoutingServerProxy(MBeanServer source,
- String sourceNs,
- String targetNs,
- boolean probe) {
- super(source, sourceNs, targetNs, probe);
- }
-
- /**
- * This method is called each time an IOException is raised when
- * trying to forward an operation to the underlying
- * MBeanServerConnection, as a result of calling
- * {@link #getMBeanServerConnection()} or as a result of invoking the
- * operation on the returned connection.
- * Subclasses may redefine this method if they need to perform any
- * specific handling of IOException (logging etc...).
- * @param x The raised IOException.
- * @param method The name of the method in which the exception was
- * raised. This is one of the methods of the MBeanServer
- * interface.
- * @return A RuntimeException that should be thrown by the caller.
- * In this default implementation, this is an
- * {@link UndeclaredThrowableException} wrapping <var>x</var>.
- **/
- protected RuntimeException handleIOException(IOException x,
- String method) {
- return Util.newRuntimeIOException(x);
- }
-
-
- //--------------------------------------------
- //--------------------------------------------
- //
- // Implementation of the MBeanServer interface
- //
- //--------------------------------------------
- //--------------------------------------------
- @Override
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- try {
- super.addNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw handleIOException(x,"addNotificationListener");
- }
- }
-
- @Override
- public void addNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- try {
- super.addNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw handleIOException(x,"addNotificationListener");
- }
- }
-
- @Override
- public ObjectInstance createMBean(String className, ObjectName name)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException {
- try {
- return super.createMBean(className, name);
- } catch (IOException x) {
- throw handleIOException(x,"createMBean");
- }
- }
-
- @Override
- public ObjectInstance createMBean(String className, ObjectName name,
- Object params[], String signature[])
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException {
- try {
- return super.createMBean(className, name,
- params, signature);
- } catch (IOException x) {
- throw handleIOException(x,"createMBean");
- }
- }
-
- @Override
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException {
- try {
- return super.createMBean(className, name, loaderName);
- } catch (IOException x) {
- throw handleIOException(x,"createMBean");
- }
- }
-
- @Override
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- Object params[],
- String signature[])
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException {
- try {
- return super.createMBean(className, name, loaderName,
- params, signature);
- } catch (IOException x) {
- throw handleIOException(x,"createMBean");
- }
- }
-
- /**
- * @deprecated see {@link MBeanServer#deserialize(ObjectName,byte[])
- * MBeanServer}
- **/
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException {
- final ObjectName sourceName = toSourceOrRuntime(name);
- try {
- return source().deserialize(sourceName,data);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- /**
- * @deprecated see {@link MBeanServer#deserialize(String,byte[])
- * MBeanServer}
- */
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException {
- try {
- return source().deserialize(className,data);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- /**
- * @deprecated see {@link MBeanServer#deserialize(String,ObjectName,byte[])
- * MBeanServer}
- */
- @Deprecated
- public ObjectInputStream deserialize(String className,
- ObjectName loaderName,
- byte[] data)
- throws
- InstanceNotFoundException,
- OperationsException,
- ReflectionException {
- try {
- return source().deserialize(className,loaderName,data);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- @Override
- public Object getAttribute(ObjectName name, String attribute)
- throws
- MBeanException,
- AttributeNotFoundException,
- InstanceNotFoundException,
- ReflectionException {
- try {
- return super.getAttribute(name, attribute);
- } catch (IOException x) {
- throw handleIOException(x,"getAttribute");
- }
- }
-
- @Override
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- try {
- return super.getAttributes(name, attributes);
- } catch (IOException x) {
- throw handleIOException(x,"getAttributes");
- }
- }
-
- public ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- final ObjectName sourceName = toSourceOrRuntime(loaderName);
- try {
- return source().getClassLoader(sourceName);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- public ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- final ObjectName sourceName = toSourceOrRuntime(mbeanName);
- try {
- return source().getClassLoaderFor(sourceName);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- public ClassLoaderRepository getClassLoaderRepository() {
- try {
- return source().getClassLoaderRepository();
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- @Override
- public String getDefaultDomain() {
- try {
- return super.getDefaultDomain();
- } catch (IOException x) {
- throw handleIOException(x,"getDefaultDomain");
- }
- }
-
- @Override
- public String[] getDomains() {
- try {
- return super.getDomains();
- } catch (IOException x) {
- throw handleIOException(x,"getDomains");
- }
- }
-
- @Override
- public Integer getMBeanCount() {
- try {
- return super.getMBeanCount();
- } catch (IOException x) {
- throw handleIOException(x,"getMBeanCount");
- }
- }
-
- @Override
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws
- InstanceNotFoundException,
- IntrospectionException,
- ReflectionException {
- try {
- return super.getMBeanInfo(name);
- } catch (IOException x) {
- throw handleIOException(x,"getMBeanInfo");
- }
- }
-
- @Override
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- try {
- return super.getObjectInstance(name);
- } catch (IOException x) {
- throw handleIOException(x,"getObjectInstance");
- }
- }
-
- public Object instantiate(String className)
- throws ReflectionException, MBeanException {
- try {
- return source().instantiate(className);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- public Object instantiate(String className,
- Object params[],
- String signature[])
- throws ReflectionException, MBeanException {
- try {
- return source().instantiate(className,
- params,signature);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- public Object instantiate(String className, ObjectName loaderName)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- final ObjectName srcLoaderName = toSourceOrRuntime(loaderName);
- try {
- return source().instantiate(className,srcLoaderName);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- public Object instantiate(String className, ObjectName loaderName,
- Object params[], String signature[])
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- final ObjectName srcLoaderName = toSourceOrRuntime(loaderName);
- try {
- return source().instantiate(className,srcLoaderName,
- params,signature);
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- @Override
- public Object invoke(ObjectName name, String operationName,
- Object params[], String signature[])
- throws
- InstanceNotFoundException,
- MBeanException,
- ReflectionException {
- try {
- return super.invoke(name,operationName,params,signature);
- } catch (IOException x) {
- throw handleIOException(x,"invoke");
- }
- }
-
- @Override
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- try {
- return super.isInstanceOf(name, className);
- } catch (IOException x) {
- throw handleIOException(x,"isInstanceOf");
- }
- }
-
- @Override
- public boolean isRegistered(ObjectName name) {
- try {
- return super.isRegistered(name);
- } catch (IOException x) {
- throw handleIOException(x,"isRegistered");
- }
- }
-
- @Override
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- try {
- return super.queryMBeans(name, query);
- } catch (IOException x) {
- handleIOException(x,"queryMBeans");
- return Collections.emptySet();
- }
- }
-
- @Override
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- try {
- return super.queryNames(name, query);
- } catch (IOException x) {
- handleIOException(x,"queryNames");
- return Collections.emptySet();
- }
- }
-
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- NotCompliantMBeanException {
- final ObjectName sourceName = newSourceMBeanName(name);
- try {
- return processOutputInstance(
- source().registerMBean(object,sourceName));
- } catch (RuntimeException x) {
- throw makeCompliantRuntimeException(x);
- }
- }
-
- @Override
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- super.removeNotificationListener(name, listener);
- } catch (IOException x) {
- throw handleIOException(x,"removeNotificationListener");
- }
- }
-
- @Override
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- super.removeNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw handleIOException(x,"removeNotificationListener");
- }
- }
-
- @Override
- public void removeNotificationListener(ObjectName name,
- ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- super.removeNotificationListener(name, listener);
- } catch (IOException x) {
- throw handleIOException(x,"removeNotificationListener");
- }
- }
-
- @Override
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- super.removeNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw handleIOException(x,"removeNotificationListener");
- }
- }
-
- @Override
- public void setAttribute(ObjectName name, Attribute attribute)
- throws
- InstanceNotFoundException,
- AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException {
- try {
- super.setAttribute(name, attribute);
- } catch (IOException x) {
- throw handleIOException(x,"setAttribute");
- }
- }
-
- @Override
- public AttributeList setAttributes(ObjectName name,
- AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- try {
- return super.setAttributes(name, attributes);
- } catch (IOException x) {
- throw handleIOException(x,"setAttributes");
- }
- }
-
- @Override
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException {
- try {
- super.unregisterMBean(name);
- } catch (IOException x) {
- throw handleIOException(x,"unregisterMBean");
- }
- }
-
- static final RoutingProxyFactory<MBeanServer,RoutingServerProxy>
- FACTORY = new RoutingProxyFactory<MBeanServer,RoutingServerProxy>() {
-
- public RoutingServerProxy newInstance(MBeanServer source,
- String sourcePath, String targetPath, boolean probe) {
- return new RoutingServerProxy(
- source, sourcePath, targetPath, probe);
- }
- };
-
- public static MBeanServer cd(
- MBeanServer source, String sourcePath, boolean probe) {
- return RoutingProxy.cd(RoutingServerProxy.class, FACTORY,
- source, sourcePath, probe);
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/package.html Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
- <head>
- <title>The <code>com.sun.jmx.namespace</code> package</title>
-<!--
-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.
--->
- </head>
- <body bgcolor="white">
- <p>The <code>com.sun.jmx.namespace</code> package contains
- sun specific implementation classes used to implement the
- JMX namespaces.
- </p>
- <p><b>DO NOT USE THESE CLASSES DIRECTLY</b></p>
- <p><b>
- This API is a Sun internal API and is subject to changes without notice.
- </b></p>
- <p>The public API through wich these proprietary classes can be
- invoked is located in <code>javax.management.namespace</code>
- package.
- </p>
- </body>
-</html>
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/DefaultRewritingProcessor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +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.namespace.serial;
-
-
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-/**
- * Class DefaultRewritingProcessor. Rewrite ObjectName in input & output
- * parameters.
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-// We know that rewriting using serialization is costly.
-// This object tries to determine whether an object needs rewriting prior
-// to rewriting, and rewrites by creating a new object in those cases
-// where we know how to recreate a new object (e.g. a Notification).
-// Rewriting is however usually not used - so this object is just a
-// skeleton that eventually uses serialization...
-//
-class DefaultRewritingProcessor extends RewritingProcessor {
-
-
- private static enum RewriteMode {
- INPUT, // Input from target to source (parameters)
- OUTPUT // Output from source to target (results)
- };
-
- private final boolean identity;
-
- public DefaultRewritingProcessor(String targetDirName) {
- this(targetDirName,null);
- }
-
- /** Creates a new instance of SerialParamProcessor */
- public DefaultRewritingProcessor(final String remove, final String add) {
- super(new SerialRewritingProcessor(remove, add));
- identity = remove.equals(add);
- }
-
- private ObjectName rewriteObjectName(RewriteMode mode,
- ObjectName name) {
- return changeContext(mode, name);
- }
-
- private ObjectInstance rewriteObjectInstance(RewriteMode mode,
- ObjectInstance moi) {
- final ObjectName srcName = moi.getObjectName();
- final ObjectName targetName = changeContext(mode,srcName);
- if (targetName == srcName) return moi;
- return new ObjectInstance(targetName,moi.getClassName());
- }
-
-
- private Object processObject(RewriteMode mode, Object obj) {
- if (obj == null) return null;
-
- // Some things which will always needs rewriting:
- // ObjectName, ObjectInstance, and Notifications.
- // Take care of those we can handle here...
- //
- if (obj instanceof ObjectName)
- return rewriteObjectName(mode,(ObjectName) obj);
- else if (obj instanceof ObjectInstance)
- return rewriteObjectInstance(mode,(ObjectInstance) obj);
-
- // TODO: add other standard JMX classes - like e.g. MBeanInfo...
- //
-
- // Well, the object may contain an ObjectName => pass it to
- // our serial rewriting delegate...
- //
- return processAnyObject(mode,obj);
- }
-
-
- private Object processAnyObject(RewriteMode mode, Object obj) {
- switch (mode) {
- case INPUT:
- return super.rewriteInput(obj);
- case OUTPUT:
- return super.rewriteOutput(obj);
- default: // can't happen.
- throw new AssertionError();
- }
- }
-
- private ObjectName changeContext(RewriteMode mode, ObjectName name) {
- switch (mode) {
- case INPUT:
- return toSourceContext(name);
- case OUTPUT:
- return toTargetContext(name);
- default: // can't happen.
- throw new AssertionError();
- }
- }
-
- @Override
- public ObjectName toTargetContext(ObjectName srcName) {
- if (identity) return srcName;
- return super.toTargetContext(srcName);
- }
-
- @Override
- public ObjectName toSourceContext(ObjectName targetName) {
- if (identity) return targetName;
- return super.toSourceContext(targetName);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T> T rewriteInput(T input) {
- if (identity) return input;
- return (T) processObject(RewriteMode.INPUT,input);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T> T rewriteOutput(T result) {
- if (identity) return result;
- return (T) processObject(RewriteMode.OUTPUT,result);
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/IdentityProcessor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.namespace.serial;
-
-
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-/**
- * Class RoutingOnlyProcessor. A RewritingProcessor that uses
- * Java Serialization to rewrite ObjectNames contained in
- * input & results...
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- *
- * @since 1.7
- */
-class IdentityProcessor extends RewritingProcessor {
-
-
- /** Creates a new instance of SerialRewritingProcessor */
- public IdentityProcessor() {
- }
-
- @Override
- public <T> T rewriteOutput(T result) {
- return result;
- }
-
- @Override
- public <T> T rewriteInput(T input) {
- return input;
- }
-
- @Override
- public final ObjectName toTargetContext(ObjectName sourceName) {
- return sourceName;
- }
-
- @Override
- public final ObjectInstance toTargetContext(ObjectInstance sourceMoi) {
- return sourceMoi;
- }
-
- @Override
- public final ObjectName toSourceContext(ObjectName targetName) {
- return targetName;
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/JMXNamespaceContext.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +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.namespace.serial;
-
-import com.sun.jmx.defaults.JmxProperties;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-
-/**
- * The JMXNamespaceContext class is used to implement a thread local
- * serialization / deserialization context for namespaces.
- * <p>
- * This class is consulted by {@link javax.management.ObjectName} at
- * serialization / deserialization time.
- * The serialization or deserialization context is established by
- * by the {@link SerialRewritingProcessor} defined in this package.
- * <p>
- * These classes are Sun proprietary APIs, subject to change without
- * notice. Do not use these classes directly.
- * The public API to rewrite ObjectNames embedded in parameters is
- * defined in {@link javax.management.namespace.JMXNamespaces}.
- *
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public class JMXNamespaceContext {
-
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- public final String prefixToRemove;
- public final String prefixToAdd;
-
- private JMXNamespaceContext(String add, String remove) {
- prefixToRemove = (remove==null?"":remove);
- prefixToAdd = (add==null?"":add);
- }
-
- private final static class SerialContext {
- private JMXNamespaceContext serializationContext;
- private JMXNamespaceContext deserializationContext;
- public SerialContext(){
- serializationContext = new JMXNamespaceContext("","");
- deserializationContext = new JMXNamespaceContext("","");
- }
- }
-
- private final static ThreadLocal<SerialContext> prefix =
- new ThreadLocal<SerialContext>() {
- @Override
- protected SerialContext initialValue() {
- return new SerialContext();
- }
- };
-
- public static JMXNamespaceContext getSerializationContext() {
- return prefix.get().serializationContext;
- }
-
- public static JMXNamespaceContext getDeserializationContext() {
- return prefix.get().deserializationContext;
- }
-
- private static String[] setSerializationContext(String oldPrefix,
- String newPrefix) {
- final SerialContext c = prefix.get();
- JMXNamespaceContext dc = c.serializationContext;
- String[] old = {dc.prefixToRemove, dc.prefixToAdd};
- c.serializationContext = new JMXNamespaceContext(newPrefix,oldPrefix);
- return old;
- }
-
- private static String[] setDeserializationContext(String oldPrefix,
- String newPrefix) {
- final SerialContext c = prefix.get();
- JMXNamespaceContext dc = c.deserializationContext;
- String[] old = {dc.prefixToRemove, dc.prefixToAdd};
- c.deserializationContext = new JMXNamespaceContext(newPrefix,oldPrefix);
- return old;
- }
-
- static void serialize(ObjectOutputStream stream, Object obj,
- String prefixToRemove, String prefixToAdd)
- throws IOException {
- final String[] old =
- setSerializationContext(prefixToRemove,prefixToAdd);
- try {
- stream.writeObject(obj);
- } finally {
- try {
- setSerializationContext(old[0],old[1]);
- } catch (Exception x) {
- LOG.log(Level.FINEST,
- "failed to restore serialization context",x);
- }
- }
- }
-
- static Object deserialize(ObjectInputStream stream,
- String prefixToRemove,
- String prefixToAdd)
- throws IOException, ClassNotFoundException {
- final String[] old =
- setDeserializationContext(prefixToRemove,prefixToAdd);
- try {
- return stream.readObject();
- } finally {
- try {
- setDeserializationContext(old[0],old[1]);
- } catch (Exception x) {
- LOG.log(Level.FINEST,
- "failed to restore serialization context",x);
- }
- }
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/RewritingProcessor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +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.namespace.serial;
-
-
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-/**
- * An object that can rewrite ObjectNames contained in input/output
- * parameters when entering/leaving a {@link javax.management.namespace
- * namespace}.
- * <p>When entering a {@link javax.management.namespace
- * namespace}, the {@code namespace} prefix is stripped from
- * ObjectNames contained in input parameters. When leaving a
- * {@code namespace},
- * the {@code namespace} prefix is prepended to the ObjectNames contained in
- * the result parameters returned from that {@code namespace}.
- * </p>
- * <p>Objects that need to perform these operations usually use a
- * {@code RewritingProcessor} for that purpose.<br>
- * The {@code RewritingProcessor} allows a somewhat larger
- * transformation in which part of a prefix {@link #newRewritingProcessor
- * remove} can be replaced by another prefix {@link #newRewritingProcessor
- * add}. The transformation described above correspond to the case where
- * {@code remove} is the stripped {@link javax.management.namespace
- * namespace} prefix (removed when entering the {@code namespace}) and
- * {@code add} is the empty String {@code ""}.
- * <br>
- * It is interesting to note that {@link
- * javax.management.JMXNamespaces#narrowToNamespace narrowToNamespace}
- * operations use the inverse transformation (that is, {@code remove} is
- * the empty String {@code ""} and {@code add} is the {@link
- * javax.management.namespace namespace} prefix).
- * <br>
- * On a more general scale, {@link #rewriteInput rewriteInput} removes
- * {@link #newRewritingProcessor remove} and the prepend {@link
- * #newRewritingProcessor add}, and {@link #rewriteOutput rewriteOutput}
- * does the opposite, removing {@link #newRewritingProcessor add}, and
- * then adding {@link #newRewritingProcessor remove}.
- * <br>
- * An implementation of {@code RewritingProcessor} should make sure that
- * <code>rewriteInput(rewriteOutput(x,clp),clp)</code> and
- * <code>rewriteOutput(rewriteInput(x,clp),clp)</code> always return
- * {@code x} or an exact clone of {@code x}.
- * </p>
- * <p>A default implementation of {@code RewritingProcessor} based on
- * Java Object Serialization can be
- * obtained from {@link #newRewritingProcessor newRewritingProcessor}.
- * </p>
- * <p>
- * By default, the instances of {@code RewritingProcessor} returned by
- * {@link #newRewritingProcessor newRewritingProcessor} will rewrite
- * ObjectNames contained in instances of classes they don't know about by
- * serializing and then deserializing such object instances. This will
- * happen even if such instances don't - or can't contain ObjectNames,
- * because the default implementation of {@code RewritingProcessor} will
- * not be able to determine whether instances of such classes can/do contain
- * instance of ObjectNames before serializing/deserializing them.
- * </p>
- * <p>If you are using custom classes that the default implementation of
- * {@code RewritingProcessor} don't know about, it can be interesting to
- * prevent an instance of {@code RewritingProcessor} to serialize/deserialize
- * instances of such classes for nothing. In that case, you could customize
- * the behavior of such a {@code RewritingProcessor} by wrapping it in a
- * custom subclass of {@code RewritingProcessor} as shown below:
- * <pre>
- * public class MyRewritingProcessor extends RewritingProcessor {
- * MyRewritingProcessor(String remove, String add) {
- * this(RewritingProcessor.newRewritingProcessor(remove,add));
- * }
- * MyRewritingProcessor(RewritingProcessor delegate) {
- * super(delegate);
- * }
- *
- * <T> T rewriteInput(T input) {
- * if (input == null) return null;
- * if (MyClass.equals(input.getClass())) {
- * // I know that MyClass doesn't contain any ObjectName
- * return (T) input;
- * }
- * return super.rewriteInput(input);
- * }
- * <T> T rewriteOutput(T result) {
- * if (result == null) return null;
- * if (MyClass.equals(result.getClass())) {
- * // I know that MyClass doesn't contain any ObjectName
- * return (T) result;
- * }
- * return super.rewriteOutput(result);
- * }
- * }
- * </pre>
- * </p>
- * <p>Such a subclass may also provide an alternate way of rewriting
- * custom subclasses for which rewriting is needed - for instance:
- * <pre>
- * public class MyRewritingProcessor extends RewritingProcessor {
- * MyRewritingProcessor(String remove, String add) {
- * this(RewritingProcessor.newRewritingProcessor(remove,add));
- * }
- * MyRewritingProcessor(RewritingProcessor delegate) {
- * super(delegate);
- * }
- *
- * <T> T rewriteInput(T input) {
- * if (input == null) return null;
- * if (MyClass.equals(input.getClass())) {
- * // I know that MyClass doesn't contain any ObjectName
- * return (T) input;
- * } else if (MyOtherClass.equals(input.getClass())) {
- * // Returns a new instance in which ObjectNames have been
- * // replaced.
- * final ObjectName aname = ((MyOtherClass)input).getName();
- * return (T) (new MyOtherClass(super.rewriteInput(aname)));
- * }
- * return super.rewriteInput(input,clp);
- * }
- * <T> T rewriteOutput(T result) {
- * if (result == null) return null;
- * if (MyClass.equals(result.getClass())) {
- * // I know that MyClass doesn't contain any ObjectName
- * return (T) result;
- * } else if (MyOtherClass.equals(result.getClass())) {
- * // Returns a new instance in which ObjectNames have been
- * // replaced.
- * final ObjectName aname = ((MyOtherClass)result).getName();
- * return (T) (new MyOtherClass(super.rewriteOutput(aname)));
- * }
- * return super.rewriteOutput(result,clp);
- * }
- * }
- * </pre>
- * </p>
- * <p>If your application only uses {@link javax.management.MXBean MXBeans},
- * or MBeans using simple types, and doesn't define any custom subclass of
- * {@link javax.management.Notification}, you should never write such
- * such {@code RewitingProcessor} implementations.
- * </p>
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-public abstract class RewritingProcessor {
- /**
- * A logger for this class.
- **/
- private final RewritingProcessor delegate;
-
- /**
- * Creates a new instance of RewritingProcessor.
- * <p>This is equivalent to calling {@link
- * #RewritingProcessor(RewritingProcessor) RewritingProcessor(null)}.
- * </p>
- **/
- protected RewritingProcessor() {
- this(null);
- }
-
- /**
- * Creates a new instance of RewritingProcessor, with a delegate.
- * @param delegate a {@code RewritingProcessor} to which all the
- * calls will be delegated. When implementing a subclass
- * of {@code RewritingProcessor}, calling {@link
- * #rewriteInput super.rewriteInput} will invoke
- * {@code delegate.rewriteInput} and calling {@link
- * #rewriteOutput super.rewriteOutput} will invoke
- * {@code delegate.rewriteOutput}.
- *
- **/
- protected RewritingProcessor(RewritingProcessor delegate) {
- this.delegate = delegate;
- }
-
- /**
- * Rewrites ObjectNames when {@link RewritingProcessor leaving} a {@link
- * javax.management.namespace namespace}.
- * <p>
- * Returns {@code obj}, if it is known that {@code obj} doesn't contain
- * any ObjectName, or a new copied instance of {@code obj} in which
- * ObjectNames (if any) will have been rewritten, if {@code obj} contains
- * ObjectNames, or if it is not known whether {@code obj} contains
- * ObjectNames or not.
- * </p>
- * <p>
- * The default implementation of this method is as follows: if the
- * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
- * null}, throws an {@link IllegalArgumentException}. Otherwise,
- * returns {@code delegate.rewriteOutput(obj)}.
- * </p>
- * <p>This behavior can be overridden by subclasses as shown in this
- * class {@link RewritingProcessor description}.
- * </p>
- * @param obj The result to be rewritten if needed.
- *
- * @return {@code obj}, or a clone of {@code obj} in which ObjectNames
- * have been rewritten. See this class {@link RewritingProcessor
- * description} for more details.
- * @throws IllegalArgumentException if this implementation does not know
- * how to rewrite the object.
- **/
- public <T> T rewriteOutput(T obj) {
- if (obj == null) return null;
- if (delegate != null)
- return delegate.rewriteOutput(obj);
- throw new IllegalArgumentException("can't rewrite "+
- obj.getClass().getName());
- }
-
- /**
- * Rewrites ObjectNames when {@link RewritingProcessor entering} a {@link
- * javax.management.namespace namespace}.
- * <p>
- * Returns {@code obj}, if it is known that {@code obj} doesn't contain
- * any ObjectName, or a new copied instance of {@code obj} in which
- * ObjectNames (if any) will have been rewritten, if {@code obj} contains
- * ObjectNames, or if it is not known whether {@code obj} contains
- * ObjectNames or not.
- * </p>
- * <p>
- * The default implementation of this method is as follows: if the
- * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
- * null}, throws an {@link IllegalArgumentException}. Otherwise,
- * returns {@code delegate.rewriteInput(obj)}.
- * </p>
- * <p>This behavior can be overridden by subclasses as shown in this
- * class {@link RewritingProcessor description}.
- * </p>
- * @param obj The result to be rewritten if needed.
- * @return {@code obj}, or a clone of {@code obj} in which ObjectNames
- * have been rewritten. See this class {@link RewritingProcessor
- * description} for more details.
- * @throws IllegalArgumentException if this implementation does not know
- * how to rewrite the object.
- **/
- public <T> T rewriteInput(T obj) {
- if (obj == null) return null;
- if (delegate != null)
- return delegate.rewriteInput(obj);
- throw new IllegalArgumentException("can't rewrite "+
- obj.getClass().getName());
- }
-
- /**
- * Translate a routing ObjectName from the target (calling) context to
- * the source (called) context when {@link RewritingProcessor entering} a
- * {@link javax.management.namespace namespace}.
- * <p>
- * The default implementation of this method is as follows: if the
- * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
- * null}, throws an {@link IllegalArgumentException}. Otherwise,
- * returns {@code delegate.toSourceContext(targetName)}.
- * </p>
- * <p>This behavior can be overridden by subclasses as shown in this
- * class {@link RewritingProcessor description}.
- * </p>
- * @param targetName The routing target ObjectName to translate.
- * @return The ObjectName translated to the source context.
- * @throws IllegalArgumentException if this implementation does not know
- * how to rewrite the object.
- **/
- public ObjectName toSourceContext(ObjectName targetName) {
- if (delegate != null)
- return delegate.toSourceContext(targetName);
- throw new IllegalArgumentException("can't rewrite targetName: "+
- " no delegate.");
- }
-
- /**
- * Translate an ObjectName returned from the source context into
- * the target (calling) context when {@link RewritingProcessor leaving} a
- * {@link javax.management.namespace namespace}.
- * <p>
- * The default implementation of this method is as follows: if the
- * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
- * null}, throws an {@link IllegalArgumentException}. Otherwise,
- * returns {@code delegate.toTargetContext(sourceName)}.
- * </p>
- * <p>This behavior can be overridden by subclasses as shown in this
- * class {@link RewritingProcessor description}.
- * </p>
- * @param sourceName The routing source ObjectName to translate to the
- * target context.
- * @return The ObjectName translated to the target context.
- * @throws IllegalArgumentException if this implementation does not know
- * how to rewrite the object.
- **/
- public ObjectName toTargetContext(ObjectName sourceName) {
- if (delegate != null)
- return delegate.toTargetContext(sourceName);
- throw new IllegalArgumentException("can't rewrite sourceName: "+
- " no delegate.");
- }
-
- /**
- * Translate an ObjectInstance returned from the source context into
- * the target (calling) context when {@link RewritingProcessor leaving} a
- * {@link javax.management.namespace namespace}.
- * <p>
- * The default implementation of this method is as follows: if the
- * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
- * null}, throws an {@link IllegalArgumentException}. Otherwise,
- * returns {@code delegate.toTargetContext(sourceMoi)}.
- * </p>
- * <p>This behavior can be overridden by subclasses as shown in this
- * class {@link RewritingProcessor description}.
- * </p>
- * @param sourceMoi The routing source ObjectInstance to translate.
- * @return The ObjectInstance translated to the target context.
- * @throws IllegalArgumentException if this implementation does not know
- * how to rewrite the object.
- **/
- public ObjectInstance toTargetContext(ObjectInstance sourceMoi) {
- if (delegate != null)
- return delegate.toTargetContext(sourceMoi);
- throw new IllegalArgumentException("can't rewrite sourceName: "+
- " no delegate.");
- }
-
- /**
- * Creates a new default instance of {@link RewritingProcessor}.
- * @param remove The prefix to remove from {@link ObjectName ObjectNames}
- * when {@link RewritingProcessor entering} the {@link
- * javax.management.namespace namespace}.
- * @param add The prefix to add to {@link ObjectName ObjectNames}
- * when {@link RewritingProcessor entering} the {@link
- * javax.management.namespace namespace} (this is performed
- * after having removed the {@code remove} prefix.
- * @return A new {@link RewritingProcessor} processor object that will
- * perform the requested operation, using Java serialization if
- * necessary.
- **/
- public static RewritingProcessor newRewritingProcessor(String remove,
- String add) {
- return new DefaultRewritingProcessor(remove,add);
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/RoutingOnlyProcessor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.namespace.serial;
-
-import com.sun.jmx.namespace.ObjectNameRouter;
-
-
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-/**
- * Class RoutingOnlyProcessor. A RewritingProcessor that uses
- * Java Serialization to rewrite ObjectNames contained in
- * input and results...
- *
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-class RoutingOnlyProcessor extends RewritingProcessor {
-
- final ObjectNameRouter router;
-
- public RoutingOnlyProcessor(String targetDirName) {
- this(targetDirName,null);
- }
-
- /** Creates a new instance of RoutingOnlyProcessor */
- public RoutingOnlyProcessor(final String remove, final String add) {
- super(new IdentityProcessor());
- if (remove == null || add == null)
- throw new IllegalArgumentException("Null argument");
- router = new ObjectNameRouter(remove,add);
- }
-
- @Override
- public final ObjectName toTargetContext(ObjectName sourceName) {
- return router.toTargetContext(sourceName,false);
- }
-
- @Override
- public final ObjectName toSourceContext(ObjectName targetName) {
- return router.toSourceContext(targetName,false);
- }
-
- @Override
- public final ObjectInstance toTargetContext(ObjectInstance sourceMoi) {
- return router.toTargetContext(sourceMoi,false);
- }
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/SerialRewritingProcessor.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +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.namespace.serial;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidClassException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
-import java.io.OutputStream;
-import java.util.LinkedList;
-import java.util.Queue;
-
-import javax.management.ObjectName;
-
-/**
- * Class SerialRewritingProcessor. A RewritingProcessor that uses
- * Java Serialization to rewrite ObjectNames contained in
- * input & results...
- * <p><b>
- * This API is a Sun internal API and is subject to changes without notice.
- * </b></p>
- * @since 1.7
- */
-class SerialRewritingProcessor extends RewritingProcessor {
-
-
- private static class CloneOutput extends ObjectOutputStream {
- Queue<Class<?>> classQueue = new LinkedList<Class<?>>();
-
- CloneOutput(OutputStream out) throws IOException {
- super(out);
- }
-
- @Override
- protected void annotateClass(Class<?> c) {
- classQueue.add(c);
- }
-
- @Override
- protected void annotateProxyClass(Class<?> c) {
- classQueue.add(c);
- }
- }
-
- private static class CloneInput extends ObjectInputStream {
- private final CloneOutput output;
-
- CloneInput(InputStream in, CloneOutput output) throws IOException {
- super(in);
- this.output = output;
- }
-
- @Override
- protected Class<?> resolveClass(ObjectStreamClass osc)
- throws IOException, ClassNotFoundException {
- Class<?> c = output.classQueue.poll();
- String expected = osc.getName();
- String found = (c == null) ? null : c.getName();
- if (!expected.equals(found)) {
- throw new InvalidClassException("Classes desynchronized: " +
- "found " + found + " when expecting " + expected);
- }
- return c;
- }
-
- @Override
- protected Class<?> resolveProxyClass(String[] interfaceNames)
- throws IOException, ClassNotFoundException {
- return output.classQueue.poll();
- }
- }
-
-
- final String targetPrefix;
- final String sourcePrefix;
- final boolean identity;
-
-
- public SerialRewritingProcessor(String targetDirName) {
- this(targetDirName,null);
- }
-
- /** Creates a new instance of SerialRewritingProcessor */
- public SerialRewritingProcessor(final String remove, final String add) {
- super(new RoutingOnlyProcessor(remove,add));
- this.targetPrefix = remove;
- this.sourcePrefix = add;
- identity = targetPrefix.equals(sourcePrefix);
- }
-
- private <T> T switchContext(T result, String from,String to)
- throws IOException, ClassNotFoundException {
- final ByteArrayOutputStream baos = new ByteArrayOutputStream();
- final CloneOutput ostream = new CloneOutput(baos);
-
- JMXNamespaceContext.serialize(ostream,result,from,null);
- ostream.flush();
-
- final byte[] bytes = baos.toByteArray();
- final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- final CloneInput istream = new CloneInput(bais, ostream);
- @SuppressWarnings("unchecked")
- final T clone = (T) JMXNamespaceContext.deserialize(istream,null,to);
- return clone;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T> T rewriteOutput(T result) {
- if (identity) return result;
- return (T) processOutput(result);
- }
-
- private Object processOutput(Object result) {
- try {
- if (result instanceof ObjectName)
- return toTargetContext((ObjectName) result);
- return switchContext(result,sourcePrefix,targetPrefix);
- } catch (ClassNotFoundException x) {
- throw new IllegalArgumentException("Can't process result: "+x,x);
- } catch (IOException x) {
- throw new IllegalArgumentException("Can't process result: "+x,x);
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T> T rewriteInput(T input) {
- if (identity) return input;
- return (T) processInput(input);
- }
-
- private Object processInput(Object input) {
- try {
- if (input instanceof ObjectName)
- return toSourceContext((ObjectName) input);
- return switchContext(input,targetPrefix,sourcePrefix);
- } catch (ClassNotFoundException x) {
- throw new IllegalArgumentException("Can't process input: "+x,x);
- } catch (IOException x) {
- throw new IllegalArgumentException("Can't process input: "+x,x);
- }
- }
-
-}
--- a/jdk/src/share/classes/com/sun/jmx/namespace/serial/package.html Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
- <head>
- <title>The <code>com.sun.jmx.namespace.serial</code> package</title>
-<!--
-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.
--->
- </head>
- <body bgcolor="white">
- <p>The <code>com.sun.jmx.namespace.serial</code> package contains
- sun specific implementation classes used to switch namespace
- prefixes in ObjectName during serialization.
- </p>
- <p><b>NEVER USE THESE CLASSES DIRECTLY</b></p>
- <p><b>
- This API is a Sun internal API and is subject to changes without notice.
- </b></p>
- <p>The public API through which these proprietary classes can be invoked is
- located in <code>javax.management.namespace.JMXNamespaces</code>
- </p>
- </body>
-</html>
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Wed Oct 21 16:50:44 2009 +0100
@@ -86,8 +86,7 @@
// Explicitly check MBeanPermission for addNotificationListener
//
- checkMBeanPermission(getMBeanServerName(),
- mbeanServer, name, "addNotificationListener");
+ checkMBeanPermission(name, "addNotificationListener");
if (notificationAccessController != null) {
notificationAccessController.addNotificationListener(
connectionId, name, getSubject());
@@ -157,8 +156,7 @@
// Explicitly check MBeanPermission for removeNotificationListener
//
- checkMBeanPermission(getMBeanServerName(),
- mbeanServer, name, "removeNotificationListener");
+ checkMBeanPermission(name, "removeNotificationListener");
if (notificationAccessController != null) {
notificationAccessController.removeNotificationListener(
connectionId, name, getSubject());
@@ -333,8 +331,8 @@
* Explicitly check the MBeanPermission for
* the current access control context.
*/
- public static void checkMBeanPermission(String serverName,
- final MBeanServer mbs, final ObjectName name, final String actions)
+ public void checkMBeanPermission(
+ final ObjectName name, final String actions)
throws InstanceNotFoundException, SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -345,7 +343,7 @@
new PrivilegedExceptionAction<ObjectInstance>() {
public ObjectInstance run()
throws InstanceNotFoundException {
- return mbs.getObjectInstance(name);
+ return mbeanServer.getObjectInstance(name);
}
});
} catch (PrivilegedActionException e) {
@@ -353,7 +351,6 @@
}
String classname = oi.getClassName();
MBeanPermission perm = new MBeanPermission(
- serverName,
classname,
null,
name,
@@ -369,8 +366,7 @@
TargetedNotification tn) {
try {
if (checkNotificationEmission) {
- checkMBeanPermission(getMBeanServerName(),
- mbeanServer, name, "addNotificationListener");
+ checkMBeanPermission(name, "addNotificationListener");
}
if (notificationAccessController != null) {
notificationAccessController.fetchNotification(
@@ -432,27 +428,12 @@
}
}
- private String getMBeanServerName() {
- if (mbeanServerName != null) return mbeanServerName;
- else return (mbeanServerName = getMBeanServerName(mbeanServer));
- }
-
- private static String getMBeanServerName(final MBeanServer server) {
- final PrivilegedAction<String> action = new PrivilegedAction<String>() {
- public String run() {
- return Util.getMBeanServerSecurityName(server);
- }
- };
- return AccessController.doPrivileged(action);
- }
-
//------------------
// PRIVATE VARIABLES
//------------------
private MBeanServer mbeanServer;
- private volatile String mbeanServerName;
private final String connectionId;
@@ -462,7 +443,7 @@
private final static int[] listenerCounterLock = new int[0];
private NotificationBuffer notifBuffer;
- private Map<ObjectName, Set<IdAndFilter>> listenerMap =
+ private final Map<ObjectName, Set<IdAndFilter>> listenerMap =
new HashMap<ObjectName, Set<IdAndFilter>>();
private boolean terminated = false;
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Wed Oct 21 16:50:44 2009 +0100
@@ -781,25 +781,6 @@
}
/**
- * Returns true if the parameter JMXConnector.USE_EVENT_SERVICE is set to a
- * String equals "true" by ignoring case in the map or in the System.
- */
- public static boolean eventServiceEnabled(Map<String, ?> env) {
- return computeBooleanFromString(env, JMXConnector.USE_EVENT_SERVICE, true);
- }
-
- /**
- * Returns true if the parameter JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE
- * is set to a String equals "true" (ignores case).
- * If the property DELEGATE_TO_EVENT_SERVICE is not set, returns
- * a default value of "true".
- */
- public static boolean delegateToEventService(Map<String, ?> env) {
- return computeBooleanFromString(env,
- JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE, true, true);
- }
-
- /**
* <p>Name of the attribute that specifies whether a connector server
* should not prevent the VM from exiting
*/
@@ -817,46 +798,6 @@
("true".equalsIgnoreCase((String)env.get(JMX_SERVER_DAEMON)));
}
-// /**
-// * <p>Name of the attribute that specifies an EventRelay object to use.
-// */
-// public static final String EVENT_RELAY =
-// "jmx.remote.x.event.relay";
-//
-//
-// /**
-// * Returns an EventRelay object. The default one is FetchingEventRelay.
-// * If {@code EVENT_RELAY} is specified in {@code env} as a key,
-// * its value will be returned as an EventRelay object, if the value is
-// * not of type {@code EventRelay}, the default {@code FetchingEventRelay}
-// * will be returned.
-// * If {@code EVENT_RELAY} is not specified but {@code ENABLE_EVENT_RELAY}
-// * is specified as a key and its value is <code true>, the default {@code FetchingEventRelay}
-// * will be returned.
-// */
-// public static EventRelay getEventRelay(Map env) {
-// Map info = env == null ?
-// Collections.EMPTY_MAP : env;
-//
-// Object o = env.get(EVENT_RELAY);
-// if (o instanceof EventRelay) {
-// return (EventRelay)o;
-// } else if (o != null) {
-// logger.warning("getEventRelay",
-// "The user specified object is not an EventRelay object, " +
-// "using the default class FetchingEventRelay.");
-//
-// return new FetchingEventRelay();
-// }
-//
-// if (enableEventRelay(env)) {
-// return new FetchingEventRelay();
-// }
-//
-// return null;
-// }
-
-
private static final class SinkOutputStream extends OutputStream {
public void write(byte[] b, int off, int len) {}
public void write(int b) {}
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,469 +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.remote.util;
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.event.EventClientFactory;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.MBeanServerConnection;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.namespace.JMXNamespaces;
-
-/**
- * Class EventClientConnection - a {@link Proxy} that wraps an
- * {@link MBeanServerConnection} and an {@link EventClient}.
- * All methods are routed to the underlying {@code MBeanServerConnection},
- * except add/remove notification listeners which are routed to the
- * {@code EventClient}.
- * The caller only sees an {@code MBeanServerConnection} which uses an
- * {@code EventClient} behind the scenes.
- *
- * @author Sun Microsystems, Inc.
- */
-public class EventClientConnection implements InvocationHandler,
- EventClientFactory {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NOTIFICATION_LOGGER;
-
- private static final int NAMESPACE_SEPARATOR_LENGTH =
- JMXNamespaces.NAMESPACE_SEPARATOR.length();
-
- /**
- * Creates a new {@code EventClientConnection}.
- * @param connection The underlying MBeanServerConnection.
- */
- public EventClientConnection(MBeanServerConnection connection) {
- this(connection,null);
- }
-
- /**
- * Creates a new {@code EventClientConnection}.
- * @param connection The underlying MBeanServerConnection.
- * @param eventClientFactory a factory object that will be invoked
- * to create an {@link EventClient} when needed.
- * The {@code EventClient} is created lazily, when it is needed
- * for the first time. If null, a default factory will be used
- * (see {@link #createEventClient}).
- */
- public EventClientConnection(MBeanServerConnection connection,
- Callable<EventClient> eventClientFactory) {
-
- if (connection == null) {
- throw new IllegalArgumentException("Null connection");
- }
- this.connection = connection;
- if (eventClientFactory == null) {
- eventClientFactory = new Callable<EventClient>() {
- public final EventClient call() throws Exception {
- return createEventClient(EventClientConnection.this.connection);
- }
- };
- }
- this.eventClientFactory = eventClientFactory;
- this.lock = new ReentrantLock();
- }
-
- /**
- * <p>The MBean server connection through which the methods of
- * a proxy using this handler are forwarded.</p>
- *
- * @return the MBean server connection.
- *
- * @since 1.6
- */
- public MBeanServerConnection getMBeanServerConnection() {
- return connection;
- }
-
-
-
-
- /**
- * Creates a new EventClientConnection proxy instance.
- *
- * @param <T> The underlying {@code MBeanServerConnection} - which should
- * not be using the Event Service itself.
- * @param interfaceClass {@code MBeanServerConnection.class}, or a subclass.
- * @param eventClientFactory a factory used to create the EventClient.
- * If null, a default factory is used (see {@link
- * #createEventClient}).
- * @return the new proxy instance, which will route add/remove notification
- * listener calls through an {@code EventClient}.
- *
- */
- private static <T extends MBeanServerConnection> T
- newProxyInstance(T connection,
- Class<T> interfaceClass, Callable<EventClient> eventClientFactory) {
- final InvocationHandler handler =
- new EventClientConnection(connection,eventClientFactory);
- final Class<?>[] interfaces =
- new Class<?>[] {interfaceClass, EventClientFactory.class};
-
- Object proxy =
- Proxy.newProxyInstance(interfaceClass.getClassLoader(),
- interfaces,
- handler);
- return interfaceClass.cast(proxy);
- }
-
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- final String methodName = method.getName();
-
- // add/remove notification listener are routed to the EventClient
- if (methodName.equals("addNotificationListener")
- || methodName.equals("removeNotificationListener")) {
- final Class<?>[] sig = method.getParameterTypes();
- if (sig.length>1 &&
- NotificationListener.class.isAssignableFrom(sig[1])) {
- return invokeBroadcasterMethod(proxy,method,args);
- }
- }
-
- // subscribe/unsubscribe are also routed to the EventClient.
- final Class<?> clazz = method.getDeclaringClass();
- if (clazz.equals(EventClientFactory.class)) {
- return invokeEventClientSubscriberMethod(proxy,method,args);
- }
-
- // local or not: equals, toString, hashCode
- if (shouldDoLocally(proxy, method))
- return doLocally(proxy, method, args);
-
- return call(connection,method,args);
- }
-
- // The purpose of this method is to unwrap InvocationTargetException,
- // in order to avoid throwing UndeclaredThrowableException for
- // declared exceptions.
- //
- // When calling method.invoke(), any exception thrown by the invoked
- // method will be wrapped in InvocationTargetException. If we don't
- // unwrap this exception, the proxy will always throw
- // UndeclaredThrowableException, even for runtime exceptions.
- //
- private Object call(final Object obj, final Method m,
- final Object[] args)
- throws Throwable {
- try {
- return m.invoke(obj,args);
- } catch (InvocationTargetException x) {
- final Throwable xx = x.getTargetException();
- if (xx == null) throw x;
- else throw xx;
- }
- }
-
- /**
- * Route add/remove notification listener to the event client.
- **/
- private Object invokeBroadcasterMethod(Object proxy, Method method,
- Object[] args) throws Exception {
- final String methodName = method.getName();
- final int nargs = (args == null) ? 0 : args.length;
-
- if (nargs < 1) {
- final String msg =
- "Bad arg count: " + nargs;
- throw new IllegalArgumentException(msg);
- }
-
- final ObjectName mbean = (ObjectName) args[0];
- final EventClient evtClient = getEventClient();
-
- // Fails if evtClient is null AND the MBean we try to listen to is
- // in a subnamespace. We fail here because we know this will not
- // work.
- //
- // Note that if the wrapped MBeanServerConnection points to a an
- // earlier agent (JDK 1.6 or earlier), then the EventClient will
- // be null (we can't use the event service with earlier JDKs).
- //
- // In principle a null evtClient indicates that the remote VM is of
- // an earlier version, in which case it shouldn't contain any namespace.
- //
- // So having a null evtClient AND an MBean contained in a namespace is
- // clearly an error case.
- //
- if (evtClient == null) {
- final String domain = mbean.getDomain();
- final int index = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR);
- if (index > -1 && index <
- (domain.length()-NAMESPACE_SEPARATOR_LENGTH)) {
- throw new UnsupportedOperationException(method.getName()+
- " on namespace "+domain.substring(0,index+
- NAMESPACE_SEPARATOR_LENGTH));
- }
- }
-
- if (methodName.equals("addNotificationListener")) {
- /* The various throws of IllegalArgumentException here
- should not happen, since we know what the methods in
- NotificationBroadcaster and NotificationEmitter
- are. */
- if (nargs != 4) {
- final String msg =
- "Bad arg count to addNotificationListener: " + nargs;
- throw new IllegalArgumentException(msg);
- }
- /* Other inconsistencies will produce ClassCastException
- below. */
-
- final NotificationListener listener = (NotificationListener) args[1];
- final NotificationFilter filter = (NotificationFilter) args[2];
- final Object handback = args[3];
-
- if (evtClient != null) {
- // general case
- evtClient.addNotificationListener(mbean,listener,filter,handback);
- } else {
- // deprecated case. Only works for mbean in local namespace.
- connection.addNotificationListener(mbean,listener,filter,
- handback);
- }
- return null;
-
- } else if (methodName.equals("removeNotificationListener")) {
-
- /* NullPointerException if method with no args, but that
- shouldn't happen because removeNL does have args. */
- NotificationListener listener = (NotificationListener) args[1];
-
- switch (nargs) {
- case 2:
- if (evtClient != null) {
- // general case
- evtClient.removeNotificationListener(mbean,listener);
- } else {
- // deprecated case. Only works for mbean in local namespace.
- connection.removeNotificationListener(mbean, listener);
- }
- return null;
-
- case 4:
- NotificationFilter filter = (NotificationFilter) args[2];
- Object handback = args[3];
- if (evtClient != null) {
- evtClient.removeNotificationListener(mbean,
- listener,
- filter,
- handback);
- } else {
- connection.removeNotificationListener(mbean,
- listener,
- filter,
- handback);
- }
- return null;
-
- default:
- final String msg =
- "Bad arg count to removeNotificationListener: " + nargs;
- throw new IllegalArgumentException(msg);
- }
-
- } else {
- throw new IllegalArgumentException("Bad method name: " +
- methodName);
- }
- }
-
- private boolean shouldDoLocally(Object proxy, Method method) {
- final String methodName = method.getName();
- if ((methodName.equals("hashCode") || methodName.equals("toString"))
- && method.getParameterTypes().length == 0
- && isLocal(proxy, method))
- return true;
- if (methodName.equals("equals")
- && Arrays.equals(method.getParameterTypes(),
- new Class<?>[] {Object.class})
- && isLocal(proxy, method))
- return true;
- return false;
- }
-
- private Object doLocally(Object proxy, Method method, Object[] args) {
- final String methodName = method.getName();
-
- if (methodName.equals("equals")) {
-
- if (this == args[0]) {
- return true;
- }
-
- if (!(args[0] instanceof Proxy)) {
- return false;
- }
-
- final InvocationHandler ihandler =
- Proxy.getInvocationHandler(args[0]);
-
- if (ihandler == null ||
- !(ihandler instanceof EventClientConnection)) {
- return false;
- }
-
- final EventClientConnection handler =
- (EventClientConnection)ihandler;
-
- return connection.equals(handler.connection) &&
- proxy.getClass().equals(args[0].getClass());
- } else if (methodName.equals("hashCode")) {
- return connection.hashCode();
- }
-
- throw new RuntimeException("Unexpected method name: " + methodName);
- }
-
- private static boolean isLocal(Object proxy, Method method) {
- final Class<?>[] interfaces = proxy.getClass().getInterfaces();
- if(interfaces == null) {
- return true;
- }
-
- final String methodName = method.getName();
- final Class<?>[] params = method.getParameterTypes();
- for (Class<?> intf : interfaces) {
- try {
- intf.getMethod(methodName, params);
- return false; // found method in one of our interfaces
- } catch (NoSuchMethodException nsme) {
- // OK.
- }
- }
-
- return true; // did not find in any interface
- }
-
- /**
- * Return the EventClient used by this object. Can be null if the
- * remote VM is of an earlier JDK version which doesn't have the
- * event service.<br>
- * This method will invoke the event client factory the first time
- * it is called.
- **/
- public final EventClient getEventClient() {
- if (initialized) return client;
- try {
- if (!lock.tryLock(TRYLOCK_TIMEOUT,TimeUnit.SECONDS))
- throw new IllegalStateException("can't acquire lock");
- try {
- client = eventClientFactory.call();
- initialized = true;
- } finally {
- lock.unlock();
- }
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new IllegalStateException("Can't create EventClient: "+x,x);
- }
- return client;
- }
-
- /**
- * Returns an event client for the wrapped {@code MBeanServerConnection}.
- * This is the method invoked by the default event client factory.
- * @param connection the wrapped {@code MBeanServerConnection}.
- **/
- protected EventClient createEventClient(MBeanServerConnection connection)
- throws Exception {
- final ObjectName name =
- EventClientDelegate.OBJECT_NAME;
- if (connection.isRegistered(name)) {
- return new EventClient(connection);
- }
- return null;
- }
-
- /**
- * Creates a new {@link MBeanServerConnection} that goes through an
- * {@link EventClient} to receive/subscribe to notifications.
- * @param connection the underlying {@link MBeanServerConnection}.
- * The given <code>connection</code> shouldn't be already
- * using an {@code EventClient}.
- * @param eventClientFactory a factory object that will be invoked
- * to create an {@link EventClient} when needed.
- * The {@code EventClient} is created lazily, when it is needed
- * for the first time. If null, a default factory will be used
- * (see {@link #createEventClient}).
- * @return the MBeanServerConnection.
- **/
- public static MBeanServerConnection getEventConnectionFor(
- MBeanServerConnection connection,
- Callable<EventClient> eventClientFactory) {
- if (connection instanceof EventClientFactory
- && eventClientFactory != null)
- throw new IllegalArgumentException("connection already uses EventClient");
-
- if (connection instanceof EventClientFactory)
- return connection;
-
- // create a new proxy using an event client.
- //
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("Creating EventClient for: "+connection);
- return newProxyInstance(connection,
- MBeanServerConnection.class,
- eventClientFactory);
- }
-
- private Object invokeEventClientSubscriberMethod(Object proxy,
- Method method, Object[] args) throws Throwable {
- return call(this,method,args);
- }
-
- // Maximum lock timeout in seconds. Obviously arbitrary.
- //
- private final static short TRYLOCK_TIMEOUT = 3;
-
- private final MBeanServerConnection connection;
- private final Callable<EventClient> eventClientFactory;
- private final Lock lock;
- private volatile EventClient client = null;
- private volatile boolean initialized = false;
-
-}
--- a/jdk/src/share/classes/java/lang/management/PlatformComponent.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/java/lang/management/PlatformComponent.java Wed Oct 21 16:50:44 2009 +0100
@@ -40,6 +40,7 @@
import com.sun.management.UnixOperatingSystemMXBean;
import sun.management.ManagementFactoryHelper;
+import sun.management.Util;
/**
* This enum class defines the list of platform components
@@ -384,7 +385,7 @@
// if there are more than 1 key properties (i.e. other than "type")
domainAndType += ",*";
}
- ObjectName on = ObjectName.valueOf(domainAndType);
+ ObjectName on = Util.newObjectName(domainAndType);
Set<ObjectName> set = mbs.queryNames(on, null);
for (PlatformComponent pc : subComponents) {
set.addAll(pc.getObjectNames(mbs));
--- a/jdk/src/share/classes/java/util/logging/Logging.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/java/util/logging/Logging.java Wed Oct 21 16:50:44 2009 +0100
@@ -29,6 +29,7 @@
import java.util.List;
import java.util.ArrayList;
+import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
/**
@@ -118,6 +119,10 @@
}
public ObjectName getObjectName() {
- return ObjectName.valueOf(LogManager.LOGGING_MXBEAN_NAME);
+ try {
+ return ObjectName.getInstance(LogManager.LOGGING_MXBEAN_NAME);
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException(e);
+ }
}
}
--- a/jdk/src/share/classes/javax/management/AndQueryExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/AndQueryExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -104,26 +104,4 @@
public String toString() {
return "(" + exp1 + ") and (" + exp2 + ")";
}
-
- @Override
- String toQueryString() {
- // Parentheses are only added if needed to disambiguate.
- return parens(exp1) + " and " + parens(exp2);
- }
-
- // Add parens if needed to disambiguate an expression such as
- // Query.and(Query.or(a, b), c). We need to return
- // (a or b) and c
- // in such a case, because
- // a or b and c
- // would mean
- // a or (b and c)
- private static String parens(QueryExp exp) {
- String s = Query.toString(exp);
- if (exp instanceof OrQueryExp)
- return "(" + s + ")";
- else
- return s;
- }
-
}
--- a/jdk/src/share/classes/javax/management/AttributeList.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/AttributeList.java Wed Oct 21 16:50:44 2009 +0100
@@ -138,56 +138,6 @@
}
/**
- * <p>Constructs an {@code AttributeList} containing the elements of
- * the {@code Map} specified, in the order in which they appear in the
- * {@code Map}'s {@link Map#entrySet entrySet}. For each <em>{@code
- * key}</em> and <em>{@code value}</em> in the {@code Map}, the constructed
- * {@code AttributeList} will contain {@link Attribute#Attribute
- * Attribute(<em>key</em>, <em>value</em>)}.</p>
- *
- * @param map the {@code Map} defining the elements of the new
- * {@code AttributeList}.
- */
- public AttributeList(Map<String, ?> map) {
- for (Map.Entry<String, ?> entry : map.entrySet())
- add(new Attribute(entry.getKey(), entry.getValue()));
- typeSafe = true;
- }
-
- /**
- * <p>Return a {@code Map} that is a snapshot of the values in this
- * {@code AttributeList}. Each key in the {@code Map} is the {@linkplain
- * Attribute#getName() name} of an {@code Attribute} in the list, and each
- * value is the corresponding {@linkplain Attribute#getValue() value} of
- * that {@code Attribute}. The {@code AttributeList} and the {@code Map}
- * are unrelated after the call, that is, changes to one do not affect the
- * other.</p>
- *
- * <p>If the {@code AttributeList} contains more than one {@code Attribute}
- * with the same name, then the {@code Map} will contain an entry
- * for that name where the value is that of the last of those {@code
- * Attribute}s.</p>
- *
- * @return the new {@code Map}.
- *
- * @throws IllegalArgumentException if this {@code AttributeList} contains
- * an element that is not an {@code Attribute}.
- */
- public Map<String, Object> toMap() {
- Map<String, Object> map = new LinkedHashMap<String, Object>();
-
- // We can't call adding(this) because we're not necessarily typeSafe
- if (tainted)
- throw new IllegalArgumentException("AttributeList contains non-Attribute");
-
- for (Object x : this) {
- Attribute a = (Attribute) x;
- map.put(a.getName(), a.getValue());
- }
- return map;
- }
-
- /**
* Return a view of this list as a {@code List<Attribute>}.
* Changes to the returned value are reflected by changes
* to the original {@code AttributeList} and vice versa.
--- a/jdk/src/share/classes/javax/management/AttributeValueExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/AttributeValueExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -51,8 +51,6 @@
*/
private String attr;
- private transient int dotIndex;
-
/**
* An <code>AttributeValueExp</code> with a null attribute.
* @deprecated An instance created with this constructor cannot be
@@ -71,18 +69,6 @@
*/
public AttributeValueExp(String attr) {
this.attr = attr;
- setDotIndex();
- }
-
- private void setDotIndex() {
- if (attr != null)
- dotIndex = attr.indexOf('.');
- }
-
- private void readObject(ObjectInputStream in)
- throws ClassNotFoundException, IOException {
- in.defaultReadObject();
- setDotIndex();
}
/**
@@ -134,7 +120,7 @@
*/
@Override
public String toString() {
- return QueryParser.quoteId(attr);
+ return attr;
}
@@ -160,18 +146,6 @@
* If the attempt to access the attribute generates an exception,
* return null.</p>
*
- * <p>Let <em>n</em> be the {@linkplain #getAttributeName attribute
- * name}. Then this method proceeds as follows. First it calls
- * {@link MBeanServer#getAttribute getAttribute(name, <em>n</em>)}. If that
- * generates an {@link AttributeNotFoundException}, and if <em>n</em>
- * contains at least one dot ({@code .}), then the method calls {@code
- * getAttribute(name, }<em>n</em>{@code .substring(0, }<em>n</em>{@code
- * .indexOf('.')))}; in other words it calls {@code getAttribute}
- * with the substring of <em>n</em> before the first dot. Then it
- * extracts a component from the retrieved value, as described in the <a
- * href="monitor/package-summary.html#complex">documentation for the {@code
- * monitor} package</a>.</p>
- *
* <p>The MBean Server used is the one returned by {@link
* QueryEval#getMBeanServer()}.</p>
*
@@ -186,34 +160,9 @@
MBeanServer server = QueryEval.getMBeanServer();
- try {
return server.getAttribute(name, attr);
- } catch (AttributeNotFoundException e) {
- if (dotIndex < 0)
- throw e;
- }
-
- String toGet = attr.substring(0, dotIndex);
-
- Object value = server.getAttribute(name, toGet);
-
- return extractElement(value, attr.substring(dotIndex + 1));
} catch (Exception re) {
return null;
}
}
-
- private Object extractElement(Object value, String elementWithDots)
- throws AttributeNotFoundException {
- while (true) {
- int dot = elementWithDots.indexOf('.');
- String element = (dot < 0) ?
- elementWithDots : elementWithDots.substring(0, dot);
- value = Introspector.elementFromComplex(value, element);
- if (dot < 0)
- return value;
- elementWithDots = elementWithDots.substring(dot + 1);
- }
- }
-
}
--- a/jdk/src/share/classes/javax/management/BetweenQueryExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/BetweenQueryExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -139,9 +139,4 @@
public String toString() {
return "(" + exp1 + ") between (" + exp2 + ") and (" + exp3 + ")";
}
-
- @Override
- String toQueryString() {
- return exp1 + " between " + exp2 + " and " + exp3;
- }
}
--- a/jdk/src/share/classes/javax/management/BinaryOpValueExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/BinaryOpValueExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -253,7 +253,5 @@
@Deprecated
public void setMBeanServer(MBeanServer s) {
super.setMBeanServer(s);
+ }
}
-
-
- }
--- a/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -192,11 +192,6 @@
return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")";
}
- @Override
- String toQueryString() {
- return exp1 + " " + relOpString() + " " + exp2;
- }
-
private String relOpString() {
switch (relOp) {
case Query.GT:
--- a/jdk/src/share/classes/javax/management/ClientContext.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1091 +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 javax.management;
-
-import com.sun.jmx.interceptor.SingleMBeanForwarder;
-import com.sun.jmx.namespace.RoutingConnectionProxy;
-import com.sun.jmx.namespace.RoutingProxy;
-import com.sun.jmx.namespace.RoutingServerProxy;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaceMBean;
-import javax.management.namespace.MBeanServerSupport;
-import javax.management.remote.IdentityMBeanServerForwarder;
-import javax.management.remote.MBeanServerForwarder;
-
-/**
- * <p>Methods to communicate a client context to MBeans. A context is
- * a {@literal Map<String, String>} that is provided by the client and
- * that an MBean can consult using the {@link #getContext()} method.
- * The context is set on a per-thread basis and can be consulted by any
- * code that the target MBean calls within the thread.</p>
- *
- * <p>One common usage of client context is to communicate the client's
- * {@link Locale} to MBeans. For example, if an MBean has a String attribute
- * {@code LastProblemDescription}, the value of that attribute could be
- * a description of the last problem encountered by the MBean, translated
- * into the client's locale. Different clients accessing this attribute
- * from different locales would each see the appropriate version for their
- * locale.</p>
- *
- * <p>The locale case is sufficiently important that it has a special
- * shorthand, the {@link #getLocale()} method. This method calls
- * <code>{@link #getContext()}.get({@link #LOCALE_KEY})</code> and converts the
- * resultant String into a Locale object.</p>
- *
- * <p>Here is what an MBean with a localized {@code LastProblemDescription}
- * attribute might look like:</p>
- *
- * <pre>
- * public class LocaleSensitive implements LocaleSensitiveMBean {
- * ...
- * public String getLastProblemDescription() {
- * Locale loc = {@link #getLocale() ClientContext.getLocale()};
- * ResourceBundle rb = ResourceBundle.getBundle("MyResources", loc);
- * String resourceKey = getLastProblemResourceKey();
- * return rb.getString(resourceKey);
- * }
- * ...
- * }
- * </pre>
- *
- * <p>Here is how a client can communicate its locale to the target
- * MBean:</p>
- *
- * <pre>
- * JMXConnector connector = JMXConnectorFactory.connect(url);
- * MBeanServerConnection connection = connector.getMBeanServerConnection();
- * <b>MBeanServerConnection localizedConnection =
- * {@link #withLocale(MBeanServerConnection, Locale)
- * ClientContext.withLocale}(connection, Locale.getDefault());</b>
- * String problem = localizedConnection.getAttribute(
- * objectName, "LastProblemDescription");
- * </pre>
- *
- * <p>In the more general case where the client wants to communicate context
- * other than the locale, it can use {@link #withContext(MBeanServerConnection,
- * String, String) withContext} instead of {@code withLocale}, and the target
- * MBean can retrieve the context using {@link #getContext()}.</p>
- *
- *
- * <h3 id="remote-use">Remote use of contexts</h3>
- *
- * <p>The various {@code with*} methods, for example {@link
- * #withLocale(javax.management.MBeanServer, java.util.Locale) withLocale},
- * transmit the context of each request by encoding it in the ObjectName of
- * the request. For example, if a client creates a connection in the
- * French locale like this...</p>
- *
- * <pre>
- * MBeanServerConnection mbsc = ...;
- * Locale french = new Locale("fr");
- * MBeanServerConnection localizedConnection = ClientContext.withLocale(mbsc, french);
- * </pre>
- *
- * <p>...or, equivalently, like this...</p>
- *
- * <pre>
- * MBeanServerConnection localizedConnection =
- * ClientContext.withContext(mbsc, {@link #LOCALE_KEY "jmx.locale"}, "fr");
- * </pre>
- *
- * <p>...then the context associates {@code "jmx.locale"} with {@code "fr"}
- * and a request such as<br>
- * {@code localizedConnection.getAttribute("java.lang:type=Runtime", "Name")}<br>
- * is translated into<br>
- * {@code mbsc.getAttribute("jmx.context//jmx.locale=fr//java.lang:Runtime", "Name")}.<br>
- * A special {@linkplain javax.management.namespace namespace} {@code jmx.context//}
- * extracts the context from the string {@code jmx.locale=fr} and establishes
- * it in the thread that will do<br>
- * {@code getAttribute("java.lang:Runtime", "Name")}.</p>
- *
- * <p>The details of how contexts are encoded into ObjectNames are explained
- * in the {@link #encode encode} method.</p>
- *
- * <p>The namespace {@code jmx.context//} just mentioned is only needed by
- * remote clients, since local clients can set the context directly using
- * {@link #doWithContext doWithContext}. Accordingly, this namespace is not
- * present by default in the {@code MBeanServer}. Instead, it is
- * <em>simulated</em> by the standard RMI connector using a special
- * {@link MBeanServerForwarder}. If you are using this connector, you do not
- * need to do anything special. Other connectors may or may not simulate this
- * namespace in the same way. If the connector server returns true from the
- * method {@link
- * javax.management.remote.JMXConnectorServer#supportsSystemMBeanServerForwarder()
- * supportsSystemMBeanServerForwarder} then it does simulate the namespace.
- * If you are using another connector, or if you want to be able to use the
- * {@code with*} methods locally, then you can install the {@code
- * MBeanServerForwarder} yourself as described in the method {@link
- * #newContextForwarder newContextForwarder}.</p>
- */
-public class ClientContext {
- /**
- * <p>The context key for the client locale. The string associated with
- * this key is an encoded locale such as {@code en_US} which could be
- * returned by {@link Locale#toString()}.</p>
- */
- public static final String LOCALE_KEY = "jmx.locale";
-
- private static final Logger LOG =
- Logger.getLogger("javax.management.context");
-
- /**
- * <p>The namespace that implements contexts, {@value}.</p>
- */
- public static final String
- NAMESPACE = "jmx.context";
- private static final String NAMESPACE_PLUS_SEP =
- NAMESPACE + NAMESPACE_SEPARATOR;
- static final ObjectName CLIENT_CONTEXT_NAMESPACE_HANDLER =
- ObjectName.valueOf(NAMESPACE_PLUS_SEP + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- private static final ObjectName NAMESPACE_HANDLER_WITHOUT_NAMESPACE =
- ObjectName.valueOf(":" + JMXNamespace.TYPE_ASSIGNMENT);
-
- private static final ThreadLocal<Map<String, String>> contextThreadLocal =
- new InheritableThreadLocal<Map<String, String>>() {
- @Override
- protected Map<String, String> initialValue() {
- return Collections.emptyMap();
- }
- };
-
- /** There are no instances of this class. */
- private ClientContext() {
- }
-
- /**
- * <p>Get the client context associated with the current thread.
- *
- * @return the client context associated with the current thread.
- * This may be an empty Map, but it cannot be null. The returned
- * Map cannot be modified.
- */
- public static Map<String, String> getContext() {
- return Collections.unmodifiableMap(contextThreadLocal.get());
- }
-
- /**
- * <p>Get the client locale associated with the current thread.
- * If the client context includes the {@value #LOCALE_KEY} key
- * then the returned value is the Locale encoded in that key.
- * Otherwise the returned value is the {@linkplain Locale#getDefault()
- * default locale}.
- *
- * @return the client locale.
- */
- public static Locale getLocale() {
- String localeS = getContext().get(LOCALE_KEY);
- if (localeS == null)
- return Locale.getDefault();
- // Parse the locale string. Why isn't there a method in Locale for this?
- String language, country, variant;
- int ui = localeS.indexOf('_');
- if (ui < 0) {
- language = localeS;
- country = variant = "";
- } else {
- language = localeS.substring(0, ui);
- localeS = localeS.substring(ui + 1);
- ui = localeS.indexOf('_');
- if (ui < 0) {
- country = localeS;
- variant = "";
- } else {
- country = localeS.substring(0, ui);
- variant = localeS.substring(ui + 1);
- }
- }
- return new Locale(language, country, variant);
- }
-
- /**
- * <p>Execute the given {@code task} with the client context set to
- * the given Map. This Map will be the result of {@link #getContext()}
- * within the {@code task}.</p>
- *
- * <p>The {@code task} may include nested calls to {@code doWithContext}.
- * The value returned by {@link #getContext} at any point is the Map
- * provided to the most recent {@code doWithContext} (in the current thread)
- * that has not yet returned.</p>
- *
- * <p>The {@link #getContext()} method returns the same value immediately
- * after a call to this method as immediately before. In other words,
- * {@code doWithContext} only affects the context during the execution of
- * the {@code task}.</p>
- *
- * <p>As an example, suppose you want to get an attribute with whatever
- * context has already been set, plus the locale set to "fr". You could
- * write this:</p>
- *
- * <pre>
- * {@code Map<String, String>} context =
- * new {@code HashMap<String, String>}(ClientContext.getContext());
- * context.put(ClientContext.LOCALE_KEY, "fr");
- * String lastProblemDescription =
- * ClientContext.doWithContext(context, new {@code Callable<String>}() {
- * public String call() {
- * return (String) mbeanServer.getAttribute(mbean, "LastProblemDescription");
- * }
- * });
- * </pre>
- *
- * @param <T> the type of value that the task will return. This type
- * parameter is usually inferred from the type of the {@code task}
- * parameter. For example, if {@code task} is a {@code Callable<String>}
- * then {@code T} is {@code String}. If the task does not return a value,
- * use a {@code Callable<Void>} and return null from its
- * {@link Callable#call call} method.
- * @param context the context to use while executing {@code task}.
- * @param task the task to run with the {@code key}={@code value}
- * binding.
- * @return the result of {@link Callable#call() task.call()}.
- * @throws IllegalArgumentException if either parameter is null, or
- * if any key in {@code context} is null or empty, or if any value
- * in {@code context} is null.
- * @throws Exception If {@link Callable#call() task.call()} throws an
- * exception, {@code doWithContext} throws the same exception.
- */
- public static <T> T doWithContext(Map<String, String> context, Callable<T> task)
- throws Exception {
- if (context == null || task == null)
- throw new IllegalArgumentException("Null parameter");
- Map<String, String> contextCopy = new TreeMap<String, String>(context);
- validateContext(contextCopy);
- Map<String, String> oldContextMap = contextThreadLocal.get();
- try {
- contextThreadLocal.set(contextCopy);
- return task.call();
- } finally {
- contextThreadLocal.set(oldContextMap);
- }
- }
-
- private static void validateContext(Map<String, String> context) {
- for (Map.Entry<String, String> entry : context.entrySet()) {
- // If the user passes a raw Map rather than a Map<String, String>,
- // entries could contain objects other than Strings. If so,
- // we'll get a ClassCastException here.
- String key = entry.getKey();
- String value = entry.getValue();
- if (key == null || value == null)
- throw new IllegalArgumentException("Null key or value in context");
- if (key.equals(""))
- throw new IllegalArgumentException("Empty key in context");
- }
- }
-
- /**
- * <p>Return an MBeanServer object that is equivalent to the given
- * MBeanServer object except that operations on MBeans run with
- * the given Locale in their {@linkplain #getContext() thread context}.
- * Note that this will only work if the given MBeanServer supports
- * contexts, as described <a href="#remote-use">above</a>.</p>
- *
- * <p>This method is equivalent to {@link #withContext(MBeanServer,
- * String, String) withContext}<code>(mbs, {@value LOCALE_KEY},
- * locale.toString())</code>.</p>
- *
- * @throws IllegalArgumentException if either parameter is null, or if
- * {@code mbs} does not support contexts. In the second case only,
- * the cause of the {@code IllegalArgumentException} will be an {@link
- * InstanceNotFoundException}.
- */
- public static MBeanServer withLocale(MBeanServer mbs, Locale locale) {
- return withLocale(mbs, MBeanServer.class, locale);
- }
-
- /**
- * <p>Return an MBeanServerConnection object that is equivalent to the given
- * MBeanServerConnection object except that operations on MBeans run with
- * the given Locale in their {@linkplain #getContext() thread context}.
- * Note that this will only work if the given MBeanServerConnection supports
- * contexts, as described <a href="#remote-use">above</a>.</p>
- *
- * <p>This method is equivalent to {@link #withContext(MBeanServerConnection,
- * String, String) withContext}<code>(mbs, {@value LOCALE_KEY},
- * locale.toString())</code>.</p>
- *
- * @throws IllegalArgumentException if either parameter is null, or if
- * the communication with {@code mbsc} fails, or if {@code mbsc} does not
- * support contexts. If the communication with {@code mbsc} fails, the
- * {@linkplain Throwable#getCause() cause} of this exception will be an
- * {@code IOException}. If {@code mbsc} does not support contexts, the
- * cause will be an {@link InstanceNotFoundException}.
- */
- public static MBeanServerConnection withLocale(
- MBeanServerConnection mbsc, Locale locale) {
- return withLocale(mbsc, MBeanServerConnection.class, locale);
- }
-
- private static <T extends MBeanServerConnection> T withLocale(
- T mbsc, Class<T> mbscClass, Locale locale) {
- if (locale == null)
- throw new IllegalArgumentException("Null locale");
- return withContext(mbsc, mbscClass, LOCALE_KEY, locale.toString());
- }
-
- /**
- * <p>Return an MBeanServer object that is equivalent to the given
- * MBeanServer object except that operations on MBeans run with
- * the given key bound to the given value in their {@linkplain
- * #getContext() thread context}.
- * Note that this will only work if the given MBeanServer supports
- * contexts, as described <a href="#remote-use">above</a>.</p>
- *
- * @param mbs the original MBeanServer.
- * @param key the key to bind in the context of MBean operations
- * in the returned MBeanServer object.
- * @param value the value to bind to the key in the context of MBean
- * operations in the returned MBeanServer object.
- * @throws IllegalArgumentException if any parameter is null, or
- * if {@code key} is the empty string, or if {@code mbs} does not support
- * contexts. In the last case only, the cause of the {@code
- * IllegalArgumentException} will be an {@link InstanceNotFoundException}.
- */
- public static MBeanServer withContext(
- MBeanServer mbs, String key, String value) {
- return withContext(mbs, MBeanServer.class, key, value);
- }
-
- /**
- * <p>Return an MBeanServerConnection object that is equivalent to the given
- * MBeanServerConnection object except that operations on MBeans run with
- * the given key bound to the given value in their {@linkplain
- * #getContext() thread context}.
- * Note that this will only work if the given MBeanServerConnection supports
- * contexts, as described <a href="#remote-use">above</a>.</p>
- *
- * @param mbsc the original MBeanServerConnection.
- * @param key the key to bind in the context of MBean operations
- * in the returned MBeanServerConnection object.
- * @param value the value to bind to the key in the context of MBean
- * operations in the returned MBeanServerConnection object.
- * @throws IllegalArgumentException if any parameter is null, or
- * if {@code key} is the empty string, or if the communication with {@code
- * mbsc} fails, or if {@code mbsc} does not support contexts. If
- * the communication with {@code mbsc} fails, the {@linkplain
- * Throwable#getCause() cause} of this exception will be an {@code
- * IOException}. If {@code mbsc} does not support contexts, the cause will
- * be an {@link InstanceNotFoundException}.
- */
- public static MBeanServerConnection withContext(
- MBeanServerConnection mbsc, String key, String value) {
- return withContext(mbsc, MBeanServerConnection.class, key, value);
- }
-
-
- /**
- * <p>Returns an MBeanServerConnection object that is equivalent to the
- * given MBeanServerConnection object except that remote operations on
- * MBeans run with the context that has been established by the client
- * using {@link #doWithContext doWithContext}. Note that this will
- * only work if the remote system supports contexts, as described <a
- * href="#remote-use">above</a>.</p>
- *
- * <p>For example, suppose the remote system does support contexts, and you
- * have created a {@code JMXConnector} like this:</p>
- *
- * <pre>
- * JMXServiceURL url = ...;
- * JMXConnector client = JMXConnectorFactory.connect(url);
- * MBeanServerConnection mbsc = client.getMBeanServerConnection();
- * <b>mbsc = ClientContext.withDynamicContext(mbsc);</b>
- * </pre>
- *
- * <p>Then if you do this...</p>
- *
- * <pre>
- * MBeanInfo mbi = ClientContext.doWithContext(
- * Collections.singletonMap(ClientContext.LOCALE_KEY, "fr"),
- * new {@code Callable<MBeanInfo>}() {
- * public MBeanInfo call() {
- * return mbsc.getMBeanInfo(objectName);
- * }
- * });
- * </pre>
- *
- * <p>...then the context with the locale set to "fr" will be in place
- * when the {@code getMBeanInfo} is executed on the remote MBean Server.</p>
- *
- * @param mbsc the original MBeanServerConnection.
- *
- * @throws IllegalArgumentException if the {@code mbsc} parameter is null,
- * or if the communication with {@code mbsc} fails, or if {@code mbsc}
- * does not support contexts. If the communication with {@code mbsc}
- * fails, the {@linkplain Throwable#getCause() cause} of this exception
- * will be an {@code IOException}. If {@code mbsc} does not support
- * contexts, the cause will be an {@link InstanceNotFoundException}.
- */
- public static MBeanServerConnection withDynamicContext(
- MBeanServerConnection mbsc) {
- // Probe mbsc to get the right exception if it's incommunicado or
- // doesn't support namespaces.
- JMXNamespaces.narrowToNamespace(mbsc, NAMESPACE);
- return (MBeanServerConnection) Proxy.newProxyInstance(
- MBeanServerConnection.class.getClassLoader(),
- new Class<?>[] {MBeanServerConnection.class},
- new DynamicContextIH(mbsc));
- }
-
- private static class DynamicContextIH implements InvocationHandler {
- private final MBeanServerConnection mbsc;
-
- public DynamicContextIH(MBeanServerConnection mbsc) {
- this.mbsc = mbsc;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- MBeanServerConnection dynMBSC = withContext(
- mbsc, MBeanServerConnection.class, getContext(), false);
- try {
- return method.invoke(dynMBSC, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- }
-
- private static <T extends MBeanServerConnection> T withContext(
- T mbsc, Class<T> mbscClass, String key, String value) {
- return withContext(
- mbsc, mbscClass, Collections.singletonMap(key, value), true);
- }
-
- private static <T extends MBeanServerConnection> T withContext(
- T mbsc, Class<T> mbscClass, Map<String, String> context,
- boolean probe) {
- if (mbsc == null || context == null)
- throw new IllegalArgumentException("Null parameter");
- if (context.isEmpty())
- return mbsc;
- validateContext(context);
- Map<String, String> contextMap = null;
- if (mbsc.getClass() == RoutingServerProxy.class ||
- mbsc.getClass() == RoutingProxy.class) {
- RoutingProxy<?> nsp = (RoutingProxy<?>) mbsc;
- String where = nsp.getSourceNamespace();
- if (where.startsWith(NAMESPACE_PLUS_SEP)) {
- /* Try to merge the existing context namespace with the
- * new one. If it doesn't work, we fall back to just
- * prefixing jmx.context//key=value, which
- * might lead to a name like jmx.c//k1=v1//jmx.c//k2=v2//d:k=v.
- */
- String encodedContext =
- where.substring(NAMESPACE_PLUS_SEP.length());
- if (encodedContext.indexOf(NAMESPACE_SEPARATOR) < 0) {
- contextMap = stringToMapOrNull(encodedContext);
- if (contextMap != null) {
- contextMap.putAll(context);
- mbsc = mbscClass.cast(nsp.source());
- }
- }
- }
- }
- if (contextMap == null)
- contextMap = context;
- String contextDir = NAMESPACE_PLUS_SEP + mapToString(contextMap);
- if (mbscClass == MBeanServer.class) {
- return mbscClass.cast(RoutingServerProxy.cd(
- (MBeanServer) mbsc, contextDir, probe));
- } else if (mbscClass == MBeanServerConnection.class) {
- return mbscClass.cast(RoutingConnectionProxy.cd(
- mbsc, contextDir, probe));
- } else
- throw new AssertionError("Bad MBSC: " + mbscClass);
- }
-
- /**
- * <p>Returns an encoded context prefix for ObjectNames.
- * If the given context is empty, {@code ""} is returned.
- * Otherwise, this method returns a string of the form
- * {@code "jmx.context//key=value;key=value;..."}.
- * For example, if the context has keys {@code "jmx.locale"}
- * and {@code "xid"} with respective values {@code "fr"}
- * and {@code "1234"}, this method will return
- * {@code "jmx.context//jmx.locale=fr;xid=1234"} or
- * {@code "jmx.context//xid=1234;jmx.locale=fr"}.</p>
- *
- * <p>Each key and each value in the encoded string is subject to
- * encoding as if by the method {@link URLEncoder#encode(String, String)}
- * with a character encoding of {@code "UTF-8"}, but with the additional
- * encoding of any {@code *} character as {@code "%2A"}. This ensures
- * that keys and values can contain any character. Without encoding,
- * characters such as {@code =} and {@code :} would pose problems.</p>
- *
- * @param context the context to encode.
- *
- * @return the context in encoded form.
- *
- * @throws IllegalArgumentException if the {@code context} parameter
- * is null or if it contains a null key or value.
- **/
- public static String encode(Map<String, String> context) {
- if (context == null)
- throw new IllegalArgumentException("Null context");
- if (context.isEmpty())
- return "";
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<String, String> entry : context.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- if (key == null || value == null)
- throw new IllegalArgumentException("Null key or value");
- if (sb.length() > 0)
- sb.append(";");
- sb.append(encode(key)).append("=").append(encode(value));
- }
- sb.insert(0, NAMESPACE_PLUS_SEP);
- return sb.toString();
- }
-
- /**
- * <p>Create a new {@link MBeanServerForwarder} that applies the context
- * received from a client to the current thread. A client using
- * one of the various {@code with*} methods (for example {@link
- * #withContext(MBeanServerConnection, String, String) withContext}) will
- * encode that context into the {@code ObjectName} of each
- * {@code MBeanServer} request. The object returned by this method
- * decodes the context from that {@code ObjectName} and applies it
- * as described for {@link #doWithContext doWithContext} while performing
- * the {@code MBeanServer} request using the {@code ObjectName} without
- * the encoded context.</p>
- *
- * <p>This forwarder can be used in a number of ways:</p>
- *
- * <ul>
- * <li>
- * <p>To add context decoding to a local {@code MBeanServer}, you can
- * write:</p>
- * <pre>
- * MBeanServer mbs = {@link
- * java.lang.management.ManagementFactory#getPlatformMBeanServer()
- * ManagementFactory.getPlatformMBeanServer()}; // for example
- * mbs = ClientContext.newContextForwarder(mbs, null);
- * </pre>
- *
- * <li>
- * <p>To add context decoding to a {@linkplain
- * javax.management.remote.JMXConnectorServer connector server}:</p>
- * <pre>
- * JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(...);
- * MBeanServer nextMBS = cs.getMBeanServer();
- * MBeanServerForwarder mbsf = ClientContext.newContextForwarder(nextMBS, null);
- * cs.{@link
- * javax.management.remote.JMXConnectorServer#setMBeanServerForwarder
- * setMBeanServerForwarder}(mbsf);
- * </pre>
- *
- * <li>
- * <p>For connectors, such as the standard RMI connector, that support
- * a {@linkplain
- * javax.management.remote.JMXConnectorServer#getSystemMBeanServerForwarder
- * system chain} of {@code MBeanServerForwarder}s, this forwarder will
- * be installed in that chain by default. See
- * {@link javax.management.remote.JMXConnectorServer#CONTEXT_FORWARDER
- * JMXConnectorServer.CONTEXT_FORWARDER}.
- * </p>
- *
- * </ul>
- *
- * @param nextMBS the next {@code MBeanServer} in the chain of
- * forwarders, which might be another {@code MBeanServerForwarder} or
- * a plain {@code MBeanServer}. This is the object to which {@code
- * MBeanServer} requests that do not include a context are sent. It
- * will be the value of {@link MBeanServerForwarder#getMBeanServer()
- * getMBeanServer()} on the returned object, and can be changed with {@link
- * MBeanServerForwarder#setMBeanServer setMBeanServer}. It can be null but
- * must be set to a non-null value before any {@code MBeanServer} requests
- * arrive.
- *
- * @param loopMBS the {@code MBeanServer} to which requests that contain
- * an encoded context should be sent once the context has been decoded.
- * For example, if the request is {@link MBeanServer#getAttribute
- * getAttribute}{@code ("jmx.context//jmx.locale=fr//java.lang:type=Runtime",
- * "Name")}, then the {@linkplain #getContext() context} of the thread
- * executing that request will have {@code "jmx.locale"} set to {@code "fr"}
- * while executing {@code loopMBS.getAttribute("java.lang:type=Runtime",
- * "Name")}. If this parameter is null, then these requests will be
- * sent to the newly-created {@code MBeanServerForwarder}. Usually
- * the parameter will either be null or will be the result of {@link
- * javax.management.remote.JMXConnectorServer#getSystemMBeanServerForwarder
- * getSystemMBeanServerForwarder()} for the connector server in which
- * this forwarder will be installed.
- *
- * @return a new {@code MBeanServerForwarder} that decodes client context
- * from {@code ObjectName}s.
- */
- /*
- * What we're building here is confusing enough to need a diagram.
- * The MBSF that we return is actually the composition of two forwarders:
- * the first one simulates the existence of the MBean
- * jmx.context//:type=JMXNamespace, and the second one simulates the
- * existence of the namespace jmx.context//. Furthermore, that namespace
- * loops back to the composed forwarder, so that something like
- * jmx.context//foo=bar//jmxcontext//baz=buh will work. And the loopback
- * goes through yet another forwarder, which simulates the existence of
- * (e.g.) jmx.context//foo=bar//:type=JMXNamespace, which is needed
- * notably so that narrowToNamespace will work.
- *
- * | +--------------------------------------------------+
- * v v |
- * +----------------+ |
- * | Handler MBSF |->accesses to jmx.context//:type=JMXNamespace |
- * +----------------+ (handled completely here) +-------------------+
- * | | 2nd Handler MBSF |
- * v +-------------------+
- * +----------------+ ^
- * | Namespace MBSF |->accesses to jmx.context//**-------------------+
- * +----------------+ (after attaching context to thread)
- * |
- * v accesses to anything else
- *
- * And finally, we need to ensure that from the outside the composed object
- * looks like a single forwarder, so that its get/setMBeanServer methods
- * will do the expected thing. That's what the anonymous subclass is for.
- */
- public static MBeanServerForwarder newContextForwarder(
- MBeanServer nextMBS, MBeanServer loopMBS) {
- final MBeanServerForwarder mbsWrapper =
- new IdentityMBeanServerForwarder(nextMBS);
- DynamicMBean handlerMBean = new StandardMBean(
- new JMXNamespace(mbsWrapper), JMXNamespaceMBean.class, false);
- SingleMBeanForwarder handlerForwarder = new SingleMBeanForwarder(
- CLIENT_CONTEXT_NAMESPACE_HANDLER, handlerMBean, true) {
- @Override
- public MBeanServer getMBeanServer() {
- return ((MBeanServerForwarder) super.getMBeanServer()).getMBeanServer();
- }
-
- @Override
- public void setMBeanServer(MBeanServer mbs1) {
- MBeanServerForwarder mbsf1 = (MBeanServerForwarder)
- super.getMBeanServer();
- if (mbsf1 != null)
- mbsf1.setMBeanServer(mbs1);
- else
- super.setMBeanServer(mbs1);
- mbsWrapper.setMBeanServer(mbs1);
- }
- };
- if (loopMBS == null)
- loopMBS = handlerForwarder;
- ContextInvocationHandler contextIH =
- new ContextInvocationHandler(nextMBS, loopMBS);
- MBeanServerForwarder contextForwarder = newForwarderProxy(contextIH);
- handlerForwarder.setMBeanServer(contextForwarder);
- return handlerForwarder;
- }
-
- /**
- * <p>Create a new {@link MBeanServerForwarder} that localizes
- * descriptions in {@code MBeanInfo} instances returned by
- * {@link MBeanServer#getMBeanInfo getMBeanInfo}. The {@code
- * MBeanServerForwarder} returned by this method passes all {@code
- * MBeanServer} methods through unchanged to the supplied object, {@code
- * mbs}, with the exception of {@code getMBeanInfo}. To handle {@code
- * getMBeanInfo(objectName)}, it calls {@code mbs.getMBeanInfo(objectName)}
- * to get an {@code MBeanInfo}, {@code mbi}; it calls {@link
- * MBeanServer#getClassLoaderFor mbs.getClassLoaderFor(objectName)} to
- * get a {@code ClassLoader}, {@code cl}; and it calls {@link
- * #getLocale} to get a {@code Locale}, {@code locale}. The order
- * of these three calls is not specified. Then the result is {@code
- * mbi.localizeDescriptions(locale, loader)}.</p>
- *
- * <p>This forwarder can be used in a number of ways:</p>
- *
- * <ul>
- * <li>
- * <p>To add description localization to a local {@code MBeanServer}, you
- * can write:</p>
- *
- * <pre>
- * MBeanServer mbs = {@link
- * java.lang.management.ManagementFactory#getPlatformMBeanServer()
- * ManagementFactory.getPlatformMBeanServer()}; // for example
- * mbs = ClientContext.newLocalizeMBeanInfoForwarder(mbs);
- * </pre>
- *
- * <li>
- * <p>To add description localization to a {@linkplain
- * javax.management.remote.JMXConnectorServer connector server}, you will
- * need to add both a {@linkplain #newContextForwarder context forwarder}
- * and a localization forwarder, for example like this:</p>
- *
- * <pre>
- * JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(...);
- * MBeanServer nextMBS = cs.getMBeanServer();
- * MBeanServerForwarder localizeMBSF =
- * ClientContext.newLocalizeMBeanInfoForwarder(nextMBS);
- * MBeanServerForwarder contextMBSF =
- * ClientContext.newContextForwarder(localizeMBSF, null);
- * cs.{@link
- * javax.management.remote.JMXConnectorServer#setMBeanServerForwarder
- * setMBeanServerForwarder}(contextMBSF);
- * </pre>
- *
- * <p>Notice that the context forwarder must run before the localization
- * forwarder, so that the locale is correctly established when the latter
- * runs. So the {@code nextMBS} parameter of the context forwarder must
- * be the localization forwarder, and not vice versa.</p>
- *
- * <li>
- * <p>For connectors, such as the standard RMI connector, that support
- * a {@linkplain
- * javax.management.remote.JMXConnectorServer#getSystemMBeanServerForwarder
- * system chain} of {@code MBeanServerForwarder}s, the context forwarder and
- * the localization forwarder will be installed in that chain, in the right
- * order, if you include
- * {@link
- * javax.management.remote.JMXConnectorServer#LOCALIZE_MBEAN_INFO_FORWARDER
- * LOCALIZE_MBEAN_INFO_FORWARDER} in the environment {@code Map} with
- * the value {@code "true"}, for example like this:</p>
- * </p>
- * <pre>
- * MBeanServer mbs = ...;
- * JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://...");
- * {@code Map<String, Object>} env = new {@code HashMap<String, Object>}();
- * env.put(JMXConnectorServer.LOCALIZE_MBEAN_INFO_FORWARDER, "true");
- * JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
- * url, env, mbs);
- * </pre>
- *
- * </ul>
- *
- * @param mbs the next {@code MBeanServer} in the chain of
- * forwarders, which might be another {@code MBeanServerForwarder}
- * or a plain {@code MBeanServer}. It will be the value of
- * {@link MBeanServerForwarder#getMBeanServer() getMBeanServer()}
- * on the returned object, and can be changed with {@link
- * MBeanServerForwarder#setMBeanServer setMBeanServer}. It can be null but
- * must be set to a non-null value before any {@code MBeanServer} requests
- * arrive.
- *
- * @return a new {@code MBeanServerForwarder} that localizes descriptions
- * in the result of {@code getMBeanInfo}.
- */
- public static MBeanServerForwarder newLocalizeMBeanInfoForwarder(
- MBeanServer mbs) {
- return new IdentityMBeanServerForwarder(mbs) {
- @Override
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, IntrospectionException,
- ReflectionException {
- MBeanInfo mbi = super.getMBeanInfo(name);
- Locale locale = getLocale();
- ClassLoader loader = getClassLoaderFor(name);
- return mbi.localizeDescriptions(locale, loader);
- }
- };
- }
-
- private static MBeanServerForwarder newForwarderProxy(InvocationHandler ih) {
- return (MBeanServerForwarder) Proxy.newProxyInstance(
- MBeanServerForwarder.class.getClassLoader(),
- new Class<?>[] {MBeanServerForwarder.class},
- ih);
- }
-
- // A proxy connection that will strip the 'contextDir' at input (routing),
- // and put it back at output (createMBean / registerMBean / query* /
- // getObjectInstance). Usually RoutingProxy / RoutingServerProxy are used
- // the other way round (they are used for 'cd' - where they need to add
- // something at input and remove it at output).
- // For 'cd' operations we create RoutingProxys with a non empty sourceDir,
- // and a possibly non-empty targetDir. This is the only case where we use
- // RoutingProxies with an empty sourceDir (sourceDir is what we add at input
- // and remove at output, targetDir is what we remove at input and add at
- // output.
- //
- // Note that using a transient ContextRoutingConnection
- // is possible only because RoutingProxys don't rewrite
- // notifications sources - otherwise we would have to
- // keep the ContextRoutingConnection - just to preserve
- // the 'wrapping listeners'
- //
- private static final class ContextRoutingConnection
- extends RoutingServerProxy {
- public ContextRoutingConnection(MBeanServer source,
- String contextDir) {
- super(source, "", contextDir, false);
- }
-
- // Not really needed - but this is safer and more optimized.
- // See RoutingProxy for more details.
- //
- @Override
- public Integer getMBeanCount() {
- return source().getMBeanCount();
- }
-
- // Not really needed - but this is safer and more optimized.
- // See RoutingProxy for more details.
- //
- @Override
- public String[] getDomains() {
- return source().getDomains();
- }
-
- // Not really needed - but this is safer and more optimized.
- // See RoutingProxy for more details.
- //
- @Override
- public String getDefaultDomain() {
- return source().getDefaultDomain();
- }
-
- }
-
- private static class ContextInvocationHandler implements InvocationHandler {
- /*
- * MBeanServer requests that don't include jmx.context//foo=bar//
- * are forwarded to forwardMBS, which is the unadorned MBeanServer
- * that knows nothing about the context namespace.
- * MBeanServer requests that do include this prefix will
- * usually (depending on the value of the loopMBS parameter to
- * newContextForwarder) loop back to the combined MBeanServerForwarder
- * that first implements
- * jmx.context//:type=JMXNamespace and then implements
- * jmx.context//foo=bar//. The reason is that it is valid
- * to have jmx.context//foo=bar//jmx.context//baz=buh//, although
- * usually that will be combined into jmx.context//foo=bar;baz=buh//.
- *
- * Before forwarding to loopMBS, we must check for :type=JMXNamespace
- * so that jmx.context//foo=bar//:type=JMXNamespace will exist. Its
- * existence is partial because it must remain "invisible": it should
- * not show up in queryNames or getMBeanCount even though it does
- * accept getAttribute and isRegistered and all other methods that
- * reference a single MBean.
- */
- private MBeanServer forwardMBS;
- private final MBeanServer loopMBS;
- private static final MBeanServer emptyMBS = new MBeanServerSupport() {
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- throw new InstanceNotFoundException(name.toString());
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return Collections.emptySet();
- }
- };
-
- ContextInvocationHandler(MBeanServer forwardMBS, MBeanServer loopMBS) {
- this.forwardMBS = forwardMBS;
- DynamicMBean handlerMBean = new StandardMBean(
- new JMXNamespace(loopMBS), JMXNamespaceMBean.class, false);
- MBeanServerForwarder handlerMBS = new SingleMBeanForwarder(
- NAMESPACE_HANDLER_WITHOUT_NAMESPACE, handlerMBean, false);
- handlerMBS.setMBeanServer(loopMBS);
- this.loopMBS = handlerMBS;
- }
-
- public Object invoke(Object proxy, final Method method, final Object[] args)
- throws Throwable {
- String methodName = method.getName();
- Class<?>[] paramTypes = method.getParameterTypes();
-
- // If this is a method from MBeanServerForwarder, handle it here.
- // There are only two such methods: getMBeanServer() and
- // setMBeanServer(mbs).
- if (methodName.equals("getMBeanServer"))
- return forwardMBS;
- else if (methodName.equals("setMBeanServer")) {
- this.forwardMBS = (MBeanServer) args[0];
- return null;
- }
-
- // It is a method from MBeanServer.
- // Find the first parameter whose declared type is ObjectName,
- // and see if it is in the context namespace. If so we need to
- // trigger the logic for that namespace. If not, we simply
- // forward to the next MBeanServer in the chain. This logic
- // depends on the fact that if a method in the MBeanServer interface
- // has a "routing" ObjectName parameter, it is always the first
- // parameter of that type. Conversely, if a method has an
- // ObjectName parameter, then it makes sense to "route" that
- // method. Except for deserialize and instantiate, but if we
- // recognize a context namespace in those methods' ObjectName
- // parameters it is pretty harmless.
- int objectNameI = -1;
- for (int i = 0; i < paramTypes.length; i++) {
- if (paramTypes[i] == ObjectName.class) {
- objectNameI = i;
- break;
- }
- }
-
- if (objectNameI < 0)
- return invoke(method, forwardMBS, args);
-
- ObjectName target = (ObjectName) args[objectNameI];
- if (target == null ||
- !target.getDomain().startsWith(NAMESPACE_PLUS_SEP))
- return invoke(method, forwardMBS, args);
-
- String domain = target.getDomain().substring(NAMESPACE_PLUS_SEP.length());
-
- // The method routes through the (simulated) context namespace.
- // Decode the context after it, e.g. jmx.context//jmx.locale=fr//...
- // If there is no context part, we can throw an exception,
- // because a forwarder has already handled the unique MBean
- // jmx.context//:type=JMXNamespace.
- int sep = domain.indexOf(NAMESPACE_SEPARATOR);
- if (sep < 0)
- return invoke(method, emptyMBS, args); // throw exception
- final String encodedContext = domain.substring(0, sep);
-
- if (method.getName().startsWith("query") &&
- (encodedContext.contains("*") || encodedContext.contains("?"))) {
- // Queries like jmx.context//*//d:k=v return
- // an empty set, consistent with "real" namespaces.
- return Collections.EMPTY_SET;
- }
-
- Map<String, String> ctx = new TreeMap<String, String>(getContext());
- ctx.putAll(stringToMap(encodedContext));
-
- return doWithContext(ctx, new Callable<Object>() {
- public Object call() throws Exception {
- // Create a proxy connection that will strip
- // "jmx.context//" + encodedContext + "//" on input,
- // and put it back on output.
- //
- // Note that using a transient ContextRoutingConnection
- // is possible only because it doesn't rewrite
- // notification sources - otherwise we would have to
- // keep the ContextRoutingConnection - just to preserve
- // the 'wrapping listeners'
- //
- String namespace = NAMESPACE_PLUS_SEP + encodedContext;
- final ContextRoutingConnection route =
- new ContextRoutingConnection(loopMBS, namespace);
-
- if (LOG.isLoggable(Level.FINE))
- LOG.fine("context="+encodedContext);
- if (LOG.isLoggable(Level.FINER))
- LOG.finer(method.getName()+""+
- ((args==null)?"()":(""+Arrays.asList(args))));
-
- return invoke(method, route, args);
- }
- });
- }
-
- private static Object invoke(Method method, Object target, Object[] args)
- throws Exception {
- try {
- return method.invoke(target, args);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof Error)
- throw (Error) cause;
- throw (Exception) cause;
- }
- }
- }
-
- private static String mapToString(Map<String, String> map) {
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<String, String> entry : map.entrySet()) {
- String key = encode(entry.getKey());
- String value = encode(entry.getValue());
- if (sb.length() > 0)
- sb.append(";");
- sb.append(key).append("=").append(value);
- }
- return sb.toString();
- }
-
- private static Map<String, String> stringToMap(String encodedContext) {
- Map<String, String> map = stringToMapOrNull(encodedContext);
- if (map == null) {
- throw new IllegalArgumentException(
- "Invalid encoded context: " + encodedContext);
- }
- return map;
- }
-
- private static Map<String, String> stringToMapOrNull(String encodedContext) {
- Map<String, String> map = new LinkedHashMap<String, String>();
- StringTokenizer stok = new StringTokenizer(encodedContext, ";");
- while (stok.hasMoreTokens()) {
- String tok = stok.nextToken();
- int eq = tok.indexOf('=');
- if (eq < 0)
- return null;
- String key = decode(tok.substring(0, eq));
- if (key.equals(""))
- return null;
- String value = decode(tok.substring(eq + 1));
- map.put(key, value);
- }
- return map;
- }
-
- private static String encode(String s) {
- try {
- s = URLEncoder.encode(s, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e); // Should not happen
- }
- return s.replace("*", "%2A");
- // The * character is left intact in URL encodings, but for us it
- // is special (an ObjectName wildcard) so we must map it.
- // We are assuming that URLDecoder will decode it the same way as any
- // other hex escape.
- }
-
- private static String decode(String s) {
- try {
- return URLDecoder.decode(s, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
-}
--- a/jdk/src/share/classes/javax/management/Description.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.ResourceBundle;
-
-/**
- * <p>The textual description of an MBean or part of an MBean. This
- * description is intended to be displayed to users to help them
- * understand what the MBean does. Ultimately it will be the value of
- * the {@code getDescription()} method of an {@link MBeanInfo}, {@link
- * MBeanAttributeInfo}, or similar.</p>
- *
- * <p>This annotation applies to Standard MBean interfaces and to
- * MXBean interfaces, as well as to MBean classes defined using the
- * {@link MBean @MBean} or {@link MXBean @MXBean} annotations. For
- * example, a Standard MBean might be defined like this:</p>
- *
- * <pre>
- * <b>{@code @Description}</b>("Application configuration")
- * public interface ConfigurationMBean {
- * <b>{@code @Description}</b>("Cache size in bytes")
- * public int getCacheSize();
- * public void setCacheSize(int size);
- *
- * <b>{@code @Description}</b>("Last time the configuration was changed, " +
- * "in milliseconds since 1 Jan 1970")
- * public long getLastChangedTime();
- *
- * <b>{@code @Description}</b>("Save the configuration to a file")
- * public void save(
- * <b>{@code @Description}</b>("Optional name of the file, or null for the default name")
- * String fileName);
- * }
- * </pre>
- *
- * <p>The {@code MBeanInfo} for this MBean will have a {@link
- * MBeanInfo#getDescription() getDescription()} that is {@code
- * "Application configuration"}. It will contain an {@code
- * MBeanAttributeInfo} for the {@code CacheSize} attribute that is
- * defined by the methods {@code getCacheSize} and {@code
- * setCacheSize}, and another {@code MBeanAttributeInfo} for {@code
- * LastChangedTime}. The {@link MBeanAttributeInfo#getDescription()
- * getDescription()} for {@code CacheSize} will be {@code "Cache size
- * in bytes"}. Notice that there is no need to add a
- * {@code @Description} to both {@code getCacheSize} and {@code
- * setCacheSize} - either alone will do. But if you do add a
- * {@code @Description} to both, it must be the same.</p>
- *
- * <p>The {@code MBeanInfo} will also contain an {@link
- * MBeanOperationInfo} where {@link
- * MBeanOperationInfo#getDescription() getDescription()} is {@code
- * "Save the configuration to a file"}. This {@code
- * MBeanOperationInfo} will contain an {@link MBeanParameterInfo}
- * where {@link MBeanParameterInfo#getDescription() getDescription()}
- * is {@code "Optional name of the file, or null for the default
- * name"}.</p>
- *
- * <p>The {@code @Description} annotation can also be applied to the
- * public constructors of the implementation class. Continuing the
- * above example, the {@code Configuration} class implementing {@code
- * ConfigurationMBean} might look like this:</p>
- *
- * <pre>
- * public class Configuration implements ConfigurationMBean {
- * <b>{@code @Description}</b>("A Configuration MBean with the default file name")
- * public Configuration() {
- * this(DEFAULT_FILE_NAME);
- * }
- *
- * <b>{@code @Description}</b>("A Configuration MBean with a specified file name")
- * public Configuration(
- * <b>{@code @Description}</b>("Name of the file the configuration is stored in")
- * String fileName) {...}
- * ...
- * }
- * </pre>
- *
- * <p>The {@code @Description} annotation also works in MBeans that
- * are defined using the {@code @MBean} or {@code @MXBean} annotation
- * on classes. Here is an alternative implementation of {@code
- * Configuration} that does not use an {@code ConfigurationMBean}
- * interface.</p>
- *
- * <pre>
- * <b>{@code @MBean}</b>
- * <b>{@code @Description}</b>("Application configuration")
- * public class Configuration {
- * <b>{@code @Description}</b>("A Configuration MBean with the default file name")
- * public Configuration() {
- * this(DEFAULT_FILE_NAME);
- * }
- *
- * <b>{@code @Description}</b>("A Configuration MBean with a specified file name")
- * public Configuration(
- * <b>{@code @Description}</b>("Name of the file the configuration is stored in")
- * String fileName) {...}
- *
- * <b>{@code @ManagedAttribute}</b>
- * <b>{@code @Description}</b>("Cache size in bytes")
- * public int getCacheSize() {...}
- * <b>{@code @ManagedAttribute}</b>
- * public void setCacheSize(int size) {...}
- *
- * <b>{@code @ManagedOperation}</b>
- * <b>{@code @Description}</b>("Last time the configuration was changed, " +
- * "in milliseconds since 1 Jan 1970")
- * public long getLastChangedTime() {...}
- *
- * <b>{@code @ManagedOperation}</b>
- * <b>{@code @Description}</b>("Save the configuration to a file")
- * public void save(
- * <b>{@code @Description}</b>("Optional name of the file, or null for the default name")
- * String fileName) {...}
- * ...
- * }
- * </pre>
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
- ElementType.TYPE})
-public @interface Description {
- /**
- * <p>The description.</p>
- */
- String value();
-
- /**
- * <p>The base name for the {@link ResourceBundle} in which the key given in
- * the {@code descriptionResourceKey} field can be found, for example
- * {@code "com.example.myapp.MBeanResources"}. If a non-default value
- * is supplied for this element, it will appear in the
- * <a href="Descriptor.html#descriptionResourceBundleBaseName"><!--
- * -->{@code Descriptor}</a> for the annotated item.</p>
- */
- @DescriptorKey(
- value = "descriptionResourceBundleBaseName", omitIfDefault = true)
- String bundleBaseName() default "";
-
- /**
- * <p>A resource key for the description of this element. In
- * conjunction with the {@link #bundleBaseName bundleBaseName},
- * this can be used to find a localized version of the description.
- * If a non-default value
- * is supplied for this element, it will appear in the
- * <a href="Descriptor.html#descriptionResourceKey"><!--
- * -->{@code Descriptor}</a> for the annotated item.</p>
- */
- @DescriptorKey(value = "descriptionResourceKey", omitIfDefault = true)
- String key() default "";
-}
--- a/jdk/src/share/classes/javax/management/Descriptor.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/Descriptor.java Wed Oct 21 16:50:44 2009 +0100
@@ -38,7 +38,6 @@
import java.util.Locale;
import java.util.ResourceBundle;
import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.MXBeanMappingFactory;
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
import javax.management.openmbean.OpenMBeanOperationInfoSupport;
import javax.management.openmbean.OpenMBeanParameterInfoSupport;
@@ -118,22 +117,23 @@
* deprecation, for example {@code "1.3 Replaced by the Capacity
* attribute"}.</td>
*
- * <tr><td id="descriptionResourceBundleBaseName"><i>descriptionResource<br>
- * BundleBaseName</i></td><td>String</td><td>Any</td>
+ * <tr><td id="descriptionResourceBundleBaseName">descriptionResource<br>
+ * BundleBaseName</td><td>String</td><td>Any</td>
*
* <td>The base name for the {@link ResourceBundle} in which the key given in
* the {@code descriptionResourceKey} field can be found, for example
- * {@code "com.example.myapp.MBeanResources"}. See
- * {@link MBeanInfo#localizeDescriptions MBeanInfo.localizeDescriptions}.</td>
+ * {@code "com.example.myapp.MBeanResources"}. The meaning of this
+ * field is defined by this specification but the field is not set or
+ * used by the JMX API itself.</td>
*
- * <tr><td id="descriptionResourceKey"><i>descriptionResourceKey</i></td>
+ * <tr><td id="descriptionResourceKey">descriptionResourceKey</td>
* <td>String</td><td>Any</td>
*
* <td>A resource key for the description of this element. In
* conjunction with the {@code descriptionResourceBundleBaseName},
* this can be used to find a localized version of the description.
- * See {@link MBeanInfo#localizeDescriptions MBeanInfo.localizeDescriptions}.
- * </td>
+ * The meaning of this field is defined by this specification but the
+ * field is not set or used by the JMX API itself.</td>
*
* <tr><td>enabled</td><td>String</td>
* <td>MBeanAttributeInfo<br>MBeanNotificationInfo<br>MBeanOperationInfo</td>
@@ -147,31 +147,16 @@
* might be disabled if it cannot currently be emitted but could be in
* other circumstances.</td>
*
- * <tr id="exceptions"><td><i>exceptions</i><td>String[]</td>
+ * <tr id="exceptions"><td>exceptions<td>String[]</td>
* <td>MBeanAttributeInfo, MBeanConstructorInfo, MBeanOperationInfo</td>
*
* <td>The class names of the exceptions that can be thrown when invoking a
- * constructor or operation, or getting an attribute. Exceptions thrown when
+ * constructor or operation, or getting an attribute. The meaning of this field
+ * is defined by this specification but the field is not set or used by the
+ * JMX API itself. Exceptions thrown when
* setting an attribute are specified by the field
* <a href="#setExceptions">{@code setExceptions}</a>.
*
- * <tr id="exceptionErrorCodes"><td>exceptionErrorCodes</td><td>String[]</td>
- * <td>MBeanAttributeInfo<br>MBeanConstructorInfo<br>MBeanOperationInfo</td>
- *
- * <td>The {@linkplain GenericMBeanException#getErrorCode() error codes}
- * that can appear in a {@link GenericMBeanException} thrown when getting
- * this attribute or invoking this operation or constructor. See also
- * <a href="#setExceptionErrorCodes">{@code setExceptionErrorCodes}</a>.
- *
- * <tr id="exceptionUserDataTypes"><td>exceptionUserDataTypes</td>
- * <td>{@link javax.management.openmbean.CompositeType}[]</td>
- * <td>MBeanAttributeInfo<br>MBeanConstructorInfo<br>MBeanOperationInfo</td>
- *
- * <td>The types of {@linkplain GenericMBeanException#getUserData() userData}
- * that can appear in a {@link GenericMBeanException} thrown when getting
- * this attribute or invoking this operation or constructor. See also
- * <a href="#setExceptionUserDataTypes">{@code setExceptionUserDataTypes}</a>.
- *
* <tr id="immutableInfo"><td><i>immutableInfo</i><td>String</td>
* <td>MBeanInfo</td>
*
@@ -213,7 +198,7 @@
* <td>Legal values for an attribute or parameter. See
* {@link javax.management.openmbean}.</td>
*
- * <tr id="locale"><td><i>locale</i></td>
+ * <tr id="locale"><td>locale</td>
* <td>String</td><td>Any</td>
*
* <td>The {@linkplain Locale locale} of the description in this
@@ -254,21 +239,6 @@
* StandardMBean} class will have this field in its MBeanInfo
* Descriptor.</td>
*
- * <tr><td id="mxbeanMappingFactoryClass"><i>mxbeanMappingFactoryClass</i>
- * </td><td>String</td>
- * <td>MBeanInfo</td>
- *
- * <td>The name of the {@link MXBeanMappingFactory} class that was used for this
- * MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default}
- * one.</td>
- *
- * <tr><td id="objectNameTemplate"><i>objectNameTemplate</i>
- * </td><td>String</td>
- * <td>MBeanInfo</td>
- *
- * <td>The template to use to name this MBean. Its value must be compliant with
- * the specification of the {@link ObjectNameTemplate} annotation.</td>
- *
* <tr id="openType"><td><i>openType</i><td>{@link OpenType}</td>
* <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
*
@@ -306,26 +276,11 @@
* <td>MBeanAttributeInfo</td>
*
* <td>The class names of the exceptions that can be thrown when setting
- * an attribute. Exceptions thrown when getting an attribute are specified
+ * an attribute. The meaning of this field
+ * is defined by this specification but the field is not set or used by the
+ * JMX API itself. Exceptions thrown when getting an attribute are specified
* by the field <a href="#exceptions">{@code exceptions}</a>.
*
- * <tr id="setExceptionErrorCodes"><td>setExceptionErrorCodes</td>
- * <td>String[]</td><td>MBeanAttributeInfo</td>
- *
- * <td>The {@linkplain GenericMBeanException#getErrorCode() error codes}
- * that can appear in a {@link GenericMBeanException} thrown when setting
- * this attribute. See also
- * <a href="#exceptionErrorCodes">{@code exceptionErrorCodes}</a>.
- *
- * <tr id="setExceptionUserDataTypes"><td>setExceptionUserDataTypes</td>
- * <td>{@link javax.management.openmbean.CompositeType}[]</td>
- * <td>MBeanAttributeInfo</td>
- *
- * <td>The types of {@linkplain GenericMBeanException#getUserData() userData}
- * that can appear in a {@link GenericMBeanException} thrown when setting
- * this attribute. See also
- * <a href="#exceptionUserDataTypes">{@code exceptionUserDataTypes}</a>.
- *
* <tr><td>severity</td><td>String<br>Integer</td>
* <td>MBeanNotificationInfo</td>
*
--- a/jdk/src/share/classes/javax/management/DescriptorFields.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>Annotation that adds fields to a {@link Descriptor}. This can be the
- * Descriptor for an MBean, or for an attribute, operation, or constructor
- * in an MBean, or for a parameter of an operation or constructor.</p>
- *
- * <p>Consider this Standard MBean interface, for example:</p>
- *
- * <pre>
- * public interface CacheControlMBean {
- * <b>@DescriptorFields("units=bytes")</b>
- * public long getCacheSize();
- * }
- * </pre>
- *
- * <p>When a Standard MBean is made using this interface, the usual rules
- * mean that it will have an attribute called {@code CacheSize} of type
- * {@code long}. The {@code DescriptorFields} annotation will ensure
- * that the {@link MBeanAttributeInfo} for this attribute will have a
- * {@code Descriptor} that has a field called {@code units} with
- * corresponding value {@code bytes}.</p>
- *
- * <p>Similarly, if the interface looks like this:</p>
- *
- * <pre>
- * public interface CacheControlMBean {
- * <b>@DescriptorFields({"units=bytes", "since=1.5"})</b>
- * public long getCacheSize();
- * }
- * </pre>
- *
- * <p>then the resulting {@code Descriptor} will contain the following
- * fields:</p>
- *
- * <table border="2">
- * <tr><th>Name</th><th>Value</th></tr>
- * <tr><td>units</td><td>"bytes"</td></tr>
- * <tr><td>since</td><td>"1.5"</td></tr>
- * </table>
- *
- * <p>The {@code @DescriptorFields} annotation can be applied to:</p>
- *
- * <ul>
- * <li>a Standard MBean or MXBean interface;
- * <li>a method in such an interface;
- * <li>a parameter of a method in a Standard MBean or MXBean interface
- * when that method is an operation (not a getter or setter for an attribute);
- * <li>a public constructor in the class that implements a Standard MBean
- * or MXBean;
- * <li>a parameter in such a constructor.
- * </ul>
- *
- * <p>Other uses of the annotation will either fail to compile or be
- * ignored.</p>
- *
- * <p>Interface annotations are checked only on the exact interface
- * that defines the management interface of a Standard MBean or an
- * MXBean, not on its parent interfaces. Method annotations are
- * checked only in the most specific interface in which the method
- * appears; in other words, if a child interface overrides a method
- * from a parent interface, only {@code @DescriptorFields} annotations in
- * the method in the child interface are considered.
- *
- * <p>The Descriptor fields contributed in this way must be consistent
- * with each other and with any fields contributed by {@link
- * DescriptorKey @DescriptorKey} annotations. That is, two
- * different annotations, or two members of the same annotation, must
- * not define a different value for the same Descriptor field. Fields
- * from annotations on a getter method must also be consistent with
- * fields from annotations on the corresponding setter method.</p>
- *
- * <p>The Descriptor resulting from these annotations will be merged
- * with any Descriptor fields provided by the implementation, such as
- * the <a href="Descriptor.html#immutableInfo">{@code
- * immutableInfo}</a> field for an MBean. The fields from the annotations
- * must be consistent with these fields provided by the implementation.</p>
- *
- * <h4>{@literal @DescriptorFields and @DescriptorKey}</h4>
- *
- * <p>The {@link DescriptorKey @DescriptorKey} annotation provides
- * another way to use annotations to define Descriptor fields.
- * <code>@DescriptorKey</code> requires more work but is also more
- * robust, because there is less risk of mistakes such as misspelling
- * the name of the field or giving an invalid value.
- * <code>@DescriptorFields</code> is more convenient but includes
- * those risks. <code>@DescriptorFields</code> is more
- * appropriate for occasional use, but for a Descriptor field that you
- * add in many places, you should consider a purpose-built annotation
- * using <code>@DescriptorKey</code>.
- *
- * @since 1.7
- */
-@Documented
-@Inherited // for @MBean and @MXBean classes
-@Target({ElementType.CONSTRUCTOR, ElementType.METHOD,
- ElementType.PARAMETER, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface DescriptorFields {
- /**
- * <p>The descriptor fields. Each element of the string looks like
- * {@code "name=value"}.</p>
- */
- public String[] value();
-}
--- a/jdk/src/share/classes/javax/management/DescriptorKey.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/DescriptorKey.java Wed Oct 21 16:50:44 2009 +0100
@@ -33,11 +33,6 @@
* an MBean, or for an attribute, operation, or constructor in an
* MBean, or for a parameter of an operation or constructor.</p>
*
- * <p>(The {@link DescriptorFields @DescriptorFields} annotation
- * provides another way to add fields to a {@code Descriptor}. See
- * the documentation for that annotation for a comparison of the
- * two possibilities.)</p>
- *
* <p>Consider this annotation for example:</p>
*
* <pre>
@@ -130,13 +125,12 @@
* the method in the child interface are considered.
*
* <p>The Descriptor fields contributed in this way by different
- * annotations on the same program element must be consistent with
- * each other and with any fields contributed by a {@link
- * DescriptorFields @DescriptorFields} annotation. That is, two
- * different annotations, or two members of the same annotation, must
- * not define a different value for the same Descriptor field. Fields
- * from annotations on a getter method must also be consistent with
- * fields from annotations on the corresponding setter method.</p>
+ * annotations on the same program element must be consistent. That
+ * is, two different annotations, or two members of the same
+ * annotation, must not define a different value for the same
+ * Descriptor field. Fields from annotations on a getter method must
+ * also be consistent with fields from annotations on the
+ * corresponding setter method.</p>
*
* <p>The Descriptor resulting from these annotations will be merged
* with any Descriptor fields provided by the implementation, such as
@@ -175,36 +169,4 @@
@Target(ElementType.METHOD)
public @interface DescriptorKey {
String value();
-
- /**
- * <p>Do not include this field in the Descriptor if the annotation
- * element has its default value. For example, suppose {@code @Units} is
- * defined like this:</p>
- *
- * <pre>
- * @Documented
- * @Target(ElementType.METHOD)
- * @Retention(RetentionPolicy.RUNTIME)
- * public @interface Units {
- * @DescriptorKey("units")
- * String value();
- *
- * <b>@DescriptorKey(value = "descriptionResourceKey",
- * omitIfDefault = true)</b>
- * String resourceKey() default "";
- *
- * <b>@DescriptorKey(value = "descriptionResourceBundleBaseName",
- * omitIfDefault = true)</b>
- * String resourceBundleBaseName() default "";
- * }
- * </pre>
- *
- * <p>Then consider a usage such as {@code @Units("bytes")} or
- * {@code @Units(value = "bytes", resourceKey = "")}, where the
- * {@code resourceKey} and {@code resourceBundleBaseNames} elements
- * have their default values. In this case the Descriptor resulting
- * from these annotations will not include a {@code descriptionResourceKey}
- * or {@code descriptionResourceBundleBaseName} field.</p>
- */
- boolean omitIfDefault() default false;
}
--- a/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2005-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 javax.management;
-
-/**
- * <p>An MBean can implement this interface to affect how the MBeanServer's
- * {@link MBeanServer#getClassLoaderFor getClassLoaderFor} and
- * {@link MBeanServer#isInstanceOf isInstanceOf} methods behave.
- * If these methods should refer to a wrapped object rather than the
- * MBean object itself, then the {@link #getWrappedObject} method should
- * return that wrapped object.</p>
- *
- * @see MBeanServer#getClassLoaderFor
- * @see MBeanServer#isInstanceOf
- */
-public interface DynamicWrapperMBean extends DynamicMBean {
- /**
- * <p>The resource corresponding to this MBean. This is the object whose
- * class name should be reflected by the MBean's
- * {@link MBeanServer#getMBeanInfo getMBeanInfo()}.<!--
- * -->{@link MBeanInfo#getClassName getClassName()} for example. For a "plain"
- * DynamicMBean it will be "this". For an MBean that wraps another
- * object, in the manner of {@link javax.management.StandardMBean}, it will be the
- * wrapped object.</p>
- *
- * @return The resource corresponding to this MBean.
- */
- public Object getWrappedObject();
-
- /**
- * <p>The {@code ClassLoader} for this MBean, which can be used to
- * retrieve resources associated with the MBean for example. Usually,
- * it will be
- * {@link #getWrappedObject()}.{@code getClass().getClassLoader()}.
- *
- * @return The {@code ClassLoader} for this MBean.
- */
- public ClassLoader getWrappedClassLoader();
-}
--- a/jdk/src/share/classes/javax/management/GenericMBeanException.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +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 javax.management;
-
-import javax.management.openmbean.CompositeData;
-
-/**
- * <p>A customizable exception that has an optional error code string and
- * payload. By using this exception in an MBean, you can avoid requiring
- * clients of the MBean to have custom exception classes.</p>
- *
- * <p>An instance of this class has an optional {@linkplain #getErrorCode()
- * error code}, and an optional {@linkplain #getUserData() payload} known as
- * {@code userData}. This allows you to distinguish between different
- * sorts of exception while still using this class for all of them.</p>
- *
- * <p>To produce a suitable {@code userData}, it is often simplest to use
- * the MXBean framework. For example, suppose you want to convey a severity
- * and a subsystem with your exception, which are respectively an int and a
- * String. You could define a class like this:</p>
- *
- * <pre>
- * public class ExceptionDetails {
- * private final int severity;
- * private final String subsystem;
- *
- * {@link java.beans.ConstructorProperties @ConstructorProperties}(<!--
- * -->{"severity", "subsystem"})
- * public ExceptionDetails(int severity, String subsystem) {
- * this.severity = severity;
- * this.subsystem = subsystem;
- * }
- *
- * public int getSeverity() {
- * return severity;
- * }
- *
- * public String getSubsystem() {
- * return subsystem;
- * }
- * }
- * </pre>
- *
- * <p>Then you can get the MXBean framework to transform {@code ExceptionDetails}
- * into {@link CompositeData} like this:</p>
- *
- * <pre>
- * static final <!--
- * -->{@link javax.management.openmbean.MXBeanMapping MXBeanMapping} <!--
- * -->exceptionDetailsMapping = <!--
- * -->{@link javax.management.openmbean.MXBeanMappingFactory#DEFAULT
- * MXBeanMappingFactory.DEFAULT}.mappingForType(
- * ExceptionDetails.class, MXBeanMappingFactory.DEFAULT);
- *
- * public static GenericMBeanException newGenericMBeanException(
- * String message, String errorCode, int severity, String subsystem) {
- * ExceptionDetails details = new ExceptionDetails(severity, subsystem);
- * CompositeData userData = (CompositeData)
- * exceptionDetailsMapping.toOpenValue(details);
- * return new GenericMBeanException(
- * message, errorCode, userData, (Throwable) null);
- * }
- *
- * ...
- * throw newGenericMBeanException(message, errorCode, 25, "foosystem");
- * </pre>
- *
- * <p>A client that knows the {@code ExceptionDetails} class can convert
- * back from the {@code userData} of a {@code GenericMBeanException}
- * that was generated as above:</p>
- *
- * <pre>
- * ...
- * try {
- * mbeanProxy.foo();
- * } catch (GenericMBeanException e) {
- * CompositeData userData = e.getUserData();
- * ExceptionDetails details = (ExceptionDetails)
- * exceptionDetailsMapping.fromOpenValue(userData);
- * System.out.println("Exception Severity: " + details.getSeverity());
- * }
- * ...
- * </pre>
- *
- * <p>The Descriptor field <a href="Descriptor.html#exceptionErrorCodes"><!--
- * -->exceptionErrorCodes</a> can be used to specify in the
- * {@link MBeanOperationInfo} for an operation what the possible
- * {@linkplain #getErrorCode() error codes} are when that operation throws
- * {@code GenericMBeanException}. It can also be used in an {@link
- * MBeanConstructorInfo} or {@link MBeanAttributeInfo} to specify what the
- * possible error codes are for {@code GenericMBeanException} when invoking
- * that constructor or getting that attribute, respectively. The field
- * <a href="Descriptor.html#setExceptionErrorCodes"><!--
- * -->setExceptionErrorCodes</a> can be used to specify what the possible
- * error codes are when setting an attribute.</p>
- *
- * <p>You may want to use the {@link DescriptorKey @DescriptorKey} facility
- * to define annotations that allow you to specify the error codes. If you
- * define...</p>
- *
- * <pre>
- * {@link java.lang.annotation.Documented @Documented}
- * {@link java.lang.annotation.Target @Target}(ElementType.METHOD)
- * {@link java.lang.annotation.Retention @Retention}(RetentionPolicy.RUNTIME)
- * public @interface ErrorCodes {
- * @DescriptorKey("exceptionErrorCodes")
- * String[] value();
- * }
- * </pre>
- *
- * <p>...then you can write MBean interfaces like this...</p>
- *
- * <pre>
- * public interface FooMBean { // or FooMXBean
- * @ErrorCodes({"com.example.bad", "com.example.worse"})
- * public void foo() throws GenericMBeanException;
- * }
- * </pre>
- *
- * <p>The Descriptor field <a href="Descriptor.html#exceptionUserDataTypes"><!--
- * -->exceptionUserDataTypes</a> can be used to specify in the
- * {@link MBeanOperationInfo} for an operation what the possible types of
- * {@linkplain #getUserData() userData} are when that operation throws
- * {@code GenericMBeanException}. It is an array of
- * {@link javax.management.openmbean.CompositeType CompositeType} values
- * describing the possible {@link CompositeData} formats. This field can also be used
- * in an {@link MBeanConstructorInfo} or {@link MBeanAttributeInfo} to specify
- * the possible types of user data for {@code GenericMBeanException} when
- * invoking that constructor or getting that attribute, respectively. The
- * field
- * <a href="Descriptor.html#setExceptionUserDataTypes">setExceptionUserDataTypes</a>
- * can be used to specify the possible types of user data for exceptions when
- * setting an attribute. If a Descriptor has both {@code exceptionErrorCodes}
- * and {@code exceptionUserDataTypes} then the two arrays should be the
- * same size; each pair of corresponding elements describes one kind
- * of exception. Similarly for {@code setExceptionErrorCodes} and {@code
- * setExceptionUserDataTypes}.
- *
- *
- * <h4>Serialization</h4>
- *
- * <p>For compatibility reasons, instances of this class are serialized as
- * instances of {@link MBeanException}. Special logic in that class converts
- * them back to instances of this class at deserialization time. If the
- * serialized object is deserialized in an earlier version of the JMX API
- * that does not include this class, then it will appear as just an {@code
- * MBeanException} and the error code or userData will not be available.</p>
- *
- * @since 1.7
- */
-public class GenericMBeanException extends MBeanException {
- private static final long serialVersionUID = -1560202003985932823L;
-
- /**
- * <p>Constructs a new {@code GenericMBeanException} with the given
- * detail message. This constructor is
- * equivalent to {@link #GenericMBeanException(String, String,
- * CompositeData, Throwable) GenericMBeanException(message, "",
- * null, null)}.</p>
- *
- * @param message the exception detail message.
- */
- public GenericMBeanException(String message) {
- this(message, "", null, null);
- }
-
- /**
- * <p>Constructs a new {@code GenericMBeanException} with the given
- * detail message and cause. This constructor is
- * equivalent to {@link #GenericMBeanException(String, String,
- * CompositeData, Throwable) GenericMBeanException(message, "",
- * null, cause)}.</p>
- *
- * @param message the exception detail message.
- * @param cause the cause of this exception. Can be null.
- */
- public GenericMBeanException(String message, Throwable cause) {
- this(message, "", null, cause);
- }
-
- /**
- * <p>Constructs a new {@code GenericMBeanException} with the given
- * detail message, error code, and user data. This constructor is
- * equivalent to {@link #GenericMBeanException(String, String,
- * CompositeData, Throwable) GenericMBeanException(message, errorCode,
- * userData, null)}.</p>
- *
- * @param message the exception detail message.
- * @param errorCode the exception error code. Specifying a null value
- * is equivalent to specifying an empty string. It is recommended to use
- * the same reverse domain name convention as package names, for example
- * "com.example.foo.UnexpectedFailure". There is no requirement that the
- * error code be a syntactically valid Java identifier.
- * @param userData extra information about the exception. Can be null.
- */
- public GenericMBeanException(
- String message, String errorCode, CompositeData userData) {
- this(message, errorCode, userData, null);
- }
-
- /**
- * <p>Constructs a new {@code GenericMBeanException} with the given
- * detail message, error code, user data, and cause.</p>
- *
- * @param message the exception detail message.
- * @param errorCode the exception error code. Specifying a null value
- * is equivalent to specifying an empty string. It is recommended to use
- * the same reverse domain name convention as package names, for example
- * "com.example.foo.UnexpectedFailure". There is no requirement that the
- * error code be a syntactically valid Java identifier.
- * @param userData extra information about the exception. Can be null.
- * @param cause the cause of this exception. Can be null.
- */
- public GenericMBeanException(
- String message, String errorCode, CompositeData userData,
- Throwable cause) {
- super(message, (errorCode == null) ? "" : errorCode, userData, cause);
- }
-
- /**
- * <p>Returns the error code of this exception.</p>
- *
- * @return the error code. This value is never null.
- */
- public String getErrorCode() {
- return errorCode;
- }
-
- /**
- * <p>Returns the userData of this exception.</p>
- *
- * @return the userData. Can be null.
- */
- public CompositeData getUserData() {
- return userData;
- }
-
- /**
- * <p>Instances of this class are serialized as instances of
- * {@link MBeanException}. {@code MBeanException} has private fields that can
- * not be set by its public constructors. They can only be set in objects
- * returned by this method. When an {@code MBeanException} instance is
- * deserialized, if those fields are present then its {@code readResolve}
- * method will substitute a {@code GenericMBeanException} equivalent to
- * this one.</p>
- */
- Object writeReplace() {
- MBeanException x = new MBeanException(
- getMessage(), errorCode, userData, getCause());
- x.setStackTrace(this.getStackTrace());
- return x;
- }
-}
--- a/jdk/src/share/classes/javax/management/Impact.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +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 javax.management;
-
-/**
- * <p>Defines the impact of an MBean operation, in particular whether it
- * has an effect on the MBean or simply returns information. This enum
- * is used in the {@link ManagedOperation @ManagedOperation} annotation.
- * Its {@link #getCode()} method can be used to get an {@code int} suitable
- * for use as the {@code impact} parameter in an {@link MBeanOperationInfo}
- * constructor.</p>
- */
-public enum Impact {
- /**
- * The operation is read-like: it returns information but does not change
- * any state.
- * @see MBeanOperationInfo#INFO
- */
- INFO(MBeanOperationInfo.INFO),
-
- /**
- * The operation is write-like: it has an effect but does not return
- * any information from the MBean.
- * @see MBeanOperationInfo#ACTION
- */
- ACTION(MBeanOperationInfo.ACTION),
-
- /**
- * The operation is both read-like and write-like: it has an effect,
- * and it also returns information from the MBean.
- * @see MBeanOperationInfo#ACTION_INFO
- */
- ACTION_INFO(MBeanOperationInfo.ACTION_INFO),
-
- /**
- * The impact of the operation is unknown or cannot be expressed
- * using one of the other values.
- * @see MBeanOperationInfo#UNKNOWN
- */
- UNKNOWN(MBeanOperationInfo.UNKNOWN);
-
- private final int code;
-
- /**
- * An instance of this enumeration, with the corresponding {@code int}
- * code used by the {@link MBeanOperationInfo} constructors.
- *
- * @param code the code used by the {@code MBeanOperationInfo} constructors.
- */
- Impact(int code) {
- this.code = code;
- }
-
- /**
- * The equivalent {@code int} code used by the {@link MBeanOperationInfo}
- * constructors.
- * @return the {@code int} code.
- */
- public int getCode() {
- return code;
- }
-
- /**
- * Return the {@code Impact} value corresponding to the given {@code int}
- * code. The {@code code} is the value that would be used in an
- * {@code MBeanOperationInfo} constructor.
- *
- * @param code the {@code int} code.
- *
- * @return an {@code Impact} value {@code x} such that
- * {@code code == x.}{@link #getCode()}, or {@code Impact.UNKNOWN}
- * if there is no such value.
- */
- public static Impact forCode(int code) {
- switch (code) {
- case MBeanOperationInfo.ACTION: return ACTION;
- case MBeanOperationInfo.INFO: return INFO;
- case MBeanOperationInfo.ACTION_INFO: return ACTION_INFO;
- default: return UNKNOWN;
- }
- }
-}
--- a/jdk/src/share/classes/javax/management/InstanceNotFoundException.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/InstanceNotFoundException.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2003 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
@@ -51,16 +51,4 @@
public InstanceNotFoundException(String message) {
super(message);
}
-
- /**
- * Constructor for the frequent case where the message is the ObjectName
- * of the missing MBean.
- *
- * @param name the ObjectName of the missing MBean.
- *
- * @since 1.7
- */
- public InstanceNotFoundException(ObjectName name) {
- this(String.valueOf(name));
- }
}
--- a/jdk/src/share/classes/javax/management/JMRuntimeException.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/JMRuntimeException.java Wed Oct 21 16:50:44 2009 +0100
@@ -58,22 +58,6 @@
* specification. A later version may make it public.
*/
JMRuntimeException(String message, Throwable cause) {
- super(message);
-
- /* Make a best effort to set the cause, but if we don't
- succeed, too bad, you don't get that useful debugging
- information. We jump through hoops here so that we can
- work on platforms prior to J2SE 1.4 where the
- Throwable.initCause method was introduced. If we change
- the public interface of JMRuntimeException in a future
- version we can add getCause() so we don't need to do this. */
- try {
- java.lang.reflect.Method initCause =
- Throwable.class.getMethod("initCause",
- new Class<?>[] {Throwable.class});
- initCause.invoke(this, new Object[] {cause});
- } catch (Exception e) {
- // OK: just means we won't have debugging info
- }
+ super(message, cause);
}
}
--- a/jdk/src/share/classes/javax/management/JMX.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/JMX.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2006 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
@@ -26,20 +26,8 @@
package javax.management;
import com.sun.jmx.mbeanserver.Introspector;
-import com.sun.jmx.mbeanserver.MBeanInjector;
-import com.sun.jmx.remote.util.ClassLogger;
-import java.beans.BeanInfo;
-import java.beans.PropertyDescriptor;
-import java.io.IOException;
-import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.util.Map;
-import java.util.TreeMap;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.openmbean.MXBeanMappingFactory;
/**
* Static methods from the JMX API. There are no instances of this class.
@@ -60,27 +48,6 @@
*/
public static final String DEFAULT_VALUE_FIELD = "defaultValue";
- /**
- * The name of the <a
- * href="Descriptor.html#descriptionResourceBundleBaseName">{@code
- * descriptionResourceBundleBaseName}</a> field.
- */
- public static final String DESCRIPTION_RESOURCE_BUNDLE_BASE_NAME_FIELD =
- "descriptionResourceBundleBaseName";
-
- /**
- * The name of the <a href="Descriptor.html#descriptionResourceKey">{@code
- * descriptionResourceKey}</a> field.
- */
- public static final String DESCRIPTION_RESOURCE_KEY_FIELD =
- "descriptionResourceKey";
-
- /**
- * The name of the <a href="Descriptor.html#exceptions">{@code
- * exceptions}</a> field.
- */
- public static final String EXCEPTIONS_FIELD = "exceptions";
-
/**
* The name of the <a href="Descriptor.html#immutableInfo">{@code
* immutableInfo}</a> field.
@@ -100,12 +67,6 @@
public static final String LEGAL_VALUES_FIELD = "legalValues";
/**
- * The name of the <a href="Descriptor.html#locale">{@code locale}</a>
- * field.
- */
- public static final String LOCALE_FIELD = "locale";
-
- /**
* The name of the <a href="Descriptor.html#maxValue">{@code
* maxValue}</a> field.
*/
@@ -124,14 +85,6 @@
public static final String MXBEAN_FIELD = "mxbean";
/**
- * The name of the
- * <a href="Descriptor.html#mxbeanMappingFactoryClass">{@code
- * mxbeanMappingFactoryClass}</a> field.
- */
- public static final String MXBEAN_MAPPING_FACTORY_CLASS_FIELD =
- "mxbeanMappingFactoryClass";
-
- /**
* The name of the <a href="Descriptor.html#openType">{@code
* openType}</a> field.
*/
@@ -144,276 +97,6 @@
public static final String ORIGINAL_TYPE_FIELD = "originalType";
/**
- * The name of the <a href="Descriptor.html#setExceptions">{@code
- * setExceptions}</a> field.
- */
- public static final String SET_EXCEPTIONS_FIELD = "setExceptions";
-
- /**
- * The name of the <a href="Descriptor.html#objectNameTemplate">{@code
- * objectNameTemplate}</a> field.
- */
- public static final String OBJECT_NAME_TEMPLATE = "objectNameTemplate";
-
- /**
- * <p>Options to apply to an MBean proxy or to an instance of {@link
- * StandardMBean}.</p>
- *
- * <p>For example, to specify the "wrapped object visible" option for a
- * {@code StandardMBean}, you might write this:</p>
- *
- * <pre>
- * StandardMBean.Options opts = new StandardMBean.Options();
- * opts.setWrappedObjectVisible(true);
- * StandardMBean mbean = new StandardMBean(impl, intf, opts);
- * </pre>
- *
- * @see javax.management.JMX.ProxyOptions
- * @see javax.management.StandardMBean.Options
- */
- public static class MBeanOptions implements Serializable, Cloneable {
- private static final long serialVersionUID = -6380842449318177843L;
-
- static final MBeanOptions MXBEAN = new MBeanOptions();
- static {
- MXBEAN.setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- }
-
- private MXBeanMappingFactory mappingFactory;
-
- /**
- * <p>Construct an {@code MBeanOptions} object where all options have
- * their default values.</p>
- */
- public MBeanOptions() {}
-
- @Override
- public MBeanOptions clone() {
- try {
- return (MBeanOptions) super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * <p>True if this is an MXBean proxy or a StandardMBean instance
- * that is an MXBean. The default value is false.</p>
- *
- * <p>This method is equivalent to {@link #getMXBeanMappingFactory()
- * this.getMXBeanMappingFactory()}{@code != null}.</p>
- *
- * @return true if this is an MXBean proxy or a StandardMBean instance
- * that is an MXBean.
- */
- public boolean isMXBean() {
- return (this.mappingFactory != null);
- }
-
- /**
- * <p>The mappings between Java types and Open Types to be used in
- * an MXBean proxy or a StandardMBean instance that is an MXBean,
- * or null if this instance is not for an MXBean.
- * The default value is null.</p>
- *
- * @return the mappings to be used in this proxy or StandardMBean,
- * or null if this instance is not for an MXBean.
- */
- public MXBeanMappingFactory getMXBeanMappingFactory() {
- return mappingFactory;
- }
-
- /**
- * <p>Set the {@link #getMXBeanMappingFactory() MXBeanMappingFactory} to
- * the given value. The value should be null if this instance is not
- * for an MXBean. If this instance is for an MXBean, the value should
- * usually be either a custom mapping factory, or
- * {@link MXBeanMappingFactory#forInterface
- * MXBeanMappingFactory.forInterface}{@code (mxbeanInterface)}
- * which signifies
- * that the {@linkplain MXBeanMappingFactory#DEFAULT default} mapping
- * factory should be used unless an {@code @}{@link
- * javax.management.openmbean.MXBeanMappingFactoryClass
- * MXBeanMappingFactoryClass} annotation on {@code mxbeanInterface}
- * specifies otherwise.</p>
- *
- * <p>Examples:</p>
- * <pre>
- * MBeanOptions opts = new MBeanOptions();
- * opts.setMXBeanMappingFactory(myMappingFactory);
- * MyMXBean proxy = JMX.newMBeanProxy(
- * mbeanServerConnection, objectName, MyMXBean.class, opts);
- *
- * // ...or...
- *
- * MBeanOptions opts = new MBeanOptions();
- * MXBeanMappingFactory defaultFactoryForMyMXBean =
- * MXBeanMappingFactory.forInterface(MyMXBean.class);
- * opts.setMXBeanMappingFactory(defaultFactoryForMyMXBean);
- * MyMXBean proxy = JMX.newMBeanProxy(
- * mbeanServerConnection, objectName, MyMXBean.class, opts);
- * </pre>
- *
- * @param f the new value. If null, this instance is not for an
- * MXBean.
- */
- public void setMXBeanMappingFactory(MXBeanMappingFactory f) {
- this.mappingFactory = f;
- }
-
- /* To maximise object sharing, classes in this package can replace
- * a private MBeanOptions with no MXBeanMappingFactory with one
- * of these shared instances. But they must be EXTREMELY careful
- * never to give out the shared instances to user code, which could
- * modify them.
- */
- private static final MBeanOptions[] CANONICALS = {
- new MBeanOptions(), MXBEAN,
- };
- // Overridden in local subclasses:
- MBeanOptions[] canonicals() {
- return CANONICALS;
- }
-
- // This is only used by the logic for canonical instances.
- // Overridden in local subclasses:
- boolean same(MBeanOptions opt) {
- return (opt.mappingFactory == mappingFactory);
- }
-
- final MBeanOptions canonical() {
- for (MBeanOptions opt : canonicals()) {
- if (opt.getClass() == this.getClass() && same(opt))
- return opt;
- }
- return this;
- }
-
- final MBeanOptions uncanonical() {
- for (MBeanOptions opt : canonicals()) {
- if (this == opt)
- return clone();
- }
- return this;
- }
-
- private Map<String, Object> toMap() {
- Map<String, Object> map = new TreeMap<String, Object>();
- try {
- BeanInfo bi = java.beans.Introspector.getBeanInfo(getClass());
- PropertyDescriptor[] pds = bi.getPropertyDescriptors();
- for (PropertyDescriptor pd : pds) {
- String name = pd.getName();
- if (name.equals("class"))
- continue;
- Method get = pd.getReadMethod();
- if (get != null)
- map.put(name, get.invoke(this));
- }
- } catch (Exception e) {
- Throwable t = e;
- if (t instanceof InvocationTargetException)
- t = t.getCause();
- map.put("Exception", t);
- }
- return map;
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + toMap();
- // For example "MBeanOptions{MXBean=true, <etc>}".
- }
-
- /**
- * <p>Indicates whether some other object is "equal to" this one. The
- * result is true if and only if the other object is also an instance
- * of MBeanOptions or a subclass, and has the same properties with
- * the same values.</p>
- * @return {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == this)
- return true;
- if (obj == null || obj.getClass() != this.getClass())
- return false;
- return toMap().equals(((MBeanOptions) obj).toMap());
- }
-
- @Override
- public int hashCode() {
- return toMap().hashCode();
- }
- }
-
- /**
- * <p>Options to apply to an MBean proxy.</p>
- *
- * @see #newMBeanProxy
- */
- public static class ProxyOptions extends MBeanOptions {
- private static final long serialVersionUID = 7238804866098386559L;
-
- private boolean notificationEmitter;
-
- /**
- * <p>Construct a {@code ProxyOptions} object where all options have
- * their default values.</p>
- */
- public ProxyOptions() {}
-
- @Override
- public ProxyOptions clone() {
- return (ProxyOptions) super.clone();
- }
-
- /**
- * <p>Defines whether the returned proxy should
- * implement {@link NotificationEmitter}. The default value is false.</p>
- *
- * @return true if this proxy will be a NotificationEmitter.
- *
- * @see JMX#newMBeanProxy(MBeanServerConnection, ObjectName, Class,
- * MBeanOptions)
- */
- public boolean isNotificationEmitter() {
- return this.notificationEmitter;
- }
-
- /**
- * <p>Set the {@link #isNotificationEmitter NotificationEmitter} option to
- * the given value.</p>
- * @param emitter the new value.
- */
- public void setNotificationEmitter(boolean emitter) {
- this.notificationEmitter = emitter;
- }
-
- // Canonical objects for each of (MXBean,!MXBean) x (Emitter,!Emitter)
- private static final ProxyOptions[] CANONICALS = {
- new ProxyOptions(), new ProxyOptions(),
- new ProxyOptions(), new ProxyOptions(),
- };
- static {
- CANONICALS[1].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- CANONICALS[2].setNotificationEmitter(true);
- CANONICALS[3].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- CANONICALS[3].setNotificationEmitter(true);
- }
- @Override
- MBeanOptions[] canonicals() {
- return CANONICALS;
- }
-
- @Override
- boolean same(MBeanOptions opt) {
- return (super.same(opt) && opt instanceof ProxyOptions &&
- ((ProxyOptions) opt).notificationEmitter == notificationEmitter);
- }
- }
-
- /**
* <p>Make a proxy for a Standard MBean in a local or remote
* MBean Server.</p>
*
@@ -501,12 +184,6 @@
* likewise for the other methods of {@link
* NotificationBroadcaster} and {@link NotificationEmitter}.</p>
*
- * <p>This method is equivalent to {@link
- * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions)
- * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where
- * {@code opts} is a {@link JMX.ProxyOptions} representing the
- * {@code notificationEmitter} parameter.</p>
- *
* @param connection the MBean server to forward to.
* @param objectName the name of the MBean within
* {@code connection} to forward to.
@@ -515,18 +192,22 @@
* @param notificationEmitter make the returned proxy
* implement {@link NotificationEmitter} by forwarding its methods
* via {@code connection}.
+ *
* @param <T> allows the compiler to know that if the {@code
* interfaceClass} parameter is {@code MyMBean.class}, for
* example, then the return type is {@code MyMBean}.
+ *
* @return the new proxy instance.
*/
public static <T> T newMBeanProxy(MBeanServerConnection connection,
ObjectName objectName,
Class<T> interfaceClass,
boolean notificationEmitter) {
- ProxyOptions opts = new ProxyOptions();
- opts.setNotificationEmitter(notificationEmitter);
- return newMBeanProxy(connection, objectName, interfaceClass, opts);
+ return MBeanServerInvocationHandler.newProxyInstance(
+ connection,
+ objectName,
+ interfaceClass,
+ notificationEmitter);
}
/**
@@ -599,6 +280,10 @@
*
* </ul>
*
+ * <p>The object returned by this method is a
+ * {@link Proxy} whose {@code InvocationHandler} is an
+ * {@link MBeanServerInvocationHandler}.</p>
+ *
* <p>This method is equivalent to {@link
* #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
* boolean) newMXBeanProxy(connection, objectName, interfaceClass,
@@ -641,17 +326,6 @@
* likewise for the other methods of {@link
* NotificationBroadcaster} and {@link NotificationEmitter}.</p>
*
- * <p>This method is equivalent to {@link
- * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions)
- * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where
- * {@code opts} is a {@link JMX.ProxyOptions} where the {@link
- * JMX.ProxyOptions#getMXBeanMappingFactory() MXBeanMappingFactory}
- * property is
- * {@link MXBeanMappingFactory#forInterface(Class)
- * MXBeanMappingFactory.forInterface(interfaceClass)} and the {@link
- * JMX.ProxyOptions#isNotificationEmitter() notificationEmitter} property
- * is equal to the {@code notificationEmitter} parameter.</p>
- *
* @param connection the MBean server to forward to.
* @param objectName the name of the MBean within
* {@code connection} to forward to.
@@ -660,130 +334,26 @@
* @param notificationEmitter make the returned proxy
* implement {@link NotificationEmitter} by forwarding its methods
* via {@code connection}.
+ *
* @param <T> allows the compiler to know that if the {@code
* interfaceClass} parameter is {@code MyMXBean.class}, for
* example, then the return type is {@code MyMXBean}.
+ *
* @return the new proxy instance.
*/
public static <T> T newMXBeanProxy(MBeanServerConnection connection,
ObjectName objectName,
Class<T> interfaceClass,
boolean notificationEmitter) {
- ProxyOptions opts = new ProxyOptions();
- MXBeanMappingFactory f = MXBeanMappingFactory.forInterface(interfaceClass);
- opts.setMXBeanMappingFactory(f);
- opts.setNotificationEmitter(notificationEmitter);
- return newMBeanProxy(connection, objectName, interfaceClass, opts);
- }
-
- /**
- * <p>Make a proxy for a Standard MBean or MXBean in a local or remote MBean
- * Server that may also support the methods of {@link
- * NotificationEmitter} and (for an MXBean) that may define custom MXBean
- * type mappings.</p>
- *
- * <p>This method behaves the same as
- * {@link #newMBeanProxy(MBeanServerConnection, ObjectName, Class)} or
- * {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)},
- * according as {@code opts.isMXBean()} is respectively false or true; but
- * with the following changes based on {@code opts}.</p>
- *
- * <ul>
- * <li>If {@code opts.isNotificationEmitter()} is {@code
- * true}, then the MBean is assumed to be a {@link
- * NotificationBroadcaster} or {@link NotificationEmitter} and the
- * returned proxy will implement {@link NotificationEmitter} as
- * well as {@code interfaceClass}. A call to {@link
- * NotificationBroadcaster#addNotificationListener} on the proxy
- * will result in a call to {@link
- * MBeanServerConnection#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)}, and
- * likewise for the other methods of {@link
- * NotificationBroadcaster} and {@link NotificationEmitter}.</li>
- *
- * <li>If {@code opts.getMXBeanMappingFactory()} is not null,
- * then the mappings it defines will be applied to convert between
- * arbitrary Java types and Open Types.</li>
- * </ul>
- *
- * <p>The object returned by this method is a
- * {@link Proxy} whose {@code InvocationHandler} is an
- * {@link MBeanServerInvocationHandler}. This means that it is possible
- * to retrieve the parameters that were used to produce the proxy. If the
- * proxy was produced as follows...</p>
- *
- * <pre>
- * FooMBean proxy =
- * JMX.newMBeanProxy(connection, objectName, FooMBean.class, opts);
- * </pre>
- *
- * <p>...then you can get the {@code MBeanServerInvocationHandler} like
- * this...</p>
- *
- * <pre>
- * MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
- * {@link Proxy#getInvocationHandler(Object)
- * Proxy.getInvocationHandler}(proxy);
- * </pre>
- *
- * <p>...and you can retrieve {@code connection}, {@code
- * objectName}, and {@code opts} using the {@link
- * MBeanServerInvocationHandler#getMBeanServerConnection()
- * getMBeanServerConnection()}, {@link
- * MBeanServerInvocationHandler#getObjectName() getObjectName()}, and
- * {@link MBeanServerInvocationHandler#getMBeanOptions() getMBeanOptions()}
- * methods on {@code mbsih}. You can retrieve {@code FooMBean.class}
- * using {@code proxy.getClass().}{@link
- * Class#getInterfaces() getInterfaces()}.</p>
- *
- * @param connection the MBean server to forward to.
- * @param objectName the name of the MBean within
- * {@code connection} to forward to.
- * @param interfaceClass the Standard MBean or MXBean interface,
- * which will also be implemented by the returned proxy.
- * @param opts the options to apply for this proxy. Can be null,
- * in which case default options are applied.
- * @param <T> allows the compiler to know that if the {@code
- * interfaceClass} parameter is {@code MyMXBean.class}, for
- * example, then the return type is {@code MyMXBean}.
- * @return the new proxy instance.
- *
- * @throws IllegalArgumentException if {@code interfaceClass} is not a
- * valid MXBean interface.
- */
- public static <T> T newMBeanProxy(MBeanServerConnection connection,
- ObjectName objectName,
- Class<T> interfaceClass,
- MBeanOptions opts) {
+ // Check interface for MXBean compliance
+ //
try {
- return newMBeanProxy2(connection, objectName, interfaceClass, opts);
+ Introspector.testComplianceMXBeanInterface(interfaceClass);
} catch (NotCompliantMBeanException e) {
throw new IllegalArgumentException(e);
}
- }
-
- private static <T> T newMBeanProxy2(MBeanServerConnection connection,
- ObjectName objectName,
- Class<T> interfaceClass,
- MBeanOptions opts)
- throws NotCompliantMBeanException {
-
- if (opts == null)
- opts = new MBeanOptions();
-
- boolean notificationEmitter = opts instanceof ProxyOptions &&
- ((ProxyOptions) opts).isNotificationEmitter();
-
- MXBeanMappingFactory mappingFactory = opts.getMXBeanMappingFactory();
-
- if (mappingFactory != null) {
- // Check interface for MXBean compliance
- Introspector.testComplianceMXBeanInterface(interfaceClass,
- mappingFactory);
- }
-
InvocationHandler handler = new MBeanServerInvocationHandler(
- connection, objectName, opts);
+ connection, objectName, true);
final Class<?>[] interfaces;
if (notificationEmitter) {
interfaces =
@@ -822,109 +392,4 @@
// exactly the string "MXBean" since that would mean there
// was no package name, which is pretty unlikely in practice.
}
-
- /**
- * <p>Test if an MBean can emit notifications. An MBean can emit
- * notifications if either it implements {@link NotificationBroadcaster}
- * (perhaps through its child interface {@link NotificationEmitter}), or
- * it uses <a href="MBeanRegistration.html#injection">resource
- * injection</a> to obtain an instance of {@link SendNotification}
- * through which it can send notifications.</p>
- *
- * @param mbean an MBean object.
- * @return true if the given object is a valid MBean that can emit
- * notifications; false if the object is a valid MBean but that
- * cannot emit notifications.
- * @throws NotCompliantMBeanException if the given object is not
- * a valid MBean.
- */
- public static boolean isNotificationSource(Object mbean)
- throws NotCompliantMBeanException {
- for (int i = 0; i < 2; i++) {
- if (mbean instanceof NotificationBroadcaster ||
- MBeanInjector.injectsSendNotification(mbean))
- return true;
- if (mbean instanceof DynamicWrapperMBean)
- mbean = ((DynamicWrapperMBean) mbean).getWrappedObject();
- else
- break;
- }
- return false;
- }
-
- /**
- * <p>Return the version of the JMX specification that a (possibly remote)
- * MBean Server is using. The JMX specification described in this
- * documentation is version 2.0. The earlier versions that might be
- * reported by this method are 1.0, 1.1, 1.2, and 1.4. (There is no 1.3.)
- * All of these versions and all future versions can be compared using
- * {@link String#compareTo(String)}. So, for example, to tell if
- * {@code mbsc} is running at least version 2.0 you can write:</p>
- *
- * <pre>
- * String version = JMX.getSpecificationVersion(mbsc, null);
- * boolean atLeast2dot0 = (version.compareTo("2.0") >= 0);
- * </pre>
- *
- * <p>A remote MBean Server might be running an earlier version of the
- * JMX API, and in that case <a href="package-summary.html#interop">certain
- * features</a> might not be available in it.</p>
- *
- * <p>The version of the MBean Server {@code mbsc} is not necessarily
- * the version of all namespaces within that MBean Server, for example
- * if some of them use {@link javax.management.namespace.JMXRemoteNamespace
- * JMXRemoteNamespace}. To determine the version of the namespace
- * that a particular MBean is in, give its name as the {@code mbeanName}
- * parameter.</p>
- *
- * @param mbsc a connection to an MBean Server.
- *
- * @param mbeanName the name of an MBean within that MBean Server, or null.
- * If non-null, the namespace of this name, as determined by
- * {@link JMXNamespaces#getContainingNamespace
- * JMXNamespaces.getContainingNamespace}, is the one whose specification
- * version will be returned.
- *
- * @return the JMX specification version reported by that MBean Server.
- *
- * @throws IllegalArgumentException if {@code mbsc} is null, or if
- * {@code mbeanName} includes a wildcard character ({@code *} or {@code ?})
- * in its namespace.
- *
- * @throws IOException if the version cannot be obtained, either because
- * there is a communication problem or because the remote MBean Server
- * does not have the appropriate {@linkplain
- * MBeanServerDelegateMBean#getSpecificationVersion() attribute}.
- *
- * @see <a href="package-summary.html#interop">Interoperability between
- * versions of the JMX specification</a>
- * @see MBeanServerDelegateMBean#getSpecificationVersion
- */
- public static String getSpecificationVersion(
- MBeanServerConnection mbsc, ObjectName mbeanName)
- throws IOException {
- if (mbsc == null)
- throw new IllegalArgumentException("Null MBeanServerConnection");
-
- String namespace;
- if (mbeanName == null)
- namespace = "";
- else
- namespace = JMXNamespaces.getContainingNamespace(mbeanName);
- if (namespace.contains("*") || namespace.contains("?")) {
- throw new IllegalArgumentException(
- "ObjectName contains namespace wildcard: " + mbeanName);
- }
-
- try {
- if (namespace.length() > 0)
- mbsc = JMXNamespaces.narrowToNamespace(mbsc, namespace);
- return (String) mbsc.getAttribute(
- MBeanServerDelegate.DELEGATE_NAME, "SpecificationVersion");
- } catch (IOException e) {
- throw e;
- } catch (Exception e) {
- throw new IOException(e);
- }
- }
}
--- a/jdk/src/share/classes/javax/management/MBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +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 javax.management;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>Indicates that the annotated class is a Standard MBean. A Standard
- * MBean class can be defined as in this example:</p>
- *
- * <pre>
- * {@code @MBean}
- * public class Configuration {
- * {@link ManagedAttribute @ManagedAttribute}
- * public int getCacheSize() {...}
- * {@code @ManagedAttribute}
- * public void setCacheSize(int size);
- *
- * {@code @ManagedAttribute}
- * public long getLastChangedTime();
- *
- * {@link ManagedOperation @ManagedOperation}
- * public void save();
- * }
- * </pre>
- *
- * <p>The class must be public. Public methods within the class can be
- * annotated with {@code @ManagedOperation} to indicate that they are
- * MBean operations. Public getter and setter methods within the class
- * can be annotated with {@code @ManagedAttribute} to indicate that they define
- * MBean attributes.</p>
- *
- * <p>If the MBean is to be an MXBean rather than a Standard MBean, then
- * the {@link MXBean @MXBean} annotation must be used instead of
- * {@code @MBean}.</p>
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Inherited
-public @interface MBean {
-}
--- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -186,10 +186,8 @@
(getter != null),
(setter != null),
isIs(getter),
- ImmutableDescriptor.union(Introspector.
- descriptorForElement(getter, false),
- Introspector.descriptorForElement(setter,
- true)));
+ ImmutableDescriptor.union(Introspector.descriptorForElement(getter),
+ Introspector.descriptorForElement(setter)));
}
/**
--- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -67,7 +67,7 @@
public MBeanConstructorInfo(String description, Constructor<?> constructor) {
this(constructor.getName(), description,
constructorSignature(constructor),
- Introspector.descriptorForElement(constructor, false));
+ Introspector.descriptorForElement(constructor));
}
/**
--- a/jdk/src/share/classes/javax/management/MBeanException.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanException.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,8 +25,6 @@
package javax.management;
-import javax.management.openmbean.CompositeData;
-
/**
* Represents "user defined" exceptions thrown by MBean methods
@@ -43,26 +41,6 @@
private static final long serialVersionUID = 4066342430588744142L;
/**
- * @serial This field is null for instances of this class that were
- * produced by its public constructors. It is non-null for instances
- * of this class that represent serialized instances of {@link
- * GenericMBeanException}.
- *
- * @see GenericMBeanException#getErrorCode()
- */
- final String errorCode;
-
- /**
- * @serial This field is null for instances of this class that were
- * produced by its public constructors. It may be non-null for instances
- * of this class that represent serialized instances of {@link
- * GenericMBeanException}.
- *
- * @see GenericMBeanException#getUserData()
- */
- final CompositeData userData;
-
- /**
* @serial Encapsulated {@link Exception}
*/
private java.lang.Exception exception ;
@@ -73,8 +51,9 @@
*
* @param e the wrapped exception.
*/
- public MBeanException(Exception e) {
- this(null, null, null, e);
+ public MBeanException(java.lang.Exception e) {
+ super() ;
+ exception = e ;
}
/**
@@ -84,19 +63,11 @@
* @param e the wrapped exception.
* @param message the detail message.
*/
- public MBeanException(Exception e, String message) {
- this(message, null, null, e);
+ public MBeanException(java.lang.Exception e, String message) {
+ super(message) ;
+ exception = e ;
}
- MBeanException(
- String message, String errorCode, CompositeData userData, Throwable cause) {
- super(message);
- initCause(cause);
- if (cause instanceof Exception)
- this.exception = (Exception) cause;
- this.errorCode = errorCode;
- this.userData = userData;
- }
/**
* Return the actual {@link Exception} thrown.
@@ -108,24 +79,11 @@
}
/**
- * This method is invoked when deserializing instances of this class.
- * If the {@code errorCode} field of the deserialized instance is not
- * null, this method returns an instance of {@link GenericMBeanException}
- * instead. Otherwise it returns {@code this}.
- * @return {@code this}, or a {@code GenericMBeanException}.
+ * Return the actual {@link Exception} thrown.
+ *
+ * @return the wrapped exception.
*/
- Object readResolve() {
- if (errorCode == null) {
- // serial compatibility: earlier versions did not set
- // Throwable.cause because they overrode getCause().
- if (getCause() == null && exception != null)
- initCause(exception);
- return this;
- } else {
- Throwable t = new GenericMBeanException(
- getMessage(), errorCode, userData, getCause());
- t.setStackTrace(this.getStackTrace());
- return t;
- }
+ public Throwable getCause() {
+ return exception;
}
}
--- a/jdk/src/share/classes/javax/management/MBeanInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,7 +25,6 @@
package javax.management;
-import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.io.Serializable;
@@ -38,12 +37,6 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import static javax.management.ImmutableDescriptor.nonNullDescriptor;
/**
@@ -80,50 +73,27 @@
* constructors in that object;
*
* <li>{@link #getAttributes()} returns the list of all attributes
- * whose existence is deduced as follows:
- * <ul>
- * <li>if the Standard MBean is defined with an MBean interface,
- * from <code>get<i>Name</i></code>, <code>is<i>Name</i></code>, or
- * <code>set<i>Name</i></code> methods that conform to the conventions
+ * whose existence is deduced from the presence in the MBean interface
+ * of a <code>get<i>Name</i></code>, <code>is<i>Name</i></code>, or
+ * <code>set<i>Name</i></code> method that conforms to the conventions
* for Standard MBeans;
- * <li>if the Standard MBean is defined with the {@link MBean @MBean} or
- * {@link MXBean @MXBean} annotation on a class, from methods with the
- * {@link ManagedAttribute @ManagedAttribute} annotation;
- * </ul>
*
- * <li>{@link #getOperations()} returns the list of all operations whose
- * existence is deduced as follows:
- * <ul>
- * <li>if the Standard MBean is defined with an MBean interface, from methods in
+ * <li>{@link #getOperations()} returns the list of all methods in
* the MBean interface that do not represent attributes;
- * <li>if the Standard MBean is defined with the {@link MBean @MBean} or
- * {@link MXBean @MXBean} annotation on a class, from methods with the
- * {@link ManagedOperation @ManagedOperation} annotation;
- * </ul>
*
- * <li>{@link #getNotifications()} returns:
- * <ul>
- * <li>if the MBean implements the {@link NotificationBroadcaster} interface,
- * the result of calling {@link
+ * <li>{@link #getNotifications()} returns an empty array if the MBean
+ * does not implement the {@link NotificationBroadcaster} interface,
+ * otherwise the result of calling {@link
* NotificationBroadcaster#getNotificationInfo()} on it;
- * <li>otherwise, if there is a {@link NotificationInfo @NotificationInfo}
- * or {@link NotificationInfos @NotificationInfos} annotation on the
- * MBean interface or <code>@MBean</code> or <code>@MXBean</code>
- * class, the array implied by those annotations;
- * <li>otherwise an empty array;
- * </ul>
*
* <li>{@link #getDescriptor()} returns a descriptor containing the contents
* of any descriptor annotations in the MBean interface (see
- * {@link DescriptorFields @DescriptorFields} and
* {@link DescriptorKey @DescriptorKey}).
*
* </ul>
*
* <p>The description returned by {@link #getDescription()} and the
- * descriptions of the contained attributes and operations are determined
- * by the corresponding {@link Description} annotations if any;
- * otherwise their contents are not specified.</p>
+ * descriptions of the contained attributes and operations are not specified.</p>
*
* <p>The remaining details of the <code>MBeanInfo</code> for a
* Standard MBean are not specified. This includes the description of
@@ -758,377 +728,4 @@
throw new StreamCorruptedException("Got unexpected byte.");
}
}
-
- /**
- * <p>Return an {@code MBeanInfo} object that is the same as this one
- * except that its descriptions are localized in the given locale.
- * This means the text returned by {@link MBeanInfo#getDescription}
- * (the description of the MBean itself), and the text returned by the
- * {@link MBeanFeatureInfo#getDescription getDescription()} method
- * for every {@linkplain MBeanAttributeInfo attribute}, {@linkplain
- * MBeanOperationInfo operation}, {@linkplain MBeanConstructorInfo
- * constructor}, and {@linkplain MBeanNotificationInfo notification}
- * contained in the {@code MBeanInfo}.</p>
- *
- * <p>Here is how the description {@code this.getDescription()} is
- * localized.</p>
- *
- * <p>First, if the {@linkplain #getDescriptor() descriptor}
- * of this {@code MBeanInfo} contains a field <code><a
- * href="Descriptor.html#locale">"locale"</a></code>, and the value of
- * the field is the same as {@code locale.toString()}, then this {@code
- * MBeanInfo} is returned. Otherwise, localization proceeds as follows,
- * and the {@code "locale"} field in the returned {@code MBeanInfo} will
- * be {@code locale.toString()}.
- *
- * <p>A <em>{@code className}</em> is determined. If this
- * {@code MBeanInfo} contains a descriptor with the field
- * <a href="Descriptor.html#interfaceClassName">{@code
- * "interfaceClassName"}</a>, then the value of that field is the
- * {@code className}. Otherwise, it is {@link #getClassName()}.
- * Everything before the last period (.) in the {@code className} is
- * the <em>{@code package}</em>, and everything after is the <em>{@code
- * simpleClassName}</em>. (If there is no period, then the {@code package}
- * is empty and the {@code simpleClassName} is the same as the {@code
- * className}.)</p>
- *
- * <p>A <em>{@code resourceKey}</em> is determined. If this {@code
- * MBeanInfo} contains a {@linkplain MBeanInfo#getDescriptor() descriptor}
- * with a field {@link JMX#DESCRIPTION_RESOURCE_KEY_FIELD
- * "descriptionResourceKey"}, the value of the field is
- * the {@code resourceKey}. Otherwise, the {@code resourceKey} is {@code
- * simpleClassName + ".mbean"}.</p>
- *
- * <p>A <em>{@code resourceBundleBaseName}</em> is determined. If
- * this {@code MBeanInfo} contains a descriptor with a field {@link
- * JMX#DESCRIPTION_RESOURCE_BUNDLE_BASE_NAME_FIELD
- * "descriptionResourceBundleBaseName"}, the value of the field
- * is the {@code resourceBundleBaseName}. Otherwise, the {@code
- * resourceBundleBaseName} is {@code package + ".MBeanDescriptions"}.
- *
- * <p>Then, a {@link java.util.ResourceBundle ResourceBundle} is
- * determined, using<br> {@link java.util.ResourceBundle#getBundle(String,
- * Locale, ClassLoader) ResourceBundle.getBundle(resourceBundleBaseName,
- * locale, loader)}. If this succeeds, and if {@link
- * java.util.ResourceBundle#getString(String) getString(resourceKey)}
- * returns a string, then that string is the localized description.
- * Otherwise, the original description is unchanged.</p>
- *
- * <p>A localized description for an {@code MBeanAttributeInfo} is
- * obtained similarly. The default {@code resourceBundleBaseName}
- * is the same as above. The default description and the
- * descriptor fields {@code "descriptionResourceKey"} and {@code
- * "descriptionResourceBundleBaseName"} come from the {@code
- * MBeanAttributeInfo} rather than the {@code MBeanInfo}. If the
- * attribute's {@linkplain MBeanFeatureInfo#getName() name} is {@code
- * Foo} then its default {@code resourceKey} is {@code simpleClassName +
- * ".attribute.Foo"}.</p>
- *
- * <p>Similar rules apply for operations, constructors, and notifications.
- * If the name of the operation, constructor, or notification is {@code
- * Foo} then the default {@code resourceKey} is respectively {@code
- * simpleClassName + ".operation.Foo"}, {@code simpleClassName +
- * ".constructor.Foo"}, or {@code simpleClassName + ".notification.Foo"}.
- * If two operations or constructors have the same name (overloading) then
- * they have the same default {@code resourceKey}; if different localized
- * descriptions are needed then a non-default key must be supplied using
- * {@code "descriptionResourceKey"}.</p>
- *
- * <p>Similar rules also apply for descriptions of parameters ({@link
- * MBeanParameterInfo}). The default {@code resourceKey} for a parameter
- * whose {@linkplain MBeanFeatureInfo#getName() name} is {@code
- * Bar} in an operation or constructor called {@code Foo} is {@code
- * simpleClassName + ".operation.Foo.Bar"} or {@code simpleClassName +
- * ".constructor.Foo.Bar"} respectively.</p>
- *
- * <h4>Example</h4>
- *
- * <p>Suppose you have an MBean defined by these two Java source files:</p>
- *
- * <pre>
- * // ConfigurationMBean.java
- * package com.example;
- * public interface ConfigurationMBean {
- * public String getName();
- * public void save(String fileName);
- * }
- *
- * // Configuration.java
- * package com.example;
- * public class Configuration implements ConfigurationMBean {
- * public Configuration(String defaultName) {
- * ...
- * }
- * ...
- * }
- * </pre>
- *
- * <p>Then you could define the default descriptions for the MBean, by
- * including a resource bundle called {@code com/example/MBeanDescriptions}
- * with the compiled classes. Most often this is done by creating a file
- * {@code MBeanDescriptions.properties} in the same directory as {@code
- * ConfigurationMBean.java}. Make sure that this file is copied into the
- * same place as the compiled classes; in typical build environments that
- * will be true by default.</p>
- *
- * <p>The file {@code com/example/MBeanDescriptions.properties} might
- * look like this:</p>
- *
- * <pre>
- * # Description of the MBean
- * ConfigurationMBean.mbean = Configuration manager
- *
- * # Description of the Name attribute
- * ConfigurationMBean.attribute.Name = The name of the configuration
- *
- * # Description of the save operation
- * ConfigurationMBean.operation.save = Save the configuration to a file
- *
- * # Description of the parameter to the save operation.
- * # Parameter names from the original Java source are not available,
- * # so the default names are p1, p2, etc. If the names were available,
- * # this would be ConfigurationMBean.operation.save.fileName
- * ConfigurationMBean.operation.save.p1 = The name of the file
- *
- * # Description of the constructor. The default name of a constructor is
- * # its fully-qualified class name.
- * ConfigurationMBean.constructor.com.example.Configuration = <!--
- * -->Constructor with name of default file
- * # Description of the constructor parameter.
- * ConfigurationMBean.constructor.com.example.Configuration.p1 = <!--
- * -->Name of the default file
- * </pre>
- *
- * <p>Starting with this file, you could create descriptions for the French
- * locale by creating {@code com/example/MBeanDescriptions_fr.properties}.
- * The keys in this file are the same as before but the text has been
- * translated:
- *
- * <pre>
- * ConfigurationMBean.mbean = Gestionnaire de configuration
- *
- * ConfigurationMBean.attribute.Name = Le nom de la configuration
- *
- * ConfigurationMBean.operation.save = Sauvegarder la configuration <!--
- * -->dans un fichier
- *
- * ConfigurationMBean.operation.save.p1 = Le nom du fichier
- *
- * ConfigurationMBean.constructor.com.example.Configuration = <!--
- * -->Constructeur avec nom du fichier par défaut
- * ConfigurationMBean.constructor.com.example.Configuration.p1 = <!--
- * -->Nom du fichier par défaut
- * </pre>
- *
- * <p>The descriptions in {@code MBeanDescriptions.properties} and
- * {@code MBeanDescriptions_fr.properties} will only be consulted if
- * {@code localizeDescriptions} is called, perhaps because the
- * MBean Server has been wrapped by {@link
- * ClientContext#newLocalizeMBeanInfoForwarder} or because the
- * connector server has been created with the {@link
- * javax.management.remote.JMXConnectorServer#LOCALIZE_MBEAN_INFO_FORWARDER
- * LOCALIZE_MBEAN_INFO_FORWARDER} option. If you want descriptions
- * even when there is no localization step, then you should consider
- * using {@link Description @Description} annotations. Annotations
- * provide descriptions by default but are overridden if {@code
- * localizeDescriptions} is called.</p>
- *
- * @param locale the target locale for descriptions. Cannot be null.
- *
- * @param loader the {@code ClassLoader} to use for looking up resource
- * bundles.
- *
- * @return an {@code MBeanInfo} with descriptions appropriately localized.
- *
- * @throws NullPointerException if {@code locale} is null.
- */
- public MBeanInfo localizeDescriptions(Locale locale, ClassLoader loader) {
- if (locale == null)
- throw new NullPointerException("locale");
- Descriptor d = getDescriptor();
- String mbiLocaleString = (String) d.getFieldValue(JMX.LOCALE_FIELD);
- if (locale.toString().equals(mbiLocaleString))
- return this;
- return new Rewriter(this, locale, loader).getMBeanInfo();
- }
-
- private static class Rewriter {
- private final MBeanInfo mbi;
- private final ClassLoader loader;
- private final Locale locale;
- private final String packageName;
- private final String simpleClassNamePlusDot;
- private ResourceBundle defaultBundle;
- private boolean defaultBundleLoaded;
-
- // ResourceBundle.getBundle throws NullPointerException
- // if the loader is null, even though that is perfectly
- // valid and means the bootstrap loader. So we work
- // around with a ClassLoader that is equivalent to the
- // bootstrap loader but is not null.
- private static final ClassLoader bootstrapLoader =
- new ClassLoader(null) {};
-
- Rewriter(MBeanInfo mbi, Locale locale, ClassLoader loader) {
- this.mbi = mbi;
- this.locale = locale;
- if (loader == null)
- loader = bootstrapLoader;
- this.loader = loader;
-
- String intfName = (String)
- mbi.getDescriptor().getFieldValue("interfaceClassName");
- if (intfName == null)
- intfName = mbi.getClassName();
- int lastDot = intfName.lastIndexOf('.');
- this.packageName = intfName.substring(0, lastDot + 1);
- this.simpleClassNamePlusDot = intfName.substring(lastDot + 1) + ".";
- // Inner classes show up as Outer$Inner so won't match the dot.
- // When there is no dot, lastDot is -1,
- // packageName is empty, and simpleClassNamePlusDot is intfName.
- }
-
- MBeanInfo getMBeanInfo() {
- MBeanAttributeInfo[] mbais =
- rewrite(mbi.getAttributes(), "attribute.");
- MBeanOperationInfo[] mbois =
- rewrite(mbi.getOperations(), "operation.");
- MBeanConstructorInfo[] mbcis =
- rewrite(mbi.getConstructors(), "constructor.");
- MBeanNotificationInfo[] mbnis =
- rewrite(mbi.getNotifications(), "notification.");
- Descriptor d = mbi.getDescriptor();
- d = changeLocale(d);
- String description = getDescription(d, "mbean", "");
- if (description == null)
- description = mbi.getDescription();
- return new MBeanInfo(
- mbi.getClassName(), description,
- mbais, mbcis, mbois, mbnis, d);
- }
-
- private Descriptor changeLocale(Descriptor d) {
- if (d.getFieldValue(JMX.LOCALE_FIELD) != null) {
- Map<String, Object> map = new HashMap<String, Object>();
- for (String field : d.getFieldNames())
- map.put(field, d.getFieldValue(field));
- map.remove(JMX.LOCALE_FIELD);
- d = new ImmutableDescriptor(map);
- }
- return ImmutableDescriptor.union(
- d, new ImmutableDescriptor(JMX.LOCALE_FIELD + "=" + locale));
- }
-
- private String getDescription(
- Descriptor d, String defaultPrefix, String defaultSuffix) {
- ResourceBundle bundle = bundleFromDescriptor(d);
- if (bundle == null)
- return null;
- String key =
- (String) d.getFieldValue(JMX.DESCRIPTION_RESOURCE_KEY_FIELD);
- if (key == null)
- key = simpleClassNamePlusDot + defaultPrefix + defaultSuffix;
- return descriptionFromResource(bundle, key);
- }
-
- private <T extends MBeanFeatureInfo> T[] rewrite(
- T[] features, String resourcePrefix) {
- for (int i = 0; i < features.length; i++) {
- T feature = features[i];
- Descriptor d = feature.getDescriptor();
- String description =
- getDescription(d, resourcePrefix, feature.getName());
- if (description != null &&
- !description.equals(feature.getDescription())) {
- features[i] = setDescription(feature, description);
- }
- }
- return features;
- }
-
- private <T extends MBeanFeatureInfo> T setDescription(
- T feature, String description) {
-
- Object newf;
- String name = feature.getName();
- Descriptor d = feature.getDescriptor();
-
- if (feature instanceof MBeanAttributeInfo) {
- MBeanAttributeInfo mbai = (MBeanAttributeInfo) feature;
- newf = new MBeanAttributeInfo(
- name, mbai.getType(), description,
- mbai.isReadable(), mbai.isWritable(), mbai.isIs(),
- d);
- } else if (feature instanceof MBeanOperationInfo) {
- MBeanOperationInfo mboi = (MBeanOperationInfo) feature;
- MBeanParameterInfo[] sig = rewrite(
- mboi.getSignature(), "operation." + name + ".");
- newf = new MBeanOperationInfo(
- name, description, sig,
- mboi.getReturnType(), mboi.getImpact(), d);
- } else if (feature instanceof MBeanConstructorInfo) {
- MBeanConstructorInfo mbci = (MBeanConstructorInfo) feature;
- MBeanParameterInfo[] sig = rewrite(
- mbci.getSignature(), "constructor." + name + ".");
- newf = new MBeanConstructorInfo(
- name, description, sig, d);
- } else if (feature instanceof MBeanNotificationInfo) {
- MBeanNotificationInfo mbni = (MBeanNotificationInfo) feature;
- newf = new MBeanNotificationInfo(
- mbni.getNotifTypes(), name, description, d);
- } else if (feature instanceof MBeanParameterInfo) {
- MBeanParameterInfo mbpi = (MBeanParameterInfo) feature;
- newf = new MBeanParameterInfo(
- name, mbpi.getType(), description, d);
- } else {
- logger().log(Level.FINE, "Unknown feature type: " +
- feature.getClass());
- newf = feature;
- }
-
- return Util.<T>cast(newf);
- }
-
- private ResourceBundle bundleFromDescriptor(Descriptor d) {
- String bundleName = (String) d.getFieldValue(
- JMX.DESCRIPTION_RESOURCE_BUNDLE_BASE_NAME_FIELD);
-
- if (bundleName != null)
- return getBundle(bundleName);
-
- if (defaultBundleLoaded)
- return defaultBundle;
-
- bundleName = packageName + "MBeanDescriptions";
- defaultBundle = getBundle(bundleName);
- defaultBundleLoaded = true;
- return defaultBundle;
- }
-
- private String descriptionFromResource(
- ResourceBundle bundle, String key) {
- try {
- return bundle.getString(key);
- } catch (MissingResourceException e) {
- logger().log(Level.FINEST, "No resource for " + key, e);
- } catch (Exception e) {
- logger().log(Level.FINE, "Bad resource for " + key, e);
- }
- return null;
- }
-
- private ResourceBundle getBundle(String name) {
- try {
- return ResourceBundle.getBundle(name, locale, loader);
- } catch (Exception e) {
- logger().log(Level.FINE,
- "Could not load ResourceBundle " + name, e);
- return null;
- }
- }
-
- private Logger logger() {
- return Logger.getLogger("javax.management.locale");
- }
- }
}
--- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -48,28 +48,24 @@
/**
* Indicates that the operation is read-like:
* it returns information but does not change any state.
- * @see Impact#INFO
*/
public static final int INFO = 0;
/**
* Indicates that the operation is write-like: it has an effect but does
* not return any information from the MBean.
- * @see Impact#ACTION
*/
public static final int ACTION = 1;
/**
* Indicates that the operation is both read-like and write-like:
* it has an effect, and it also returns information from the MBean.
- * @see Impact#ACTION_INFO
*/
public static final int ACTION_INFO = 2;
/**
* Indicates that the impact of the operation is unknown or cannot be
* expressed using one of the other values.
- * @see Impact#UNKNOWN
*/
public static final int UNKNOWN = 3;
@@ -113,7 +109,7 @@
methodSignature(method),
method.getReturnType().getName(),
UNKNOWN,
- Introspector.descriptorForElement(method, false));
+ Introspector.descriptorForElement(method));
}
/**
@@ -185,6 +181,7 @@
* <p>Since this class is immutable, cloning is chiefly of interest
* to subclasses.</p>
*/
+ @Override
public Object clone () {
try {
return super.clone() ;
@@ -257,6 +254,7 @@
return impact;
}
+ @Override
public String toString() {
String impactString;
switch (getImpact()) {
@@ -288,6 +286,7 @@
* to those of this MBeanConstructorInfo. Two signature arrays
* are equal if their elements are pairwise equal.
*/
+ @Override
public boolean equals(Object o) {
if (o == this)
return true;
@@ -327,14 +326,9 @@
for (int i = 0; i < classes.length; i++) {
Descriptor d = Introspector.descriptorForAnnotations(annots[i]);
- String description = Introspector.descriptionForParameter(annots[i]);
- if (description == null)
- description = "";
- String name = Introspector.nameForParameter(annots[i]);
- if (name == null)
- name = "p" + (i + 1);
- params[i] = new MBeanParameterInfo(
- name, classes[i].getName(), description, d);
+ final String pn = "p" + (i + 1);
+ params[i] =
+ new MBeanParameterInfo(pn, classes[i].getName(), "", d);
}
return params;
--- a/jdk/src/share/classes/javax/management/MBeanPermission.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanPermission.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,7 +25,6 @@
package javax.management;
-import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.Permission;
@@ -46,7 +45,7 @@
* allowed if the permissions you have {@linkplain #implies imply} the
* permission you need.</p>
*
- * <p>An MBeanPermission contains five items of information:</p>
+ * <p>An MBeanPermission contains four items of information:</p>
*
* <ul>
*
@@ -58,23 +57,6 @@
*
* <p>The action is returned by {@link #getActions()}.</p>
*
- * <li id="MBeanServerName"><p>The <em>MBean Server name</em>.</p>
- *
- * <p>For a permission you need, this is the {@linkplain
- * javax.management.MBeanServerFactory#getMBeanServerName
- * name of the MBeanServer}
- * containing the <a href="#MBeanName">MBean</a> for which the MBean
- * permission is checked.</p>
- *
- * <p>For a permission you have, this is either the {@linkplain
- * javax.management.MBeanServerFactory#getMBeanServerName
- * name of the MBeanServer} in which the <a href="#MBeanName">MBean</a>
- * you have this permission for must be registered,
- * or a pattern against which that MBean Server name will be matched.<br>
- * An {@code mbeanServerName} pattern can also be empty or the single
- * character {@code "*"}, both of which will match any {@code MBeanServer} name.
- * </p>
- *
* <li><p>The <em>class name</em>.</p>
*
* <p>For a permission you need, this is the class name of an MBean
@@ -121,15 +103,15 @@
* </ul>
*
* <p>If you have an MBeanPermission, it allows operations only if all
- * five of the items match.</p>
+ * four of the items match.</p>
*
- * <p>The MBean Server name, class name, member, and object name can be written
- * together as a single string, which is the <em>name</em> of this permission.
+ * <p>The class name, member, and object name can be written together
+ * as a single string, which is the <em>name</em> of this permission.
* The name of the permission is the string returned by {@link
* Permission#getName() getName()}. The format of the string is:</p>
*
* <blockquote>
- * <code>mbeanServerName::className#member[objectName]</code>
+ * <code>className#member[objectName]</code>
* </blockquote>
*
* <p>The object name is written using the usual syntax for {@link
@@ -137,18 +119,15 @@
* <code>]</code>. It is terminated by a <code>]</code> character
* that is the last character in the string.</p>
*
- * <p>One or more of the <code>mbeanServerName</code>, <code>className</code>,
- * <code>member</code>, or <code>objectName</code> may be omitted. If the
- * <code>mbeanServerName</code> is omitted, the <code>::</code> may be too (but
- * does not have to be).
- * If the <code>member</code> is omitted, the <code>#</code> may be too (but
+ * <p>One or more of the <code>className</code>, <code>member</code>,
+ * or <code>objectName</code> may be omitted. If the
+ * <code>member</code> is omitted, the <code>#</code> may be too (but
* does not have to be). If the <code>objectName</code> is omitted,
* the <code>[]</code> may be too (but does not have to be). It is
- * not legal to omit all four items, that is to have a <em>name</em>
+ * not legal to omit all three items, that is to have a <em>name</em>
* that is the empty string.</p>
*
- * <p>One or more of the <code>mbeanServerName</code>, <code>className</code>,
- * <code>member</code>,
+ * <p>One or more of the <code>className</code>, <code>member</code>,
* or <code>objectName</code> may be the character "<code>-</code>",
* which is equivalent to a null value. A null value is implied by
* any value (including another null value) but does not imply any
@@ -268,13 +247,6 @@
private transient ObjectName objectName;
/**
- * The name of the MBeanServer in which this permission is checked, or
- * granted. If null, is implied by any MBean Server name
- * but does not imply any non-null MBean Server name.
- */
- private transient String mbeanServerName;
-
- /**
* Parse <code>actions</code> parameter.
*/
private void parseActions() {
@@ -311,13 +283,6 @@
throw new IllegalArgumentException("MBeanPermission name " +
"cannot be empty");
- final int sepIndex = name.indexOf("::");
- if (sepIndex < 0) {
- setMBeanServerName("*");
- } else {
- setMBeanServerName(name.substring(0,sepIndex));
- }
-
/* The name looks like "class#member[objectname]". We subtract
elements from the right as we parse, so after parsing the
objectname we have "class#member" and after parsing the
@@ -325,14 +290,11 @@
// Parse ObjectName
-
- final int start = (sepIndex<0)?0:sepIndex+2;
- int openingBracket = name.indexOf("[",start);
+ int openingBracket = name.indexOf("[");
if (openingBracket == -1) {
// If "[on]" missing then ObjectName("*:*")
//
objectName = ObjectName.WILDCARD;
- name = name.substring(start);
} else {
if (!name.endsWith("]")) {
throw new IllegalArgumentException("MBeanPermission: " +
@@ -343,11 +305,11 @@
} else {
// Create ObjectName
//
- String on = name.substring(openingBracket + 1,
- name.length() - 1);
try {
// If "[]" then ObjectName("*:*")
//
+ String on = name.substring(openingBracket + 1,
+ name.length() - 1);
if (on.equals(""))
objectName = ObjectName.WILDCARD;
else if (on.equals("-"))
@@ -362,7 +324,7 @@
}
}
- name = name.substring(start, openingBracket);
+ name = name.substring(0, openingBracket);
}
// Parse member
@@ -386,9 +348,8 @@
* Assign fields based on className, member, and objectName
* parameters.
*/
- private void initName(String mbeanServerName, String className,
- String member, ObjectName objectName) {
- setMBeanServerName(mbeanServerName);
+ private void initName(String className, String member,
+ ObjectName objectName) {
setClassName(className);
setMember(member);
this.objectName = objectName;
@@ -420,30 +381,19 @@
this.member = member;
}
- private void setMBeanServerName(String mbeanServerName) {
- if (mbeanServerName == null || mbeanServerName.equals("-")) {
- this.mbeanServerName = null;
- } else if (mbeanServerName.equals("")) {
- this.mbeanServerName = "*";
- } else {
- this.mbeanServerName = mbeanServerName;
- }
- }
-
-
/**
* <p>Create a new MBeanPermission object with the specified target name
* and actions.</p>
*
* <p>The target name is of the form
- * "<code>mbeanServerName::className#member[objectName]</code>" where
- * each part is optional. It must not be empty or null.</p>
+ * "<code>className#member[objectName]</code>" where each part is
+ * optional. It must not be empty or null.</p>
*
* <p>The actions parameter contains a comma-separated list of the
* desired actions granted on the target name. It must not be
* empty or null.</p>
*
- * @param name the quadruplet "mbeanServerName::className#member[objectName]".
+ * @param name the triplet "className#member[objectName]".
* @param actions the action string.
*
* @exception IllegalArgumentException if the <code>name</code> or
@@ -468,12 +418,6 @@
* optional. This will be the result of {@link #getName()} on the
* resultant MBeanPermission.</p>
*
- * <p>This corresponds to a permission granted for all
- * MBean servers present in the JVM and is equivalent to
- * {@link #MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission("*",className,member,objectName,actions)}.
- * </p>
- *
* <p>The actions parameter contains a comma-separated list of the
* desired actions granted on the target name. It must not be
* empty or null.</p>
@@ -495,67 +439,17 @@
String member,
ObjectName objectName,
String actions) {
- this("*",className,member,objectName,actions);
- }
- /**
- * <p>Create a new MBeanPermission object with the specified target name
- * (MBean Server name, class name, member, object name) and actions.</p>
- *
- * <p>The MBean Server name, class name, member and object name
- * parameters define a target name of the form
- * "<code>mbeanServerName::className#member[objectName]</code>" where each
- * part is optional. This will be the result of {@link #getName()} on the
- * resultant MBeanPermission.
- * If the <code>mbeanServerName</code> is empty or exactly {@code "*"}, then
- * "{@code mbeanServerName::}" is omitted in that result.
- * </p>
- *
- * <p>The actions parameter contains a comma-separated list of the
- * desired actions granted on the target name. It must not be
- * empty or null.</p>
- *
- * @param mbeanServerName the name of the {@code MBeanServer} to which this
- * permission applies.
- * May be null or <code>"-"</code>, which represents an MBeanServer name
- * that is implied by any MBeanServer name but does not imply any other
- * MBeanServer name.
- * @param className the class name to which this permission applies.
- * May be null or <code>"-"</code>, which represents a class name
- * that is implied by any class name but does not imply any other
- * class name.
- * @param member the member to which this permission applies. May
- * be null or <code>"-"</code>, which represents a member that is
- * implied by any member but does not imply any other member.
- * @param objectName the object name to which this permission
- * applies. May be null, which represents an object name that is
- * implied by any object name but does not imply any other object
- * name.
- * @param actions the action string.
- *
- * @since 1.7
- */
- public MBeanPermission(String mbeanServerName,
- String className,
- String member,
- ObjectName objectName,
- String actions) {
-
- super(makeName(mbeanServerName,className, member, objectName));
- initName(mbeanServerName,className, member, objectName);
+ super(makeName(className, member, objectName));
+ initName(className, member, objectName);
this.actions = actions;
parseActions();
}
- private static String makeName(String mbeanServerName, String className,
- String member,
+ private static String makeName(String className, String member,
ObjectName objectName) {
final StringBuilder name = new StringBuilder();
- if (mbeanServerName == null)
- mbeanServerName = "-";
- if (!mbeanServerName.equals("") && !mbeanServerName.equals("*"))
- name.append(mbeanServerName).append("::");
if (className == null)
className = "-";
name.append(className);
@@ -1097,9 +991,6 @@
*
* <li> <i>p</i> is an instance of MBeanPermission; and</li>
*
- * <li> <i>p</i> has a null mbeanServerName or <i>p</i>'s mbeanServerName
- * matches this object's mbeanServerName; and</li>
- *
* <li> <i>p</i> has a null className or <i>p</i>'s className
* matches this object's className; and</li>
*
@@ -1113,13 +1004,6 @@
*
* </ul>
*
- * <p>If this object's mbeanServerName is a pattern, then <i>p</i>'s
- * mbeanServerName is matched against that pattern. An empty
- * mbeanServerName is equivalent to "{@code *}". A null
- * mbeanServerName is equivalent to "{@code -}".</p>
- * <p>If this object's mbeanServerName is "<code>*</code>" or is
- * empty, <i>p</i>'s mbeanServerName always matches it.</p>
- *
* <p>If this object's className is "<code>*</code>", <i>p</i>'s
* className always matches it. If it is "<code>a.*</code>", <i>p</i>'s
* className matches it if it begins with "<code>a.</code>".</p>
@@ -1166,12 +1050,6 @@
// Target name
//
- // The 'mbeanServerName' check is true iff:
- // 1) the mbeanServerName in 'this' permission is omitted or "*", or
- // 2) the mbeanServerName in 'that' permission is omitted or "*", or
- // 3) the mbeanServerName in 'this' permission does pattern
- // matching with the mbeanServerName in 'that' permission.
- //
// The 'className' check is true iff:
// 1) the className in 'this' permission is omitted or "*", or
// 2) the className in 'that' permission is omitted or "*", or
@@ -1198,17 +1076,6 @@
expect that "that" contains a wildcard, since it is a
needed permission. So we assume that.classNameExactMatch. */
- if (that.mbeanServerName == null) {
- // bottom is implied
- } else if (this.mbeanServerName == null) {
- // bottom implies nothing but itself
- return false;
- } else if (that.mbeanServerName.equals(this.mbeanServerName)) {
- // exact match
- } else if (!Util.wildmatch(that.mbeanServerName,this.mbeanServerName)) {
- return false; // no match
- }
-
if (that.classNamePrefix == null) {
// bottom is implied
} else if (this.classNamePrefix == null) {
--- a/jdk/src/share/classes/javax/management/MBeanRegistration.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanRegistration.java Wed Oct 21 16:50:44 2009 +0100
@@ -33,99 +33,6 @@
* to get a reference to the MBean Server and/or its name within that
* MBean Server.</p>
*
- * <h4 id="injection">Resource injection</h4>
- *
- * <p>As an alternative to implementing {@code MBeanRegistration}, if all that
- * is needed is the MBean Server or ObjectName then an MBean can use
- * <em>resource injection</em>.</p>
- *
- * <p>If a field in the MBean object has type {@link ObjectName} and has
- * the {@link javax.annotation.Resource @Resource} annotation,
- * then the {@code ObjectName} under which the MBean is registered is
- * assigned to that field during registration. Likewise, if a field has type
- * {@link MBeanServer} and the <code>@Resource</code> annotation, then it will
- * be set to the {@code MBeanServer} in which the MBean is registered.</p>
- *
- * <p>For example:</p>
- *
- * <pre>
- * public Configuration implements ConfigurationMBean {
- * @Resource
- * private volatile MBeanServer mbeanServer;
- * @Resource
- * private volatile ObjectName objectName;
- * ...
- * void unregisterSelf() throws Exception {
- * mbeanServer.unregisterMBean(objectName);
- * }
- * }
- * </pre>
- *
- * <p>Resource injection can also be used on fields of type
- * {@link SendNotification} to simplify notification sending. Such a field
- * will get a reference to an object of type {@code SendNotification} when
- * the MBean is registered, and it can use this reference to send notifications.
- * For example:</p>
- *
- * <pre>
- * public Configuration implements ConfigurationMBean {
- * @Resource
- * private volatile SendNotification sender;
- * ...
- * private void updated() {
- * Notification n = new Notification(...);
- * sender.sendNotification(n);
- * }
- * }
- * </pre>
- *
- * <p>(Listeners may be invoked in the same thread as the caller of
- * {@code sender.sendNotification}.)</p>
- *
- * <p>A field to be injected must not be static. It is recommended that
- * such fields be declared {@code volatile}.</p>
- *
- * <p>It is also possible to use the <code>@Resource</code> annotation on
- * methods. Such a method must have a {@code void} return type and a single
- * argument of the appropriate type, for example {@code ObjectName}.</p>
- *
- * <p>Any number of fields and methods may have the <code>@Resource</code>
- * annotation. All fields and methods with type {@code ObjectName}
- * (for example) will receive the same {@code ObjectName} value.</p>
- *
- * <p>Resource injection is available for all types of MBeans, not just
- * Standard MBeans.</p>
- *
- * <p>If an MBean implements the {@link DynamicWrapperMBean} interface then
- * resource injection happens on the object returned by that interface's
- * {@link DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method
- * rather than on the MBean object itself.
- *
- * <p>Resource injection happens after the {@link #preRegister preRegister}
- * method is called (if any), and before the MBean is actually registered
- * in the MBean Server. If a <code>@Resource</code> method throws
- * an exception, the effect is the same as if {@code preRegister} had
- * thrown the exception. In particular it will prevent the MBean from being
- * registered.</p>
- *
- * <p>Resource injection can be used on a field or method where the type
- * is a parent of the injected type, if the injected type is explicitly
- * specified in the <code>@Resource</code> annotation. For example:</p>
- *
- * <pre>
- * @Resource(type = MBeanServer.class)
- * private volatile MBeanServerConnection mbsc;
- * </pre>
- *
- * <p>Formally, suppose <em>R</em> is the type in the <code>@Resource</code>
- * annotation and <em>T</em> is the type of the method parameter or field.
- * Then one of <em>R</em> and <em>T</em> must be a subtype of the other
- * (or they must be the same type). Injection happens if this subtype
- * is {@code MBeanServer}, {@code ObjectName}, or {@code SendNotification}.
- * Otherwise the <code>@Resource</code> annotation is ignored.</p>
- *
- * <p>Resource injection in MBeans is new in version 2.0 of the JMX API.</p>
- *
* @since 1.5
*/
public interface MBeanRegistration {
@@ -196,7 +103,7 @@
* <p>If the implementation of this method throws a {@link RuntimeException}
* or an {@link Error}, the MBean Server will rethrow those inside
* a {@link RuntimeMBeanException} or {@link RuntimeErrorException},
- * respectively. However, throwing an excepption in {@code postDeregister}
+ * respectively. However, throwing an exception in {@code postDeregister}
* will not change the state of the MBean:
* the MBean was already successfully deregistered and will remain so. </p>
* <p>This might be confusing for the code calling
--- a/jdk/src/share/classes/javax/management/MBeanServer.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java Wed Oct 21 16:50:44 2009 +0100
@@ -61,13 +61,9 @@
* <CODE>ObjectName</CODE> is: <BR>
* <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.</p>
*
- * <p id="security">An object obtained from the {@link
- * MBeanServerFactory#createMBeanServer(String) createMBeanServer}, {@link
- * MBeanServerFactory#createNamedMBeanServer(String,String) createNamedMBeanServer},
- * {@link
- * MBeanServerFactory#newMBeanServer(String) newMBeanServer}, or
- * {@link
- * MBeanServerFactory#newNamedMBeanServer(String,String) newNamedMBeanServer}
+ * <p>An object obtained from the {@link
+ * MBeanServerFactory#createMBeanServer(String) createMBeanServer} or
+ * {@link MBeanServerFactory#newMBeanServer(String) newMBeanServer}
* methods of the {@link MBeanServerFactory} class applies security
* checks to its methods, as follows.</p>
*
@@ -77,26 +73,10 @@
*
* <p>Assuming that there is a security manager, or that the
* implementation chooses to make checks anyway, the checks are made
- * as detailed below.
- * In what follows, and unless otherwise specified:
- * </p>
- * <ul><li><code>className</code> is the
+ * as detailed below. In what follows, and unless otherwise specified,
+ * {@code className} is the
* string returned by {@link MBeanInfo#getClassName()} for the target
- * MBean,</li>
- * <li>{@code mbeanServerName} is the
- * {@linkplain MBeanServerFactory#getMBeanServerName name of the
- * MBean Server} in which the target MBean is registered. This is the
- * value returned by {@link MBeanServerFactory#getMBeanServerName
- * MBeanServerFactory.getMBeanServerName(MBeanServer)}, and
- * is usually the {@code mbeanServerName} parameter that was supplied
- * to the {@link
- * MBeanServerFactory#createNamedMBeanServer(String,String)
- * createNamedMBeanServer} or {@link
- * MBeanServerFactory#newNamedMBeanServer(String,String) newNamedMBeanServer}
- * methods of the {@link MBeanServerFactory} when the MBeanServer was created,
- * or {@value javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if
- * no name was supplied.
- * </li></ul>
+ * MBean.</p>
*
* <p>If a security check fails, the method throws {@link
* SecurityException}.</p>
@@ -110,87 +90,79 @@
*
* <li><p>For the {@link #invoke invoke} method, the caller's
* permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, operationName, name, "invoke")}.
- * </p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, operationName, name, "invoke")}.</p>
*
* <li><p>For the {@link #getAttribute getAttribute} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, attribute, name,
- * "getAttribute")}.</p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, attribute, name, "getAttribute")}.</p>
*
* <li><p>For the {@link #getAttributes getAttributes} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName,className, null, name, "getAttribute")}.
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "getAttribute")}.
* Additionally, for each attribute <em>a</em> in the {@link
* AttributeList}, if the caller's permissions do not imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, <em>a</em>, name,
- * "getAttribute")}, the
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, <em>a</em>, name, "getAttribute")}, the
* MBean server will behave as if that attribute had not been in the
* supplied list.</p>
*
* <li><p>For the {@link #setAttribute setAttribute} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, attrName, name,
- * "setAttribute")}, where
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, attrName, name, "setAttribute")}, where
* <code>attrName</code> is {@link Attribute#getName()
* attribute.getName()}.</p>
*
* <li><p>For the {@link #setAttributes setAttributes} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name, "setAttribute")}.
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "setAttribute")}.
* Additionally, for each attribute <em>a</em> in the {@link
* AttributeList}, if the caller's permissions do not imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, <em>a</em>, name,
- * "setAttribute")}, the
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, <em>a</em>, name, "setAttribute")}, the
* MBean server will behave as if that attribute had not been in the
* supplied list.</p>
*
* <li><p>For the <code>addNotificationListener</code> methods,
* the caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name,
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name,
* "addNotificationListener")}.</p>
*
* <li><p>For the <code>removeNotificationListener</code> methods,
* the caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name,
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name,
* "removeNotificationListener")}.</p>
*
* <li><p>For the {@link #getMBeanInfo getMBeanInfo} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name, "getMBeanInfo")}.
- * </p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "getMBeanInfo")}.</p>
*
* <li><p>For the {@link #getObjectInstance getObjectInstance} method,
* the caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name,
- * "getObjectInstance")}.</p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "getObjectInstance")}.</p>
*
* <li><p>For the {@link #isInstanceOf isInstanceOf} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name, "isInstanceOf")}.
- * </p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "isInstanceOf")}.</p>
*
* <li><p>For the {@link #queryMBeans queryMBeans} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, null, null, null, "queryMBeans")}.
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(null, null, null, "queryMBeans")}.
* Additionally, for each MBean <em>n</em> that matches <code>name</code>,
* if the caller's permissions do not imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, <em>n</em>, "queryMBeans")},
- * the MBean server will behave as if that MBean did not exist.</p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, <em>n</em>, "queryMBeans")}, the
+ * MBean server will behave as if that MBean did not exist.</p>
*
* <p>Certain query elements perform operations on the MBean server.
* If the caller does not have the required permissions for a given
@@ -208,10 +180,10 @@
*
* <li><p>For the {@link #getDomains getDomains} method, the caller's
* permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, null, null, null, "getDomains")}.
- * Additionally, for each domain <var>d</var> in the returned array, if the
- * caller's permissions do not imply {@link
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(null, null, null, "getDomains")}. Additionally,
+ * for each domain <var>d</var> in the returned array, if the caller's
+ * permissions do not imply {@link
* MBeanPermission#MBeanPermission(String,String,ObjectName,String)
* MBeanPermission(null, null, new ObjectName("<var>d</var>:x=x"),
* "getDomains")}, the domain is eliminated from the array. Here,
@@ -220,22 +192,21 @@
*
* <li><p>For the {@link #getClassLoader getClassLoader} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, loaderName,
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, loaderName,
* "getClassLoader")}.</p>
*
* <li><p>For the {@link #getClassLoaderFor getClassLoaderFor} method,
* the caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, mbeanName,
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, mbeanName,
* "getClassLoaderFor")}.</p>
*
* <li><p>For the {@link #getClassLoaderRepository
* getClassLoaderRepository} method, the caller's permissions must
* imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, null, null, null,
- * "getClassLoaderRepository")}.</p>
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(null, null, null, "getClassLoaderRepository")}.</p>
*
* <li><p>For the deprecated <code>deserialize</code> methods, the
* required permissions are the same as for the methods that replace
@@ -243,15 +214,15 @@
*
* <li><p>For the <code>instantiate</code> methods, the caller's
* permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, null, "instantiate")},
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, null, "instantiate")},
* where {@code className} is the name of the class which is to
* be instantiated.</p>
*
* <li><p>For the {@link #registerMBean registerMBean} method, the
* caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name, "registerMBean")}.
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "registerMBean")}.
*
* <p>If the <code>MBeanPermission</code> check succeeds, the MBean's
* class is validated by checking that its {@link
@@ -271,8 +242,8 @@
*
* <li><p>For the {@link #unregisterMBean unregisterMBean} method,
* the caller's permissions must imply {@link
- * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String)
- * MBeanPermission(mbeanServerName, className, null, name, "unregisterMBean")}.
+ * MBeanPermission#MBeanPermission(String,String,ObjectName,String)
+ * MBeanPermission(className, null, name, "unregisterMBean")}.</p>
* </p>
*
* </ul>
@@ -351,14 +322,11 @@
/**
* <p>Registers a pre-existing object as an MBean with the MBean
- * server. If the object name given is null, the
- * MBean must provide its own name in one or both of two ways: by implementing the {@link
+ * server. If the object name given is null, the MBean must
+ * provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
- * MBeanRegistration#preRegister preRegister} method; or by defining
- * an {@code objectNameTemplate} field in its {@link Descriptor},
- * typically using the {@link ObjectNameTemplate @ObjectNameTemplate}
- * annotation.</p>
+ * MBeanRegistration#preRegister preRegister} method.
*
* <p>If this method successfully registers an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
@@ -764,16 +732,13 @@
ReflectionException;
/**
- * <p>Return the {@link java.lang.ClassLoader} that was used for loading
- * the class of the named MBean. If the MBean implements the {@link
- * DynamicWrapperMBean} interface, then the returned value is the
- * result of the {@link DynamicWrapperMBean#getWrappedClassLoader()}
- * method.</p>
+ * <p>Return the {@link java.lang.ClassLoader} that was used for
+ * loading the class of the named MBean.</p>
*
* @param mbeanName The ObjectName of the MBean.
*
* @return The ClassLoader used for that MBean. If <var>l</var>
- * is the value specified by the rules above, and <var>r</var> is the
+ * is the MBean's actual ClassLoader, and <var>r</var> is the
* returned value, then either:
*
* <ul>
--- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java Wed Oct 21 16:50:44 2009 +0100
@@ -29,7 +29,6 @@
// java import
import java.io.IOException;
import java.util.Set;
-import javax.management.event.NotificationManager;
/**
@@ -40,20 +39,17 @@
*
* @since 1.5
*/
-public interface MBeanServerConnection extends NotificationManager {
+public interface MBeanServerConnection {
/**
* <p>Instantiates and registers an MBean in the MBean server. The
* MBean server will use its {@link
* javax.management.loading.ClassLoaderRepository Default Loader
* Repository} to load the class of the MBean. An object name is
* associated with the MBean. If the object name given is null, the
- * MBean must provide its own name in one or both of two ways: by implementing the {@link
+ * MBean must provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
- * MBeanRegistration#preRegister preRegister} method; or by defining
- * an {@code objectNameTemplate} field in its {@link Descriptor},
- * typically using the {@link ObjectNameTemplate @ObjectNameTemplate}
- * annotation.</p>
+ * MBeanRegistration#preRegister preRegister} method.</p>
*
* <p>This method is equivalent to {@link
* #createMBean(String,ObjectName,Object[],String[])
@@ -122,14 +118,11 @@
* class loader to be used is identified by its object name. An
* object name is associated with the MBean. If the object name of
* the loader is null, the ClassLoader that loaded the MBean
- * server will be used. If the object name given is null, the
- * MBean must provide its own name in one or both of two ways: by implementing the {@link
+ * server will be used. If the MBean's object name given is null,
+ * the MBean must provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
- * MBeanRegistration#preRegister preRegister} method; or by defining
- * an {@code objectNameTemplate} field in its {@link Descriptor},
- * typically using the {@link ObjectNameTemplate @ObjectNameTemplate}
- * annotation.</p>
+ * MBeanRegistration#preRegister preRegister} method.</p>
*
* <p>This method is equivalent to {@link
* #createMBean(String,ObjectName,ObjectName,Object[],String[])
@@ -205,13 +198,10 @@
* javax.management.loading.ClassLoaderRepository Default Loader
* Repository} to load the class of the MBean. An object name is
* associated with the MBean. If the object name given is null, the
- * MBean must provide its own name in one or both of two ways: by implementing the {@link
+ * MBean must provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
- * MBeanRegistration#preRegister preRegister} method; or by defining
- * an {@code objectNameTemplate} field in its {@link Descriptor},
- * typically using the {@link ObjectNameTemplate @ObjectNameTemplate}
- * annotation.</p>
+ * MBeanRegistration#preRegister preRegister} method.
*
* @param className The class name of the MBean to be instantiated.
* @param name The object name of the MBean. May be null.
@@ -280,14 +270,11 @@
* class loader to be used is identified by its object name. An
* object name is associated with the MBean. If the object name of
* the loader is not specified, the ClassLoader that loaded the
- * MBean server will be used. If the object name given is null, the
- * MBean must provide its own name in one or both of two ways: by implementing the {@link
- * javax.management.MBeanRegistration MBeanRegistration} interface
- * and returning the name from the {@link
- * MBeanRegistration#preRegister preRegister} method; or by defining
- * an {@code objectNameTemplate} field in its {@link Descriptor},
- * typically using the {@link ObjectNameTemplate @ObjectNameTemplate}
- * annotation.</p>
+ * MBean server will be used. If the MBean object name given is
+ * null, the MBean must provide its own name by implementing the
+ * {@link javax.management.MBeanRegistration MBeanRegistration}
+ * interface and returning the name from the {@link
+ * MBeanRegistration#preRegister preRegister} method.
*
* @param className The class name of the MBean to be instantiated.
* @param name The object name of the MBean. May be null.
@@ -436,17 +423,7 @@
* 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. ObjectName patterns that may be contained in the
- * query expression will be
- * <a href="namespace/package-summary.html#NamespaceAndQueries"><!--
- * -->evaluated</a> 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
- * <a href="namespace/package-summary.html#RejectedNamespacePatterns"><!--
- * -->namespaces documentation</a> for more details.
+ * selecting MBeans.
*
* @return A set containing the <CODE>ObjectInstance</CODE>
* objects for the selected MBeans. If no MBean satisfies the
@@ -454,11 +431,6 @@
*
* @exception IOException A communication problem occurred when
* talking to the MBean server.
- * @exception RuntimeOperationsException Wraps a
- * <CODE>java.lang.IllegalArgumentException</CODE>: The <em>name</em>
- * parameter contains an invalid pattern. See the
- * <a href="namespace/package-summary.html#RejectedNamespacePatterns"><!--
- * -->namespaces documentation</a> for more details.
*/
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query)
throws IOException;
@@ -479,17 +451,7 @@
* 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. ObjectName patterns that may be contained in the
- * query expression will be
- * <a href="namespace/package-summary.html#NamespaceAndQueries"><!--
- * -->evaluated</a> 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
- * <a href="namespace/package-summary.html#RejectedNamespacePatterns"><!--
- * -->namespaces documentation</a> for more details.
+ * selecting MBeans.
*
* @return A set containing the ObjectNames for the MBeans
* selected. If no MBean satisfies the query, an empty list is
@@ -497,11 +459,6 @@
*
* @exception IOException A communication problem occurred when
* talking to the MBean server.
- * @exception RuntimeOperationsException Wraps a
- * <CODE>java.lang.IllegalArgumentException</CODE>: The <em>name</em>
- * parameter contains an invalid pattern. See the
- * <a href="namespace/package-summary.html#RejectedNamespacePatterns"><!--
- * -->namespaces documentation</a> for more details.
*/
public Set<ObjectName> queryNames(ObjectName name, QueryExp query)
throws IOException;
@@ -594,7 +551,8 @@
* else {
* {@code List<String>} missing = new {@code ArrayList<String>}(<!--
* -->{@link java.util.Arrays#asList Arrays.asList}(attrNames));
- * missing.removeAll(list.toMap().keySet());
+ * for (Attribute a : list.asList())
+ * missing.remove(a.getName());
* System.out.println("Did not retrieve: " + missing);
* }
* </pre>
@@ -681,9 +639,11 @@
* if (inputAttrs.size() == outputAttrs.size())
* System.out.println("All attributes were set successfully");
* else {
- * {@code List<String>} missing = new {@code ArrayList<String>}(<!--
- * -->inputAttrs.toMap().keySet());
- * missing.removeAll(outputAttrs.toMap().keySet());
+ * {@code List<String>} missing = new {@code ArrayList<String>}();
+ * for (Attribute a : inputAttrs.asList())
+ * missing.add(a.getName());
+ * for (Attribute a : outputAttrs.asList())
+ * missing.remove(a.getName());
* System.out.println("Did not set: " + missing);
* }
* </pre>
@@ -809,7 +769,28 @@
public String[] getDomains()
throws IOException;
- // doc inherited from NotificationManager
+ /**
+ * <p>Adds a listener to a registered MBean.
+ * Notifications emitted by the MBean will be forwarded to the listener.</p>
+ *
+ * @param name The name of the MBean on which the listener should
+ * be added.
+ * @param listener The listener object which will handle the
+ * notifications emitted by the registered MBean.
+ * @param filter The filter object. If filter is null, no
+ * filtering will be performed before handling notifications.
+ * @param handback The context to be sent to the listener when a
+ * notification is emitted.
+ *
+ * @exception InstanceNotFoundException The MBean name provided
+ * does not match any of the registered MBeans.
+ * @exception IOException A communication problem occurred when
+ * talking to the MBean server.
+ *
+ * @see #removeNotificationListener(ObjectName, NotificationListener)
+ * @see #removeNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ */
public void addNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
@@ -926,13 +907,65 @@
throws InstanceNotFoundException, ListenerNotFoundException,
IOException;
- // doc inherited from NotificationManager
+
+ /**
+ * <p>Removes a listener from a registered MBean.</p>
+ *
+ * <P> If the listener is registered more than once, perhaps with
+ * different filters or callbacks, this method will remove all
+ * those registrations.
+ *
+ * @param name The name of the MBean on which the listener should
+ * be removed.
+ * @param listener The listener to be removed.
+ *
+ * @exception InstanceNotFoundException The MBean name provided
+ * does not match any of the registered MBeans.
+ * @exception ListenerNotFoundException The listener is not
+ * registered in the MBean.
+ * @exception IOException A communication problem occurred when
+ * talking to the MBean server.
+ *
+ * @see #addNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ */
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException, ListenerNotFoundException,
IOException;
- // doc inherited from NotificationManager
+ /**
+ * <p>Removes a listener from a registered MBean.</p>
+ *
+ * <p>The MBean must have a listener that exactly matches the
+ * given <code>listener</code>, <code>filter</code>, and
+ * <code>handback</code> parameters. If there is more than one
+ * such listener, only one is removed.</p>
+ *
+ * <p>The <code>filter</code> and <code>handback</code> parameters
+ * may be null if and only if they are null in a listener to be
+ * removed.</p>
+ *
+ * @param name The name of the MBean on which the listener should
+ * be removed.
+ * @param listener The listener to be removed.
+ * @param filter The filter that was specified when the listener
+ * was added.
+ * @param handback The handback that was specified when the
+ * listener was added.
+ *
+ * @exception InstanceNotFoundException The MBean name provided
+ * does not match any of the registered MBeans.
+ * @exception ListenerNotFoundException The listener is not
+ * registered in the MBean, or it is not registered with the given
+ * filter and handback.
+ * @exception IOException A communication problem occurred when
+ * talking to the MBean server.
+ *
+ * @see #addNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ *
+ */
public void removeNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
@@ -986,12 +1019,6 @@
*
* <p>Otherwise, the result is false.</p>
*
- * <p>If the MBean implements the {@link DynamicWrapperMBean}
- * interface, then in the above rules X is the result of the MBean's {@link
- * DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method and L
- * is the result of its {@link DynamicWrapperMBean#getWrappedClassLoader()
- * getWrappedClassLoader()} method.
- *
* @param name The <CODE>ObjectName</CODE> of the MBean.
* @param className The name of the class.
*
--- a/jdk/src/share/classes/javax/management/MBeanServerDelegate.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanServerDelegate.java Wed Oct 21 16:50:44 2009 +0100
@@ -41,7 +41,6 @@
/** The MBean server agent identification.*/
private String mbeanServerId ;
- private String mbeanServerName;
/** The NotificationBroadcasterSupport object that sends the
notifications */
@@ -71,7 +70,6 @@
public MBeanServerDelegate () {
stamp = getStamp();
broadcaster = new NotificationBroadcasterSupport() ;
- mbeanServerName=null;
}
@@ -90,99 +88,12 @@
"using \"localhost\" instead. Cause is: "+e);
localHost = "localhost";
}
- mbeanServerId =
- Util.insertMBeanServerName(localHost + "_" + stamp,
- mbeanServerName);
+ mbeanServerId = localHost + "_" + stamp;
}
return mbeanServerId;
}
/**
- * The name of the MBeanServer.
- * @return The name of the MBeanServer, or {@value
- * javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if no
- * name was specified.
- *
- * @since 1.7
- * @see #setMBeanServerName
- */
- public synchronized String getMBeanServerName() {
- if (Util.isMBeanServerNameUndefined(mbeanServerName))
- return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
- return mbeanServerName;
- }
-
- /**
- * Sets the name of the MBeanServer. The name will be embedded into the
- * {@link #getMBeanServerId MBeanServerId} using the following format:<br>
- * {@code mbeanServerId: <mbeanServerId>;mbeanServerName=<mbeanServerName>}
- * <p>The characters {@code ':'} (colon), {@code ';'} (semicolon ),
- * {@code '*'} (star) and {@code '?'} (question mark) are not legal in an
- * MBean Server name.</p>
- * <p>For instance, if the {@code mbeanServerName} provided is
- * {@code "com.mycompany.myapp.server1"}, and the original
- * {@code MBeanServerId} was {@code "myhost_1213353064145"},
- * then {@code mbeanServerName} will be
- * embedded in the {@code MBeanServerId} - and the new value of the
- * {@code MBeanServerId} will be:
- * </p>
- * <pre>
- * "myhost_1213353064145;mbeanServerName=com.mycompany.myapp.server1"
- * </pre>
- * <p>Note: The {@code mbeanServerName} is usually set by the
- * {@code MBeanServerFactory}. It is set only once, before the
- * MBean Server is returned by the factory. Once the MBean Server name is
- * set, it is not possible to change it.
- * </p>
- * @param mbeanServerName The MBeanServer name.
- * @throws IllegalArgumentException if the MBeanServerName is already set
- * to a different value, or if the provided name contains
- * illegal characters, or if the provided name is {@code ""}
- * (the empty string) or "-" (dash).
- * @throws UnsupportedOperationException if this object is of a legacy
- * subclass of MBeanServerDelegate which overrides {@link
- * #getMBeanServerId()}
- * in a way that doesn't support setting an MBeanServer name.
- * @see MBeanServerFactory#getMBeanServerName
- * @since 1.7
- */
- public synchronized void setMBeanServerName(String mbeanServerName) {
- // Sets the name on the delegate. For complex backward
- // compatibility reasons it is not possible to give the
- // name to the MBeanServerDelegate constructor.
- //
- // The method setMBeanServerName() will call getMBeanServerId()
- // to check that the name is accurately set in the MBeanServerId.
- // If not (which could happen if a custom MBeanServerDelegate
- // implementation overrides getMBeanServerId() and was not updated
- // with respect to JMX 2.0 spec), this method will throw an
- // IllegalStateException...
-
- // will fail if mbeanServerName is illegal
- final String name = Util.checkServerName(mbeanServerName);
-
- // can only set mbeanServerDelegate once.
- if (this.mbeanServerName != null && !this.mbeanServerName.equals(name))
- throw new IllegalArgumentException(
- "MBeanServerName already set to a different value");
-
- this.mbeanServerName = name;
-
- // will fail if mbeanServerId already has a different mbeanServerName
- mbeanServerId =
- Util.insertMBeanServerName(getMBeanServerId(),name);
-
- // check that we don't have a subclass which overrides
- // getMBeanServerId() without setting mbeanServerName
- if (!name.equals(
- Util.extractMBeanServerName(getMBeanServerId())))
- throw new UnsupportedOperationException(
- "Can't set MBeanServerName in MBeanServerId - " +
- "unsupported by "+this.getClass().getName()+"?");
- // OK: at this point we know that we have correctly set mbeanServerName.
- }
-
- /**
* Returns the full name of the JMX specification implemented
* by this product.
*
@@ -304,7 +215,7 @@
* @since 1.6
*/
public static final ObjectName DELEGATE_NAME =
- ObjectName.valueOf("JMImplementation:type=MBeanServerDelegate");
+ Util.newObjectName("JMImplementation:type=MBeanServerDelegate");
/* Return a timestamp that is monotonically increasing even if
System.currentTimeMillis() isn't (for example, if you call this
--- a/jdk/src/share/classes/javax/management/MBeanServerFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanServerFactory.java Wed Oct 21 16:50:44 2009 +0100
@@ -29,11 +29,9 @@
import static com.sun.jmx.defaults.JmxProperties.JMX_INITIAL_BUILDER;
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
import com.sun.jmx.mbeanserver.GetPropertyAction;
-import com.sun.jmx.mbeanserver.Util;
import java.security.AccessController;
import java.security.Permission;
import java.util.ArrayList;
-import java.util.List;
import java.util.logging.Level;
import javax.management.loading.ClassLoaderRepository;
@@ -83,53 +81,10 @@
* returned by the default MBeanServerBuilder implementation, for the purpose
* of e.g. adding an additional security layer.</p>
*
- * <p id="MBeanServerName">Since version 2.0 of the JMX API, when creating
- * an MBeanServer,
- * it is possible to specify an {@linkplain #getMBeanServerName
- * MBean Server name}.
- * To create an MBean Server with a name, the MBeanServerFactory provides two
- * new methods:</p>
- * <ul><li>{@link #createNamedMBeanServer
- * createNamedMBeanServer(mbeanServerName, defaultDomain)}: creates a named
- * MBeanServer and keeps an internal reference to the created object. The
- * MBeanServer can be later retrieved using {@link #findMBeanServer
- * findMBeanServer(mbeanServerId)} or
- * {@link #findMBeanServerByName findMBeanServerByName(mbeanServerName)}, and
- * can be released through {@link
- * #releaseMBeanServer releaseMBeanServer(mbeanServer)}.</li>
- * <li>{@link #newNamedMBeanServer
- * newNamedMBeanServer(mbeanServerName, defaultDomain)}:
- * creates a named MBeanServer without keeping any internal reference to the
- * named server.</li>
- * </ul>
- * <p>The name of the MBeanServer is stored in the
- * {@linkplain MBeanServerDelegate MBean Server delegate MBean}
- * and is embedded in its {@link MBeanServerDelegate#getMBeanServerId
- * MBeanServerId} attribute.</p>
- * <p>The name of the MBeanServer is particularly useful when
- * <a href="MBeanServer.html#security">MBean permissions</a> are checked:
- * it makes it
- * possible to distinguish between an MBean named "X" in MBeanServer named
- * "M1", and another MBean of the same name "X" in another MBeanServer named
- * "M2".</p>
- * <p>When naming MBean servers it is recommended to use a name that starts
- * with a Java package name. It is also recommended that the default domain and
- * the MBeanServer name be the same.</p>
- *
* @since 1.5
*/
public class MBeanServerFactory {
- /**
- * The <a href="#MBeanServerName">MBean Server name</a> that will be
- * checked by a <a href="MBeanServer.html#security">permission you need</a>
- * when checking access to an MBean registered in an MBeanServer for
- * which no MBeanServer name was specified.
- *
- * @since 1.7
- */
- public final static String DEFAULT_MBEANSERVER_NAME = "default";
-
/*
* There are no instances of this class so don't generate the
* default public constructor.
@@ -268,78 +223,13 @@
* <code>javax.management.builder.initial</code> exists and can be
* instantiated but is not assignment compatible with {@link
* MBeanServerBuilder}.
- *
- * @see #createNamedMBeanServer
*/
public static MBeanServer createMBeanServer(String domain) {
- return createMBeanServer(null,domain);
- }
+ checkPermission("createMBeanServer");
- /**
- * <p>Return a new object implementing the {@link MBeanServer}
- * interface with the specified
- * <a href="#MBeanServerName">MBean Server name</a>
- * and default domain name. The given MBean server name
- * is used in <a href="MBeanServer.html#security">security checks</a>, and
- * can also be used to {@linkplain #findMBeanServerByName(java.lang.String)
- * find an MBeanServer by name}. The given
- * domain name is used as the domain part in the ObjectName of
- * MBeans when the domain is specified by the user is null.</p>
- *
- * <p>The MBeanServer reference is internally kept. This will
- * allow <CODE>findMBeanServer</CODE> to return a reference to
- * this MBeanServer object.</p>
- *
- * @param mbeanServerName the name for the created
- * MBeanServer. This is the name that will be included in the
- * {@linkplain MBeanPermission permission you need} when checking
- * <a href="MBeanServer.html#security">MBean Permissions</a> for accessing
- * an MBean registered in the returned MBeanServer. The characters
- * {@code ':'} (colon), {@code ';'} (semicolon), {@code '*'} (star)
- * and {@code '?'} are not legal.
- * It is recommended that the {@code mbeanServerName}
- * be unique in the context of a JVM, and in the form of a java package
- * identifier. If {@code mbeanServerName} is {@code null} then the created
- * MBean Server has no name - and {@value #DEFAULT_MBEANSERVER_NAME} is used.
- * Calling {@code createNamedMBeanServer(null,domain)} is equivalent
- * to calling {@link #createMBeanServer(String) createMBeanServer(domain)}.
- *
- * @param domain the default domain name for the created
- * MBeanServer. This is the value that will be returned by {@link
- * MBeanServer#getDefaultDomain}. If a non null mbeanServerName is given,
- * it is recommended to pass the same value as default domain.
- *
- * @return the newly created MBeanServer.
- *
- * @exception SecurityException if there is a SecurityManager and
- * the caller's permissions do not include or imply <code>{@link
- * MBeanServerPermission}("createMBeanServer")</code>.
- *
- * @exception JMRuntimeException if the property
- * <code>javax.management.builder.initial</code> exists but the
- * class it names cannot be instantiated through a public
- * no-argument constructor; or if the instantiated builder returns
- * null from its {@link MBeanServerBuilder#newMBeanServerDelegate
- * newMBeanServerDelegate} or {@link
- * MBeanServerBuilder#newMBeanServer newMBeanServer} methods.
- *
- * @exception ClassCastException if the property
- * <code>javax.management.builder.initial</code> exists and can be
- * instantiated but is not assignment compatible with {@link
- * MBeanServerBuilder}.
- *
- * @exception IllegalArgumentException if the specified
- * {@code mbeanServerName} is empty, or is {@code "-"}, or contains a
- * character which is not legal.
- *
- * @exception UnsupportedOperationException if the specified
- * {@code mbeanServerName} cannot be set.
- *
- * @since 1.7
- */
- public static MBeanServer createNamedMBeanServer(String mbeanServerName,
- String domain) {
- return createMBeanServer(mbeanServerName, domain);
+ final MBeanServer mBeanServer = newMBeanServer(domain);
+ addMBeanServer(mBeanServer);
+ return mBeanServer;
}
/**
@@ -418,88 +308,6 @@
* MBeanServerBuilder}.
*/
public static MBeanServer newMBeanServer(String domain) {
- return newMBeanServer(null,domain);
- }
-
- /**
- * <p>Return a new object implementing the MBeanServer interface
- * with the specified <a href="#MBeanServerName">MBean server name</a>
- * and default domain name, without keeping an
- * internal reference to this new object. The given MBean server name
- * is used in <a href="MBeanServer.html#security">security checks</a>.
- * The given domain name
- * is used as the domain part in the ObjectName of MBeans when the
- * domain is specified by the user is null.</p>
- *
- * <p>No reference is kept. <CODE>findMBeanServer</CODE> and
- * <CODE>findMBeanServerByName</CODE> will not
- * be able to return a reference to this MBeanServer object, but
- * the garbage collector will be able to remove the MBeanServer
- * object when it is no longer referenced.</p>
- *
- * @param mbeanServerName the name for the created
- * MBeanServer. This is the name that will be included in the
- * {@linkplain MBeanPermission permission you need} when checking
- * <a href="MBeanServer.html#security">MBean Permissions</a> for accessing
- * an MBean registered in the returned MBeanServer. The characters
- * {@code ':'} (colon), {@code ';'} (semicolon), {@code '*'} (star)
- * and {@code '?'} are not legal.
- * It is recommended that the mbeanServerName
- * be unique in the context of a JVM, and in the form of a java package
- * identifier. If {@code mbeanServerName} is {@code null} then the created
- * MBean Server has no name - and {@value #DEFAULT_MBEANSERVER_NAME} is used.
- * Calling {@code newNamedMBeanServer(null,domain)} is equivalent
- * to calling {@link #newMBeanServer(String) newMBeanServer(domain)}.
- *
- * @param domain the default domain name for the created
- * MBeanServer. This is the value that will be returned by {@link
- * MBeanServer#getDefaultDomain}.
- *
- * @return the newly created MBeanServer.
- *
- * @exception SecurityException if there is a SecurityManager and the
- * caller's permissions do not include or imply <code>{@link
- * MBeanServerPermission}("newMBeanServer")</code>.
- *
- * @exception JMRuntimeException if the property
- * <code>javax.management.builder.initial</code> exists but the
- * class it names cannot be instantiated through a public
- * no-argument constructor; or if the instantiated builder returns
- * null from its {@link MBeanServerBuilder#newMBeanServerDelegate
- * newMBeanServerDelegate} or {@link
- * MBeanServerBuilder#newMBeanServer newMBeanServer} methods.
- *
- * @exception ClassCastException if the property
- * <code>javax.management.builder.initial</code> exists and can be
- * instantiated but is not assignment compatible with {@link
- * MBeanServerBuilder}.
- *
- * @exception IllegalArgumentException if the specified
- * {@code mbeanServerName} is empty, or is {@code "-"},
- * or contains a character which is not legal.
- *
- * @exception UnsupportedOperationException if the specified
- * {@code mbeanServerName} cannot be set.
- *
- * @since 1.7
- */
- public static MBeanServer newNamedMBeanServer(String mbeanServerName,
- String domain) {
- return newMBeanServer(mbeanServerName, domain);
- }
-
- private static MBeanServer createMBeanServer(String mbeanServerName,
- String domain) {
- checkPermission("createMBeanServer");
-
- final MBeanServer mBeanServer =
- newMBeanServer(mbeanServerName,domain);
- addMBeanServer(mBeanServer);
- return mBeanServer;
- }
-
- private static MBeanServer newMBeanServer(String mbeanServerName,
- String domain) {
checkPermission("newMBeanServer");
// Get the builder. Creates a new one if necessary.
@@ -516,22 +324,6 @@
"returned null";
throw new JMRuntimeException(msg);
}
-
- // Sets the name on the delegate. For complex backward
- // compatibility reasons it is not possible to give the
- // name to the MBeanServerDelegate constructor.
- //
- // The method setMBeanServerName() will call getMBeanServerId()
- // to check that the name is accurately set in the MBeanServerId.
- // If not (which could happen if a custom MBeanServerDelegate
- // implementation overrides getMBeanServerId() and was not updated
- // with respect to JMX 2.0 spec, this method will throw an
- // IllegalStateException...
- //
- if (!Util.isMBeanServerNameUndefined(mbeanServerName)) {
- delegate.setMBeanServerName(mbeanServerName);
- }
-
final MBeanServer mbeanServer =
mbsBuilder.newMBeanServer(domain,null,delegate);
if (mbeanServer == null) {
@@ -539,20 +331,6 @@
"MBeanServerBuilder.newMBeanServer() returned null";
throw new JMRuntimeException(msg);
}
-
- // double check that the MBeanServer name is correctly set.
- // "*" might mean that the caller doesn't have the permission
- // to see the MBeanServer name.
- //
- final String mbsName = Util.getMBeanServerSecurityName(mbeanServer);
- if (!mbsName.equals(Util.checkServerName(mbeanServerName))
- && !mbsName.equals("*")) {
- throw new UnsupportedOperationException(
- "can't create MBeanServer with name \""+
- mbeanServerName+"\" using "+
- builder.getClass().getName());
- }
-
return mbeanServer;
}
}
@@ -594,96 +372,6 @@
}
/**
- * <p>Returns a list of registered MBeanServer objects with the given name. A
- * registered MBeanServer object is one that was created by one of
- * the <code>createMBeanServer</code> or <code>createNamedMBeanServer</code>
- * methods and not subsequently released with <code>releaseMBeanServer</code>.</p>
- * <p>See the section about <a href="#MBeanServerName">MBean Server names</a>
- * above.</p>
- *
- * @param mbeanServerName The name of the MBeanServer to
- * retrieve. If this parameter is null, all registered MBeanServers
- * in this JVM are returned.
- * Otherwise, only those MBeanServers that have a name
- * matching <code>mbeanServerName</code> are returned: this
- * parameter can be a pattern, where {@code '*'} matches any
- * sequence of characters and {@code '?'} matches any character.<br>
- * The name of an MBeanServer, if specified, is embedded in the
- * <code>MBeanServerId</code> attribute of its delegate MBean:
- * this method will parse the <code>MBeanServerId</code> to get the
- * MBeanServer name. If this parameter is equal to {@code "*"} then
- * all registered MBeanServers in this JVM are returned, whether they have
- * a name or not: {@code findMBeanServerByName(null)},
- * {@code findMBeanServerByName("*")} and {@code findMBeanServer(null)},
- * are equivalent. It is also possible to get all MBeanServers for which
- * no name was specified by calling <code>findMBeanServerByName({@value
- * #DEFAULT_MBEANSERVER_NAME})</code>.
- *
- * @return A list of MBeanServer objects.
- *
- * @exception SecurityException if there is a SecurityManager and the
- * caller's permissions do not include or imply <code>{@link
- * MBeanServerPermission}("findMBeanServer")</code>.
- *
- * @see #getMBeanServerName(MBeanServer)
- * @since 1.7
- */
- public synchronized static
- List<MBeanServer> findMBeanServerByName(String mbeanServerName) {
-
- checkPermission("findMBeanServer");
-
- if (mbeanServerName==null || "*".equals(mbeanServerName))
- return new ArrayList<MBeanServer>(mBeanServerList);
-
- // noname=true iff we are looking for MBeanServers for which no name
- // were specified.
- ArrayList<MBeanServer> result = new ArrayList<MBeanServer>();
- for (MBeanServer mbs : mBeanServerList) {
- final String name = Util.getMBeanServerSecurityName(mbs);
- if (Util.wildmatch(name, mbeanServerName)) result.add(mbs);
- }
- return result;
- }
-
- /**
- * Returns the name of the MBeanServer embedded in the MBeanServerId of
- * the given {@code server}. If the given MBeanServerId doesn't contain
- * any name, {@value #DEFAULT_MBEANSERVER_NAME} is returned.
- * The MBeanServerId is expected to be of the form:
- * {@code *[;mbeanServerName=<mbeanServerName>[;*]]}
- * <br>where {@code *} denotes any sequence of characters, and {@code [ ]}
- * indicate optional parts.
- * </p>
- * <p>For instance, if an MBeanServer is created using {@link
- * #createNamedMBeanServer(java.lang.String, java.lang.String)
- * server =
- * MBeanServerFactory.createNamedMBeanServer("com.mycompany.myapp.server1",
- * null)} then {@code MBeanServerFactory.getMBeanServerName(server)}
- * will return {@code "com.mycompany.myapp.server1"} and
- * <code>server.getAttribute({@link
- * javax.management.MBeanServerDelegate#DELEGATE_NAME
- * MBeanServerDelegate.DELEGATE_NAME}, "MBeanServerId")</code> will return
- * something like
- * {@code "myhost_1213353064145;mbeanServerName=com.mycompany.myapp.server1"}.
- * </p>
- * <p>See the section about <a href="#MBeanServerName">MBean Server names</a>
- * above.</p>
- * @param server A named (or unnamed) MBeanServer.
- * @return the name of the MBeanServer if found, or
- * {@value #DEFAULT_MBEANSERVER_NAME} if no name is
- * present in its MBeanServerId, or "*" if its
- * MBeanServerId couldn't be obtained. Returning "*" means that
- * only {@link MBeanPermission}s that allow all MBean Server names
- * will apply to this MBean Server.
- * @see MBeanServerDelegate
- * @since 1.7
- */
- public static String getMBeanServerName(MBeanServer server) {
- return Util.getMBeanServerSecurityName(server);
- }
-
- /**
* Return the ClassLoaderRepository used by the given MBeanServer.
* This method is equivalent to {@link
* MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}.
--- a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java Wed Oct 21 16:50:44 2009 +0100
@@ -33,9 +33,6 @@
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.WeakHashMap;
-import javax.management.openmbean.MXBeanMappingFactory;
-
-import static javax.management.JMX.MBeanOptions;
/**
* <p>{@link InvocationHandler} that forwards methods in an MBean's
@@ -114,7 +111,7 @@
public MBeanServerInvocationHandler(MBeanServerConnection connection,
ObjectName objectName) {
- this(connection, objectName, null);
+ this(connection, objectName, false);
}
/**
@@ -141,14 +138,6 @@
public MBeanServerInvocationHandler(MBeanServerConnection connection,
ObjectName objectName,
boolean isMXBean) {
- this(connection, objectName, isMXBean ? MBeanOptions.MXBEAN : null);
- }
-
- public MBeanServerInvocationHandler(MBeanServerConnection connection,
- ObjectName objectName,
- MBeanOptions options) {
- if (options == null)
- options = new MBeanOptions();
if (connection == null) {
throw new IllegalArgumentException("Null connection");
}
@@ -157,7 +146,7 @@
}
this.connection = connection;
this.objectName = objectName;
- this.options = options.canonical();
+ this.isMXBean = isMXBean;
}
/**
@@ -193,16 +182,7 @@
* @since 1.6
*/
public boolean isMXBean() {
- return options.isMXBean();
- }
-
- /**
- * <p>Return the {@link MBeanOptions} used for this proxy.</p>
- *
- * @return the MBeanOptions.
- */
- public MBeanOptions getMBeanOptions() {
- return options.uncanonical();
+ return isMXBean;
}
/**
@@ -346,40 +326,30 @@
*/
}
- private MXBeanProxy findMXBeanProxy(Class<?> mxbeanInterface) {
- MXBeanMappingFactory mappingFactory = options.getMXBeanMappingFactory();
+ private static MXBeanProxy findMXBeanProxy(Class<?> mxbeanInterface) {
synchronized (mxbeanProxies) {
- ClassToProxy classToProxy = mxbeanProxies.get(mappingFactory);
- if (classToProxy == null) {
- classToProxy = new ClassToProxy();
- mxbeanProxies.put(mappingFactory, classToProxy);
+ WeakReference<MXBeanProxy> proxyRef =
+ mxbeanProxies.get(mxbeanInterface);
+ MXBeanProxy p = (proxyRef == null) ? null : proxyRef.get();
+ if (p == null) {
+ try {
+ p = new MXBeanProxy(mxbeanInterface);
+ } catch (IllegalArgumentException e) {
+ String msg = "Cannot make MXBean proxy for " +
+ mxbeanInterface.getName() + ": " + e.getMessage();
+ IllegalArgumentException iae =
+ new IllegalArgumentException(msg, e.getCause());
+ iae.setStackTrace(e.getStackTrace());
+ throw iae;
+ }
+ mxbeanProxies.put(mxbeanInterface,
+ new WeakReference<MXBeanProxy>(p));
}
- WeakReference<MXBeanProxy> wr = classToProxy.get(mxbeanInterface);
- MXBeanProxy p;
- if (wr != null) {
- p = wr.get();
- if (p != null)
- return p;
- }
- try {
- p = new MXBeanProxy(mxbeanInterface, mappingFactory);
- } catch (IllegalArgumentException e) {
- String msg = "Cannot make MXBean proxy for " +
- mxbeanInterface.getName() + ": " + e.getMessage();
- throw new IllegalArgumentException(msg, e.getCause());
- }
- classToProxy.put(mxbeanInterface, new WeakReference<MXBeanProxy>(p));
return p;
}
}
- private static final WeakHashMap<MXBeanMappingFactory, ClassToProxy>
- mxbeanProxies = newWeakHashMap();
- private static class ClassToProxy
- extends WeakHashMap<Class<?>, WeakReference<MXBeanProxy>> {}
-
- private static <K, V> WeakHashMap<K, V> newWeakHashMap() {
- return new WeakHashMap<K, V>();
- }
+ private static final WeakHashMap<Class<?>, WeakReference<MXBeanProxy>>
+ mxbeanProxies = new WeakHashMap<Class<?>, WeakReference<MXBeanProxy>>();
private Object invokeBroadcasterMethod(Object proxy, Method method,
Object[] args) throws Exception {
@@ -523,5 +493,5 @@
private final MBeanServerConnection connection;
private final ObjectName objectName;
- private final MBeanOptions options;
+ private final boolean isMXBean;
}
--- a/jdk/src/share/classes/javax/management/MBeanServerNotification.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MBeanServerNotification.java Wed Oct 21 16:50:44 2009 +0100
@@ -64,13 +64,13 @@
* mbeanServer.addNotificationListener(
* MBeanServerDelegate.DELEGATE_NAME, printListener, null, null);
* </pre>
+ *
* <p id="group">
* An MBean which is not an {@link MBeanServerDelegate} may also emit
- * MBeanServerNotifications. In particular, a custom subclass of the
- * {@link javax.management.namespace.JMXDomain JMXDomain} MBean or a custom
- * subclass of the {@link javax.management.namespace.JMXNamespace JMXNamespace}
- * MBean may emit an MBeanServerNotification for a group of MBeans.<br>
- * An MBeanServerNotification emitted to denote the registration or
+ * MBeanServerNotifications. In particular, there is a convention for
+ * MBeans to emit an MBeanServerNotification for a group of MBeans.</p>
+ *
+ * <p>An MBeanServerNotification emitted to denote the registration or
* unregistration of a group of MBeans has the following characteristics:
* <ul><li>Its {@linkplain Notification#getType() notification type} is
* {@code "JMX.mbean.registered.group"} or
@@ -92,58 +92,6 @@
* declare them in their {@link MBeanInfo#getNotifications()
* MBeanNotificationInfo}.
* </p>
- * <P>
- * To receive a group MBeanServerNotification, you need to register a listener
- * with the MBean that emits it. For instance, assuming that the {@link
- * javax.management.namespace.JMXNamespace JMXNamespace} MBean handling
- * namespace {@code "foo"} has declared that it emits such a notification,
- * you will need to register your notification listener with that MBean, which
- * will be named {@link
- * javax.management.namespace.JMXNamespaces#getNamespaceObjectName(java.lang.String)
- * foo//:type=JMXNamespace}.
- * </p>
- * <p>The following code prints a message every time a group of MBean is
- * registered or unregistered in the namespace {@code "foo"}, assumimg its
- * {@link javax.management.namespace.JMXNamespace handler} supports
- * group MBeanServerNotifications:</p>
- *
- * <pre>
- * private static final NotificationListener printListener = new NotificationListener() {
- * public void handleNotification(Notification n, Object handback) {
- * if (!(n instanceof MBeanServerNotification)) {
- * System.out.println("Ignored notification of class " + n.getClass().getName());
- * return;
- * }
- * MBeanServerNotification mbsn = (MBeanServerNotification) n;
- * String what;
- * ObjectName[] names = null;
- * if (n.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
- * what = "MBean registered";
- * } else if (n.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
- * what = "MBean unregistered";
- * } else if (n.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION+".group")) {
- * what = "Group of MBeans registered matching";
- * if (mbsn.getUserData() instanceof ObjectName[])
- * names = (ObjectName[]) mbsn.getUserData();
- * } else if (n.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION+".group")) {
- * what = "Group of MBeans unregistered matching";
- * if (mbsn.getUserData() instanceof ObjectName[])
- * names = (ObjectName[]) mbsn.getUserData();
- * } else
- * what = "Unknown type " + n.getType();
- * System.out.println("Received MBean Server notification: " + what + ": " +
- * mbsn.getMBeanName());
- * if (names != null) {
- * for (ObjectName mb : names)
- * System.out.println("\t"+mb);
- * }
- * }
- * };
- *
- * ...
- * mbeanServer.addNotificationListener(
- * JMXNamespaces.getNamespaceObjectName("foo"), printListener, null, null);
- * </pre>
*
* @since 1.5
*/
--- a/jdk/src/share/classes/javax/management/MXBean.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/MXBean.java Wed Oct 21 16:50:44 2009 +0100
@@ -27,7 +27,6 @@
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -44,10 +43,6 @@
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeDataView;
import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingClass;
-import javax.management.openmbean.MXBeanMappingFactory;
-import javax.management.openmbean.MXBeanMappingFactoryClass;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenMBeanInfo;
import javax.management.openmbean.OpenType;
@@ -57,13 +52,11 @@
import javax.management.openmbean.TabularType;
/**
- <p>Annotation to mark a class or interface explicitly as being an MXBean,
- or as not being an MXBean. By default, an
+ <p>Annotation to mark an interface explicitly as being an MXBean
+ interface, or as not being an MXBean interface. By default, an
interface is an MXBean interface if its name ends with {@code
- MXBean}, as in {@code SomethingMXBean}. A class is never an MXBean by
- default.</p>
-
- <p>The following interfaces are MXBean interfaces:</p>
+ MXBean}, as in {@code SomethingMXBean}. The following interfaces
+ are MXBean interfaces:</p>
<pre>
public interface WhatsitMXBean {}
@@ -84,12 +77,7 @@
public interface MisleadingMXBean {}
</pre>
- <p>A class can be annotated with {@code @MXBean} to indicate that it
- is an MXBean. In this case, its methods should have <code>@{@link
- ManagedAttribute}</code> or <code>@{@link ManagedOperation}</code>
- annotations, as described for <code>@{@link MBean}</code>.</p>
-
- <h3 id="MXBean-spec">MXBean specification</h3>
+ <h3 id="MXBean-spec">MXBean specification</a></h3>
<p>The MXBean concept provides a simple way to code an MBean
that only references a predefined set of types, the ones defined
@@ -486,11 +474,7 @@
from type <em>opendata(J)</em> to type <em>J</em>, a null value is
mapped to a null value.</p>
- <p>In addition to the default type mapping rules, you can specify
- custom type mappings, as described <a
- href="#custom">below</a>.</p>
-
- <p>The following table summarizes the default type mapping rules.</p>
+ <p>The following table summarizes the type mapping rules.</p>
<table border="1" cellpadding="5">
<tr>
@@ -1051,77 +1035,6 @@
}
</pre>
- <p>Alternatively, you can define a custom mapping for your recursive
- type; see the next section.</p>
-
- <h3 id="custom">Custom MXBean type mappings</h3>
-
- <p>You can augment or replace the default type mappings described
- above with custom mappings. An example appears in the
- documentation for {@link MXBeanMapping}.</p>
-
- <p>If an MXBean uses custom mappings, then an MXBean proxy for
- that MXBean must use the same mappings for correct behavior.
- This requires more careful synchronization between client and
- server than is necessary with the default mappings. For example
- it typically requires the client to have the same implementation
- of any {@link MXBeanMapping} subclasses as the server. For this
- reason, custom mappings should be avoided if possible.</p>
-
- <p>Every MXBean has an associated {@link MXBeanMappingFactory}.
- Call this <code><em>f</em></code>. Then every type that appears
- in that MXBean has an associated {@link MXBeanMapping}
- determined by <code><em>f</em></code>. If the type is
- <code><em>J</em></code>, say, then the mapping is {@link
- MXBeanMappingFactory#mappingForType
- <em>f</em>.mappingForType}<code>(<em>J</em>,
- <em>f</em>)</code>.</p>
-
- <p>The {@code MXBeanMappingFactory} <code><em>f</em></code> for an
- MXBean is determined as follows.</p>
-
- <ul>
- <li><p>If a {@link JMX.MBeanOptions} argument is supplied to
- the {@link StandardMBean} constructor that makes an MXBean,
- or to the {@link JMX#newMBeanProxy(MBeanServerConnection,
- ObjectName, Class, JMX.MBeanOptions) JMX.newMBeanProxy}
- method, and the {@code MBeanOptions} object defines a non-null
- {@code MXBeanMappingFactory}, then that is the value of
- <code><em>f</em></code>.</p></li>
-
- <li><p>Otherwise, if the MXBean interface has an {@link
- MXBeanMappingFactoryClass} annotation, then that annotation
- must identify a subclass of {@code MXBeanMappingFactory}
- with a no-argument constructor. Then
- <code><em>f</em></code> is the result of calling this
- constructor. If the class does not have a no-argument
- constructor, or if calling the constructor produces an
- exception, then the MXBean is invalid and an attempt to
- register it in the MBean Server will produce a {@link
- NotCompliantMBeanException}.</p>
-
- <p>This annotation is not inherited from any parent
- interfaces. If an MXBean interface has this annotation,
- then usually any MXBean subinterfaces must repeat the same
- annotation for correct behavior.</p></li>
-
- <li><p>Otherwise, if the package in which the MXBean interface
- appears has an {@code MXBeanMappingFactoryClass} annotation,
- then <code><em>f</em></code> is determined as if that
- annotation appeared on the MXBean interface.</p></li>
-
- <li><p>Otherwise, <code><em>f</em></code> is the default mapping
- factory, {@link MXBeanMappingFactory#DEFAULT}.</p></li>
- </ul>
-
- <p>The default mapping factory recognizes the {@link
- MXBeanMappingClass} annotation on a class or interface. If
- <code><em>J</em></code> is a class or interface that has such an
- annotation, then the {@code MXBeanMapping} for
- <code><em>J</em></code> produced by the default mapping factory
- will be determined by the value of the annotation as described
- in its {@linkplain MXBeanMappingClass documentation}.</p>
-
<h3>MBeanInfo contents for an MXBean</h3>
<p>An MXBean is a type of Open MBean. However, for compatibility
@@ -1250,29 +1163,12 @@
appropriate), or <em>C</em> is true of <em>e</em>.{@link
Throwable#getCause() getCause()}".</p>
- @see MXBeanMapping
-
@since 1.6
*/
-/*
- * This annotation is @Inherited because if an MXBean is defined as a
- * class using annotations, then its subclasses are also MXBeans.
- * For example:
- * @MXBean
- * public class Super {
- * @ManagedAttribute
- * public String getName() {...}
- * }
- * public class Sub extends Super {}
- * Here Sub is an MXBean.
- *
- * The @Inherited annotation has no effect when applied to an interface.
- */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
-@Inherited
public @interface MXBean {
/**
True if the annotated interface is an MXBean interface.
--- a/jdk/src/share/classes/javax/management/ManagedAttribute.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>Indicates that a method in an MBean class defines an MBean attribute.
- * This annotation must be applied to a public method of a public class
- * that is itself annotated with an {@link MBean @MBean} or
- * {@link MXBean @MXBean} annotation, or inherits such an annotation from
- * a superclass.</p>
- *
- * <p>The annotated method must be a getter or setter. In other words,
- * it must look like one of the following...</p>
- *
- * <pre>
- * <i>T</i> get<i>Foo</i>()
- * void set<i>Foo</i>(<i>T</i> param)
- * </pre>
- *
- * <p>...where <i>{@code T}</i> is any type and <i>{@code Foo}</i> is the
- * name of the attribute. For any attribute <i>{@code Foo}</i>, if only
- * a {@code get}<i>{@code Foo}</i> method has a {@code ManagedAttribute}
- * annotation, then <i>{@code Foo}</i> is a read-only attribute. If only
- * a {@code set}<i>{@code Foo}</i> method has a {@code ManagedAttribute}
- * annotation, then <i>{@code Foo}</i> is a write-only attribute. If
- * both {@code get}<i>{@code Foo}</i> and {@code set}<i>{@code Foo}</i>
- * methods have the annotation, then <i>{@code Foo}</i> is a read-write
- * attribute. In this last case, the type <i>{@code T}</i> must be the
- * same in both methods.</p>
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-@Documented
-public @interface ManagedAttribute {
-}
--- a/jdk/src/share/classes/javax/management/ManagedOperation.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>Indicates that a method in an MBean class defines an MBean operation.
- * This annotation can be applied to:</p>
- *
- * <ul>
- * <li>A public method of a public class
- * that is itself annotated with an {@link MBean @MBean} or
- * {@link MXBean @MXBean} annotation, or inherits such an annotation from
- * a superclass.</li>
- * <li>A method of an MBean or MXBean interface.
- * </ul>
- *
- * <p>Every method in an MBean or MXBean interface defines an MBean
- * operation even without this annotation, but the annotation allows
- * you to specify the impact of the operation:</p>
- *
- * <pre>
- * public interface ConfigurationMBean {
- * {@code @ManagedOperation}(impact = {@link Impact#ACTION Impact.ACTION})
- * public void save();
- * ...
- * }
- * </pre>
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-@Documented
-public @interface ManagedOperation {
- /**
- * <p>The impact of this operation, as shown by
- * {@link MBeanOperationInfo#getImpact()}.
- */
- Impact impact() default Impact.UNKNOWN;
-}
--- a/jdk/src/share/classes/javax/management/NotQueryExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/NotQueryExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -90,10 +90,4 @@
public String toString() {
return "not (" + exp + ")";
}
-
- @Override
- String toQueryString() {
- return "not (" + Query.toString(exp) + ")";
- }
-
}
--- a/jdk/src/share/classes/javax/management/Notification.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/Notification.java Wed Oct 21 16:50:44 2009 +0100
@@ -54,7 +54,7 @@
* @since 1.5
*/
@SuppressWarnings("serial") // serialVersionUID is not constant
-public class Notification extends EventObject implements Cloneable {
+public class Notification extends EventObject {
// Serialization compatibility stuff:
// Two serial forms are supported in this class. The selected form depends
@@ -244,26 +244,6 @@
}
/**
- * <p>Creates and returns a copy of this object. The copy is created as
- * described for {@link Object#clone()}. This means, first, that the
- * class of the object will be the same as the class of this object, and,
- * second, that the copy is a "shallow copy". Fields of this notification
- * are not themselves copied. In particular, the {@linkplain
- * #getUserData user data} of the copy is the same object as the
- * original.</p>
- *
- * @return a copy of this object.
- */
- @Override
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
* Sets the source.
*
* @param source the new source for this object.
@@ -341,24 +321,12 @@
*
* @return The message string of this notification object.
*
- * @see #setMessage
*/
public String getMessage() {
return message ;
}
/**
- * Set the notification message.
- *
- * @param message the new notification message.
- *
- * @see #getMessage
- */
- public void setMessage(String message) {
- this.message = message;
- }
-
- /**
* Get the user data.
*
* @return The user data object. It is used for whatever data
--- a/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2007 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
@@ -58,8 +58,7 @@
*
* @since 1.5
*/
-public class NotificationBroadcasterSupport
- implements NotificationEmitter, SendNotification {
+public class NotificationBroadcasterSupport implements NotificationEmitter {
/**
* Constructs a NotificationBroadcasterSupport where each listener is invoked by the
* thread sending the notification. This constructor is equivalent to
@@ -249,26 +248,6 @@
}
}
}
- /**
- * Returns true if there are any listeners.
- *
- * @return true if there is at least one listener that has been added with
- * {@code addNotificationListener} and not subsequently removed with
- * {@code removeNotificationListener} or {@code removeAllNotificationListeners}.
- * @since 1.7
- */
- public boolean isListenedTo() {
- return listenerList.size() > 0;
- }
-
- /**
- * Removes all listeners.
- *
- * @since 1.7
- */
- public void removeAllNotificationListeners() {
- listenerList.clear();
- }
/**
* <p>This method is called by {@link #sendNotification
--- a/jdk/src/share/classes/javax/management/NotificationInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>Specifies the kinds of notification an MBean can emit. In both the
- * following examples, the MBean emits notifications of type
- * {@code "com.example.notifs.create"} and of type
- * {@code "com.example.notifs.destroy"}:</p>
- *
- * <pre>
- * // Example one: a Standard MBean
- * {@code @NotificationInfo}(types={"com.example.notifs.create",
- * "com.example.notifs.destroy"})
- * public interface CacheMBean {...}
- *
- * public class Cache
- * extends NotificationBroadcasterSupport implements CacheMBean {
- * public Cache() {
- * super(); // do not supply any MBeanNotificationInfo[]
- * }
- * ...
- * }
- * </pre>
- *
- * <pre>
- * // Example two: an annotated MBean
- * {@link MBean @MBean}
- * {@code @NotificationInfo}(types={"com.example.notifs.create",
- * "com.example.notifs.destroy"})
- * public class Cache {
- * <a href="MBeanRegistration.html#injection">{@code @Resource}</a>
- * private volatile SendNotification sendNotification;
- * ...
- * }
- * </pre>
- *
- * <p>Each {@code @NotificationInfo} produces an {@link
- * MBeanNotificationInfo} inside the {@link MBeanInfo} of each MBean
- * to which the annotation applies.</p>
- *
- * <p>If you need to specify different notification classes, or different
- * descriptions for different notification types, then you can group
- * several {@code @NotificationInfo} annotations into a containing
- * {@link NotificationInfos @NotificationInfos} annotation.
- *
- * <p>The {@code @NotificationInfo} and {@code @NotificationInfos} annotations
- * are ignored on an MBean that is not a {@linkplain JMX#isNotificationSource
- * notification source} or that implements {@link NotificationBroadcaster} and
- * returns a non-empty array from its {@link
- * NotificationBroadcaster#getNotificationInfo() getNotificationInfo()}
- * method.</p>
- *
- * <p>The {@code NotificationInfo} and {@code NotificationInfos}
- * annotations can be applied to the MBean implementation class, or to
- * any parent class or interface. These annotations on a class take
- * precedence over annotations on any superclass or superinterface.
- * If an MBean does not have these annotations on its class or any
- * superclass, then superinterfaces are examined. It is an error for
- * more than one superinterface to have these annotations, unless one
- * of them is a descendant of all the others; registering such an erroneous
- * MBean will cause a {@link NotCompliantMBeanException}.</p>
- */
-@Documented
-@Inherited
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface NotificationInfo {
- /**
- * <p>The {@linkplain Notification#getType() notification types}
- * that this MBean can emit.</p>
- */
- String[] types();
-
- /**
- * <p>The class that emitted notifications will have. It is recommended
- * that this be {@link Notification}, or one of its standard subclasses
- * in the JMX API.</p>
- */
- Class<? extends Notification> notificationClass() default Notification.class;
-
- /**
- * <p>The description of this notification. For example:
- *
- * <pre>
- * {@code @NotificationInfo}(
- * types={"com.example.notifs.create"},
- * description={@code @Description}("object created"))
- * </pre>
- */
- Description description() default @Description("");
-
- /**
- * <p>Additional descriptor fields for the derived {@code
- * MBeanNotificationInfo}. They are specified in the same way as
- * for the {@link DescriptorFields @DescriptorFields} annotation,
- * for example:</p>
- * <pre>
- * {@code @NotificationInfo}(
- * types={"com.example.notifs.create"},
- * descriptorFields={"severity=6"})
- * </pre>
- */
- String[] descriptorFields() default {};
-}
--- a/jdk/src/share/classes/javax/management/NotificationInfos.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.management.remote.JMXConnectionNotification;
-
-/**
- * <p>Specifies the kinds of notification an MBean can emit, when this
- * cannot be represented by a single {@link NotificationInfo
- * @NotificationInfo} annotation.</p>
- *
- * <p>For example, this annotation specifies that an MBean can emit
- * {@link AttributeChangeNotification} and {@link
- * JMXConnectionNotification}:</p>
- *
- * <pre>
- * {@code @NotificationInfos}(
- * {@code @NotificationInfo}(
- * types = {{@link AttributeChangeNotification#ATTRIBUTE_CHANGE}},
- * notificationClass = AttributeChangeNotification.class),
- * {@code @NotificationInfo}(
- * types = {{@link JMXConnectionNotification#OPENED},
- * {@link JMXConnectionNotification#CLOSED}},
- * notificationClass = JMXConnectionNotification.class)
- * )
- * </pre>
- *
- * <p>If an MBean has both {@code NotificationInfo} and {@code
- * NotificationInfos} on the same class or interface, the effect is
- * the same as if the {@code NotificationInfo} were moved inside the
- * {@code NotificationInfos}.</p>
- */
-@Documented
-@Inherited
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface NotificationInfos {
- /**
- * <p>The {@link NotificationInfo} annotations.</p>
- */
- NotificationInfo[] value();
-}
--- a/jdk/src/share/classes/javax/management/ObjectName.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/ObjectName.java Wed Oct 21 16:50:44 2009 +0100
@@ -27,8 +27,6 @@
import com.sun.jmx.mbeanserver.GetPropertyAction;
import com.sun.jmx.mbeanserver.Util;
-import com.sun.jmx.namespace.serial.JMXNamespaceContext;
-
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
@@ -56,38 +54,14 @@
* properties.</p>
*
* <p>The <em>domain</em> is a string of characters not including
- * the character colon (<code>:</code>).</p>
- * <p>Starting with the version 2.0 of the JMX specification, the
- * <em>domain</em> 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 (<code>//</code>).
- * It identifies the {@linkplain javax.management.namespace namespace} in
- * which the MBean so named is registered.</p>
- *
- * <p>For instance the ObjectName <em>bar//baz:k=v</em> identifiies an MBean
- * named <em>baz:k=v</em> in the namespace <em>bar</em>. Similarly the
- * ObjectName <em>foo//bar//baz:k=v</em> identifiies an MBean named
- * <em>baz:k=v</em> in the namespace <em>foo//bar</em>. See the {@linkplain
- * javax.management.namespace namespace} documentation for more details.</p>
+ * the character colon (<code>:</code>). It is recommended that the domain
+ * should not contain the string "{@code //}", which is reserved for future use.
*
* <p>If the domain includes at least one occurrence of the wildcard
* characters asterisk (<code>*</code>) or question mark
* (<code>?</code>), 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. <br>
- * A namespace separator <code>//</code> does not match wildcard
- * characters unless it is at the very end of the domain string.
- * So <em>foo*bar*:*</em> does not match <em>foo//bar:k=v</em> but it
- * does match <em>fooxbar//:k=v</em>.
- * </p>
- *
- * <p>When included in a namespace path the special path element
- * <code>**</code> matches any number of sub namespaces
- * recursively, but only if used as a complete namespace path element,
- * as in <code>**//b//c//D:k=v</code> or <code>a//**//c//D:k=v</code>
- * - see <a href="#metawildcard">below</a>.
+ * mark matches any single character.</p>
*
* <p>If the domain is empty, it will be replaced in certain contexts
* by the <em>default domain</em> of the MBean server in which the
@@ -195,51 +169,6 @@
* with {@code \}.</li>
* </ul>
*
- * <p id="metawildcard"><b>Pattern and namespaces:</b></p>
- * <p>In an object name pattern, a path element
- * of exactly <code>**</code> corresponds to a meta
- * wildcard that will match any number of sub namespaces.<br>Hence:</p>
- * <table border="0" cellpadding="5">
- * <thead><th>pattern</th><th>matches</th><th>doesn't match</th></thead>
- * <tbody>
- * <tr><td><ul><li><code>**//D:k=v</code></li></ul></td>
- * <td><code>a//D:k=v</code><br>
- * <code>a//b//D:k=v</code><br>
- * <code>a//b//c//D:k=v</code></td>
- * <td><code>D:k=v</code></td></tr>
- * <tr><td><ul><li><code>a//**//D:k=v</code></li></ul></td>
- * <td><code>a//b//D:k=v</code><br>
- * <code>a//b//c//D:k=v</code></td>
- * <td><code>b//b//c//D:k=v</code><br>
- * <code>a//D:k=v</code><br>
- * <code>D:k=v</code></td></tr>
- * <tr><td><ul><li><code>a//**//e//D:k=v</code></li></ul></td>
- * <td><code>a//b//e//D:k=v</code><br>
- * <code>a//b//c//e//D:k=v</code></td>
- * <td><code>a//b//c//c//D:k=v</code><br>
- * <code>b//b//c//e//D:k=v</code><br>
- * <code>a//e//D:k=v</code><br>
- * <code>e//D:k=v</code></td></tr>
- * <tr><td><ul><li><code>a//b**//e//D:k=v</code></li></ul></td>
- * <td><code>a//b//e//D:k=v</code></td>
- * <td><code>a//b//c//e//D:k=v</code><br>
- * because in that case <code>b**</code><br>
- * is not a meta-wildcard - and <code>b**</code><br>
- * is thus equivalent to <code>b*</code>.</td></tr>
- * </tbody>
- * </table>
- *</ul>
- * </p>
- * <p>
- * <b>Note:</b> Although ObjectName patterns where the characters
- * <code>*</code> and <code>?</code> 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
- * <a href="namespace/package-summary.html#RejectedNamespacePatterns"><!--
- * -->namespaces documentation</a> for more details.
- * </p>
- *
* <p>An ObjectName can be written as a String with the following
* elements in order:</p>
*
@@ -294,17 +223,6 @@
public class ObjectName implements Comparable<ObjectName>, QueryExp {
/**
- * The sequence of characters used to separate name spaces in a name space
- * path.
- *
- * @see javax.management.namespace
- * @since 1.7
- **/
- public static final String NAMESPACE_SEPARATOR = "//";
- private static final int NAMESPACE_SEPARATOR_LENGTH =
- NAMESPACE_SEPARATOR.length();
-
- /**
* A structure recording property structure and
* proposing minimal services
*/
@@ -333,17 +251,16 @@
/**
* Returns a key string for receiver key
*/
- String getKeyString(String name, int offset) {
- final int start = _key_index+offset;
- return name.substring(start, start + _key_length);
+ String getKeyString(String name) {
+ return name.substring(_key_index, _key_index + _key_length);
}
/**
* Returns a value string for receiver key
*/
- String getValueString(String name, int offset) {
- final int in_begin = _key_index + offset + _key_length + 1;
- final int out_end = in_begin + _value_length;
+ String getValueString(String name) {
+ int in_begin = _key_index + _key_length + 1;
+ int out_end = in_begin + _value_length;
return name.substring(in_begin, out_end);
}
}
@@ -476,40 +393,6 @@
*/
private transient boolean _property_value_pattern = false;
- private ObjectName(String newDomain, ObjectName aname)
- throws MalformedObjectNameException{
- copyToOtherDomain(newDomain,aname);
- }
-
- private void copyToOtherDomain(String domain, ObjectName aname)
- throws MalformedObjectNameException {
-
- // The domain cannot be null
- if (domain == null)
- throw new NullPointerException("domain cannot be null");
-
- // The key property list cannot be null
- if (aname == null)
- throw new MalformedObjectNameException(
- "key property list cannot be empty");
-
- // checks domain validity. A side effect of this method is also to
- // set the _domain_pattern flag.
- if (!isDomain(domain))
- throw new MalformedObjectNameException("Invalid domain: " + domain);
-
- // init canonicalname
- _domain_length = domain.length();
-
- _canonicalName = (domain +
- aname._canonicalName.substring(aname._domain_length)).intern();
- _kp_array = aname._kp_array;
- _ca_array = aname._ca_array;
- _propertyList = aname._propertyList;
- _property_list_pattern = aname._property_list_pattern;
- _property_value_pattern = aname._property_value_pattern;
- }
-
// Instance private fields <=======================================
// Private fields <========================================
@@ -754,12 +637,10 @@
// we got the key and value part, prepare a property for this
if (!value_pattern) {
- prop = new Property(key_index-_domain_length,
- key_length, value_length);
+ prop = new Property(key_index, key_length, value_length);
} else {
_property_value_pattern = true;
- prop = new PatternProperty(key_index-_domain_length,
- key_length, value_length);
+ prop = new PatternProperty(key_index, key_length, value_length);
}
key_name = name.substring(key_index, key_index + key_length);
@@ -844,12 +725,12 @@
boolean value_pattern = checkValue(value);
sb.append(value);
if (!value_pattern) {
- prop = new Property(key_index-_domain_length,
+ prop = new Property(key_index,
key.length(),
value.length());
} else {
_property_value_pattern = true;
- prop = new PatternProperty(key_index-_domain_length,
+ prop = new PatternProperty(key_index,
key.length(),
value.length());
}
@@ -929,9 +810,9 @@
prop = _ca_array[i];
// length of prop including '=' char
prop_len = prop._key_length + prop._value_length + 1;
- System.arraycopy(specified_chars, prop._key_index+_domain_length,
+ System.arraycopy(specified_chars, prop._key_index,
canonical_chars, prop_index, prop_len);
- prop.setKeyIndex(prop_index-_domain_length);
+ prop.setKeyIndex(prop_index);
prop_index += prop_len;
if (i != last_index) {
canonical_chars[prop_index] = ',';
@@ -1268,37 +1149,15 @@
cn = (String)in.readObject();
}
- final JMXNamespaceContext ctxt =
- JMXNamespaceContext.getDeserializationContext();
try {
- construct(changeContext(ctxt,cn));
+ construct(cn);
} catch (NullPointerException e) {
throw new InvalidObjectException(e.toString());
- } catch (IllegalArgumentException e) {
- throw new InvalidObjectException(e.toString());
} catch (MalformedObjectNameException e) {
throw new InvalidObjectException(e.toString());
}
}
- private String changeContext(JMXNamespaceContext context, String nameString) {
- final String old = context.prefixToRemove;
- final String nw = context.prefixToAdd;
- final int ol = old.length();
- if (nameString.startsWith(NAMESPACE_SEPARATOR)) return nameString;
- if (ol>0) {
- if (!nameString.startsWith(old) ||
- !nameString.startsWith(NAMESPACE_SEPARATOR,ol))
- throw new IllegalArgumentException(
- "Serialized ObjectName does not start with " + old +
- ": " + nameString);
- nameString = nameString.substring(ol+NAMESPACE_SEPARATOR_LENGTH);
- }
- if (!nw.equals("")) {
- nameString = nw + NAMESPACE_SEPARATOR + nameString;
- }
- return nameString;
- }
/**
* Serializes an {@link ObjectName} to an {@link ObjectOutputStream}.
@@ -1361,22 +1220,15 @@
private void writeObject(ObjectOutputStream out)
throws IOException {
- final JMXNamespaceContext ctxt =
- JMXNamespaceContext.getSerializationContext();
-
if (compat)
{
// Serializes this instance in the old serial form
// Read CR 6441274 before making any changes to this code
ObjectOutputStream.PutField fields = out.putFields();
- final String domain =
- changeContext(ctxt,_canonicalName.substring(0, _domain_length));
- final String cn =
- changeContext(ctxt,_canonicalName);
- fields.put("domain", domain);
+ fields.put("domain", _canonicalName.substring(0, _domain_length));
fields.put("propertyList", getKeyPropertyList());
fields.put("propertyListString", getKeyPropertyListString());
- fields.put("canonicalName", cn);
+ fields.put("canonicalName", _canonicalName);
fields.put("pattern", (_domain_pattern || _property_list_pattern));
fields.put("propertyPattern", _property_list_pattern);
out.writeFields();
@@ -1386,8 +1238,7 @@
// Serializes this instance in the new serial form
//
out.defaultWriteObject();
-
- out.writeObject(changeContext(ctxt,getSerializedNameString()));
+ out.writeObject(getSerializedNameString());
}
}
@@ -1416,10 +1267,9 @@
* @exception NullPointerException The <code>name</code> parameter
* is null.
*
- * @see #valueOf(String)
*/
public static ObjectName getInstance(String name)
- throws MalformedObjectNameException {
+ throws MalformedObjectNameException, NullPointerException {
return new ObjectName(name);
}
@@ -1444,7 +1294,6 @@
* follow the rules for quoting.
* @exception NullPointerException One of the parameters is null.
*
- * @see #valueOf(String, String, String)
*/
public static ObjectName getInstance(String domain, String key,
String value)
@@ -1476,7 +1325,6 @@
* quoting.
* @exception NullPointerException One of the parameters is null.
*
- * @see #valueOf(String, Hashtable)
*/
public static ObjectName getInstance(String domain,
Hashtable<String,String> table)
@@ -1516,143 +1364,7 @@
public static ObjectName getInstance(ObjectName name) {
if (name.getClass().equals(ObjectName.class))
return name;
- return valueOf(name.getSerializedNameString());
- }
-
- /**
- * <p>Return an instance of ObjectName that can be used anywhere
- * an object obtained with {@link #ObjectName(String) new
- * ObjectName(name)} can be used. The returned object may be of
- * a subclass of ObjectName. Calling this method twice with the
- * same parameters may return the same object or two equal but
- * not identical objects.</p>
- *
- * <p>This method is equivalent to {@link #getInstance(String)} except that
- * it does not throw any checked exceptions.</p>
- *
- * @param name A string representation of the object name.
- *
- * @return an ObjectName corresponding to the given String.
- *
- * @exception IllegalArgumentException The string passed as a
- * parameter does not have the right format. The {@linkplain
- * Throwable#getCause() cause} of this exception will be a
- * {@link MalformedObjectNameException}.
- * @exception NullPointerException The <code>name</code> parameter
- * is null.
- *
- * @since 1.7
- */
- public static ObjectName valueOf(String name) {
- try {
- return getInstance(name);
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- // Just plain IllegalArgumentException(e) produces an exception
- // message "javax.management.MalformedObjectNameException: ..."
- // which is distracting.
- }
- }
-
- /**
- * <p>Return an instance of ObjectName that can be used anywhere
- * an object obtained with {@link #ObjectName(String, String,
- * String) new ObjectName(domain, key, value)} can be used. The
- * returned object may be of a subclass of ObjectName. Calling
- * this method twice with the same parameters may return the same
- * object or two equal but not identical objects.</p>
- *
- * <p>This method is equivalent to {@link #getInstance(String, String,
- * String)} except that it does not throw any checked exceptions.</p>
- *
- * @param domain The domain part of the object name.
- * @param key The attribute in the key property of the object name.
- * @param value The value in the key property of the object name.
- *
- * @return an ObjectName corresponding to the given domain,
- * key, and value.
- *
- * @exception IllegalArgumentException The
- * <code>domain</code>, <code>key</code>, or <code>value</code>
- * contains an illegal character, or <code>value</code> does not
- * follow the rules for quoting. The {@linkplain
- * Throwable#getCause() cause} of this exception will be a
- * {@link MalformedObjectNameException}.
- * @exception NullPointerException One of the parameters is null.
- *
- * @since 1.7
- */
- public static ObjectName valueOf(String domain, String key, String value) {
- try {
- return getInstance(domain, key, value);
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
- }
-
- /**
- * <p>Return an instance of ObjectName that can be used anywhere
- * an object obtained with {@link #ObjectName(String, Hashtable)
- * new ObjectName(domain, table)} can be used. The returned
- * object may be of a subclass of ObjectName. Calling this method
- * twice with the same parameters may return the same object or
- * two equal but not identical objects.</p>
- *
- * <p>This method is equivalent to {@link #getInstance(String, Hashtable)}
- * except that it does not throw any checked exceptions.</p>
- *
- * @param domain The domain part of the object name.
- * @param table A hash table containing one or more key
- * properties. The key of each entry in the table is the key of a
- * key property in the object name. The associated value in the
- * table is the associated value in the object name.
- *
- * @return an ObjectName corresponding to the given domain and
- * key mappings.
- *
- * @exception IllegalArgumentException The <code>domain</code>
- * contains an illegal character, or one of the keys or values in
- * <code>table</code> contains an illegal character, or one of the
- * values in <code>table</code> does not follow the rules for
- * quoting. The {@linkplain Throwable#getCause() cause} of this exception
- * will be a {@link MalformedObjectNameException}.
- * @exception NullPointerException One of the parameters is null.
- *
- * @since 1.7
- */
- public static ObjectName valueOf(String domain,
- Hashtable<String,String> table) {
- try {
- return new ObjectName(domain, table);
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
- }
-
- /**
- * Returns an {@code ObjectName} that is the same as this one but
- * with the specified domain.
- * This method preserves the original key order in the new instance.
- * If the provided name has a key property pattern, it will also be
- * preserved in the returned instance.
- *
- * @param newDomain The new domain for the returned instance;
- * must not be null.
- * @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.
- * @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) {
- try {
- return new ObjectName(newDomain, this);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(x.getMessage(),x);
- }
+ return Util.newObjectName(name.getSerializedNameString());
}
/**
@@ -1664,8 +1376,6 @@
* parameter does not have the right format.
* @exception NullPointerException The <code>name</code> parameter
* is null.
- *
- * @see #valueOf(String)
*/
public ObjectName(String name)
throws MalformedObjectNameException {
@@ -1684,8 +1394,6 @@
* contains an illegal character, or <code>value</code> does not
* follow the rules for quoting.
* @exception NullPointerException One of the parameters is null.
- *
- * @see #valueOf(String, String, String)
*/
public ObjectName(String domain, String key, String value)
throws MalformedObjectNameException {
@@ -1711,8 +1419,6 @@
* values in <code>table</code> does not follow the rules for
* quoting.
* @exception NullPointerException One of the parameters is null.
- *
- * @see #valueOf(String, Hashtable)
*/
public ObjectName(String domain, Hashtable<String,String> table)
throws MalformedObjectNameException {
@@ -1814,7 +1520,7 @@
throw new NullPointerException("key property can't be null");
for (int i = 0; i < _ca_array.length; i++) {
Property prop = _ca_array[i];
- String key = prop.getKeyString(_canonicalName,_domain_length);
+ String key = prop.getKeyString(_canonicalName);
if (key.equals(property))
return (prop instanceof PatternProperty);
}
@@ -1894,10 +1600,8 @@
Property prop;
for (int i = len - 1; i >= 0; i--) {
prop = _ca_array[i];
- _propertyList.put(prop.getKeyString(_canonicalName,
- _domain_length),
- prop.getValueString(_canonicalName,
- _domain_length));
+ _propertyList.put(prop.getKeyString(_canonicalName),
+ prop.getValueString(_canonicalName));
}
}
}
@@ -1982,8 +1686,7 @@
}
}
- final String name = new String(dest_chars);
- return name;
+ return new String(dest_chars);
}
/**
@@ -2009,7 +1712,7 @@
for (int i = 0; i < len; i++) {
final Property prop = _kp_array[i];
final int prop_len = prop._key_length + prop._value_length + 1;
- System.arraycopy(value, prop._key_index+_domain_length, dest_chars, index,
+ System.arraycopy(value, prop._key_index, dest_chars, index,
prop_len);
index += prop_len;
if (i < last ) dest_chars[index++] = ',';
@@ -2054,10 +1757,6 @@
return getSerializedNameString();
}
- String toQueryString() {
- return "like " + Query.value(toString());
- }
-
/**
* Compares the current object name with another object name. Two
* ObjectName instances are equal if and only if their canonical
@@ -2218,7 +1917,7 @@
*
* @since 1.6
*/
- public static final ObjectName WILDCARD = valueOf("*:*");
+ public static final ObjectName WILDCARD = Util.newObjectName("*:*");
// Category : Utilities <===================================
@@ -2264,7 +1963,7 @@
// wildmatch domains
// This ObjectName is the pattern
// The other ObjectName is the string.
- return Util.wildpathmatch(name.getDomain(),getDomain());
+ return Util.wildmatch(name.getDomain(),getDomain());
}
return getDomain().equals(name.getDomain());
}
@@ -2290,7 +1989,7 @@
// index in receiver
//
final Property p = props[i];
- final String k = p.getKeyString(cn,_domain_length);
+ final String k = p.getKeyString(cn);
final String v = nameProps.get(k);
// Did we find a value for this key ?
//
@@ -2300,12 +1999,12 @@
if (_property_value_pattern && (p instanceof PatternProperty)) {
// wildmatch key property values
// p is the property pattern, v is the string
- if (Util.wildmatch(v,p.getValueString(cn,_domain_length)))
+ if (Util.wildmatch(v,p.getValueString(cn)))
continue;
else
return false;
}
- if (v.equals(p.getValueString(cn,_domain_length))) continue;
+ if (v.equals(p.getValueString(cn))) continue;
return false;
}
return true;
--- a/jdk/src/share/classes/javax/management/ObjectNameTemplate.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +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 javax.management;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation to allow an MBean to provide its name.
- * This annotation can be used on the following types:
- * <ul>
- * <li>MBean or MXBean Java interface.</li>
- * <li>Java class annotated with {@link javax.management.MBean @MBean}</code>
- * annotation.</li>
- * <li>Java class annotated with {@link javax.management.MXBean @MXBean}</code>
- * annotation.</li>
- * </ul>
- *
- * <p>The value of this annotation is used to build the <code>ObjectName</code>
- * when instances of the annotated type are registered in
- * an <code>MBeanServer</code> and no explicit name is given to the
- * {@code createMBean} or {@code registerMBean} method (the {@code ObjectName}
- * is {@code null}).</p>
- *
- * <p>For Dynamic MBeans, which define their own {@code MBeanInfo}, you can
- * produce the same effect as this annotation by including a field
- * <a href="Descriptor.html#objectNameTemplate">{@code objectNameTemplate}</a>
- * in the {@link Descriptor} for the {@code MBeanInfo} returned by
- * {@link DynamicMBean#getMBeanInfo()}.</p>
- *
- * <p>For Standard MBeans and MXBeans, this annotation automatically produces
- * an {@code objectNameTemplate} field in the {@code Descriptor}.</p>
- *
- * <p>The template can contain variables so that the name of the MBean
- * depends on the value of one or more of its attributes.
- * A variable that identifies an MBean attribute is of the form
- * <code>{<em>attribute name</em>}</code>. For example, to make an MBean name
- * depend on the <code>Name</code> attribute, use the variable
- * <code>{Name}</code>. Attribute names are case sensitive.
- * Naming attributes can be of any type. The <code>String</code> returned by
- * <code>toString()</code> is included in the constructed name.</p>
- *
- * <p>If you need the attribute value to be quoted
- * by a call to {@link ObjectName#quote(String) ObjectName.quote},
- * surround the variable with quotes. Quoting only applies to key values.
- * For example, <code>@ObjectNameTemplate("java.lang:type=MemoryPool,name=\"{Name}\"")</code>,
- * quotes the <code>Name</code> attribute value. You can notice the "\"
- * character needed to escape a quote within a <code>String</code>. A name
- * produced by this template might look like
- * {@code java.lang:type=MemoryPool,name="Code Cache"}.</p>
- *
- * <p>Variables can be used anywhere in the <code>String</code>.
- * Be sure to make the template derived name comply with
- * {@link ObjectName ObjectName} syntax.</p>
- *
- * <p>If an MBean is registered with a null name and it implements
- * {@link javax.management.MBeanRegistration MBeanRegistration}, then
- * the computed name is provided to the <code>preRegister</code> method.
- * Similarly,
- * if the MBean uses <a href="MBeanRegistration.html#injection">resource
- * injection</a> to discover its name, it is the computed name that will
- * be injected.</p>
- * <p>All of the above can be used with the {@link StandardMBean} class and
- * the annotation is effective in that case too.</p>
- * <p>If any exception occurs (such as unknown attribute, invalid syntax or
- * exception
- * thrown by the MBean) when the name is computed it is wrapped in a
- * <code>NotCompliantMBeanException</code>.</p>
- * <p>Some ObjectName template examples:
- * <ul><li>"com.example:type=Memory". Fixed ObjectName. Used to name a
- * singleton MBean.</li>
- * <li>"com.example:type=MemoryPool,name={Name}". Variable ObjectName.
- * <code>Name</code> attribute is retrieved to compose the <code>name</code>
- * key value.</li>
- * <li>"com.example:type=SomeType,name={InstanceName},id={InstanceId}".
- * Variable ObjectName.
- * <code>InstanceName</code> and <code>InstanceId</code> attributes are
- * retrieved to compose respectively
- * the <code>name</code> and <code>id</code> key values.</li>
- * <li>"com.example:type=OtherType,name=\"{ComplexName}\"". Variable ObjectName.
- * <code>ComplexName</code> attribute is retrieved to compose the
- * <code>name</code> key quoted value.</li> </li>
- * <li>"com.example:{TypeKey}=SomeOtherType". Variable ObjectName.
- * <code>TypeKey</code> attribute is retrieved to compose the
- * first key name.</li>
- * * <li>"{Domain}:type=YetAnotherType". Variable ObjectName.
- * <code>Domain</code> attribute is retrieved to compose the
- * management domain.</li>
- * <li>"{Naming}". Variable ObjectName.
- * <code>Naming</code> attribute is retrieved to compose the
- * complete name.</li>
- * </ul>
- * </p>
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface ObjectNameTemplate {
-
- /**
- * The MBean name template.
- * @return The MBean name template.
- */
- @DescriptorKey("objectNameTemplate")
- public String value();
-}
--- a/jdk/src/share/classes/javax/management/OrQueryExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/OrQueryExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -104,24 +104,4 @@
public String toString() {
return "(" + exp1 + ") or (" + exp2 + ")";
}
-
- @Override
- String toQueryString() {
- return parens(exp1) + " or " + parens(exp2);
- }
-
- // Add parentheses to avoid possible confusion. If we have an expression
- // such as Query.or(Query.and(a, b), c), then we return
- // (a and b) or c
- // rather than just
- // a and b or c
- // In fact the precedence rules are such that the parentheses are not
- // strictly necessary, but omitting them would be confusing.
- private static String parens(QueryExp exp) {
- String s = Query.toString(exp);
- if (exp instanceof AndQueryExp)
- return "(" + s + ")";
- else
- return s;
- }
}
--- a/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java Wed Oct 21 16:50:44 2009 +0100
@@ -113,8 +113,7 @@
@Override
public String toString() {
if (className != null) {
- return QueryParser.quoteId(className) + "#" +
- QueryParser.quoteId(super.toString());
+ return className + "." + super.toString();
} else {
return super.toString();
}
--- a/jdk/src/share/classes/javax/management/Query.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/Query.java Wed Oct 21 16:50:44 2009 +0100
@@ -40,14 +40,6 @@
* but the methods in this class return only standard classes that are
* part of the JMX implementation.</p>
*
- * <p>There are two ways to create {@code QueryExp} objects using the methods
- * in this class. The first is to build them by chaining together calls to
- * the various methods. The second is to use the Query Language described
- * <a href="#ql">below</a> and produce the {@code QueryExp} by calling
- * {@link #fromString Query.fromString}. The two ways are equivalent:
- * every {@code QueryExp} returned by {@code fromString} can also be
- * constructed by chaining method calls.</p>
- *
* <p>As an example, suppose you wanted to find all MBeans where the {@code
* Enabled} attribute is {@code true} and the {@code Owner} attribute is {@code
* "Duke"}. Here is how you could construct the appropriate {@code QueryExp} by
@@ -59,307 +51,6 @@
* Query.eq(Query.attr("Owner"), Query.value("Duke")));
* </pre>
*
- * <p>Here is how you could construct the same {@code QueryExp} using the
- * Query Language:</p>
- *
- * <pre>
- * QueryExp query = Query.fromString("Enabled = true and Owner = 'Duke'");
- * </pre>
- *
- * <p>The principal advantage of the method-chaining approach is that the
- * compiler will check that the query makes sense. The principal advantage
- * of the Query Language approach is that it is easier to write and especially
- * read.</p>
- *
- *
- * <h4 id="ql">Query Language</h4>
- *
- * <p>The query language is closely modeled on the WHERE clause of
- * SQL SELECT statements. The formal specification of the language
- * appears <a href="#formal-ql">below</a>, but it is probably easier to
- * understand it with examples such as the following.</p>
- *
- * <dl>
- * <dt>{@code Message = 'OK'}
- * <dd>Selects MBeans that have a {@code Message} attribute whose value
- * is the string {@code OK}.
- *
- * <dt>{@code FreeSpacePercent < 10}
- * <dd>Selects MBeans that have a {@code FreeSpacePercent} attribute whose
- * value is a number less than 10.
- *
- * <dt>{@code FreeSpacePercent < 10 and WarningSent = false}
- * <dd>Selects the same MBeans as the previous example, but they must
- * also have a boolean attribute {@code WarningSent} whose value
- * is false.
- *
- * <dt>{@code SpaceUsed > TotalSpace * (2.0 / 3.0)}
- * <dd>Selects MBeans that have {@code SpaceUsed} and {@code TotalSpace}
- * attributes where the first is more than two-thirds the second.
- *
- * <dt>{@code not (FreeSpacePercent between 10 and 90)}
- * <dd>Selects MBeans that have a {@code FreeSpacePercent} attribute whose
- * value is not between 10 and 90, inclusive.
- *
- * <dt>{@code FreeSpacePercent not between 10 and 90}
- * <dd>Another way of writing the previous query.
- *
- * <dt>{@code Status in ('STOPPED', 'STARTING', 'STARTED')}
- * <dd>Selects MBeans that have a {@code Status} attribute whose value
- * is one of those three strings.
- *
- * <dt>{@code Message like 'OK: *'}
- * <dd>Selects MBeans that have a {@code Message} attribute whose value
- * is a string beginning with {@code "OK: "}. <b>Notice that the
- * wildcard characters are not the ones that SQL uses.</b> In SQL,
- * {@code %} means "any sequence of characters" and {@code _}
- * means "any single character". Here, as in the rest of the JMX API,
- * those are represented by {@code *} and {@code ?} respectively.
- *
- * <dt>{@code instanceof 'javax.management.NotificationBroadcaster'}
- * <dd>Selects MBeans that are instances of
- * {@link javax.management.NotificationBroadcaster}, as reported by
- * {@link javax.management.MBeanServer#isInstanceOf MBeanServer.isInstanceOf}.
- *
- * <dt>{@code like 'mydomain:*'}
- * <dd>Selects MBeans whose {@link ObjectName}s have the domain {@code mydomain}.
- *
- * </dl>
- *
- * <p>The last two examples do not correspond to valid SQL syntax, but all
- * the others do.</p>
- *
- * <p>The remainder of this description is a formal specification of the
- * query language.</p>
- *
- *
- * <h4 id="formal-ql">Lexical elements</h4>
- *
- * <p>Keywords such as <b>and</b>, <b>like</b>, and <b>between</b> are not
- * case sensitive. You can write <b>between</b>, <b>BETWEEN</b>, or
- * <b>BeTwEeN</b> with the same effect.</p>
- *
- * <p>On the other hand, attribute names <i>are</i> case sensitive. The
- * attribute {@code Name} is not the same as the attribute {@code name}.</p>
- *
- * <p>To access an attribute whose name, ignoring case, is the same as one of
- * the keywords {@code not}, {@code instanceof}, {@code like}, {@code true},
- * or {@code false}, you can use double quotes, for example {@code "not"}.
- * Double quotes can also be used to include non-identifier characters in
- * the name of an attribute, for example {@code "attribute-name-with-hyphens"}.
- * To include the double quote character in the attribute name, write it
- * twice. {@code "foo""bar""baz"} represents the attribute called
- * {@code foo"bar"baz}.
- *
- * <p>String constants are written with single quotes like {@code 'this'}. A
- * single quote within a string constant must be doubled, for example
- * {@code 'can''t'}.</p>
- *
- * <p>Integer constants are written as a sequence of decimal digits,
- * optionally preceded by a plus or minus sign. An integer constant must be
- * a valid input to {@link Long#valueOf(String)}.</p>
- *
- * <p>Floating-point constants are written using the Java syntax. A
- * floating-point constant must be a valid input to
- * {@link Double#valueOf(String)}.</p>
- *
- * <p>A boolean constant is either {@code true} or {@code false}, ignoring
- * case.</p>
- *
- * <p>Spaces cannot appear inside identifiers (unless written with double
- * quotes) or keywords or multi-character tokens such as {@code <=}. Spaces can
- * appear anywhere else, but are not required except to separate tokens. For
- * example, the query {@code a < b and 5 = c} could also be written {@code a<b
- * and 5=c}, but no further spaces can be removed.</p>
- *
- *
- * <h4 id="grammar-ql">Grammar</h4>
- *
- * <dl>
- * <dt id="query">query:
- * <dd><a href="#andquery">andquery</a> [<b>OR</b> <a href="#query">query</a>]
- *
- * <dt id="andquery">andquery:
- * <dd><a href="#predicate">predicate</a> [<b>AND</b> <a href="#andquery">andquery</a>]
- *
- * <dt id="predicate">predicate:
- * <dd><b>(</b> <a href="#query">query</a> <b>)</b> |<br>
- * <b>NOT</b> <a href="#predicate">predicate</a> |<br>
- * <b>INSTANCEOF</b> <a href="#stringvalue">stringvalue</a> |<br>
- * <b>LIKE</b> <a href="#objectnamepattern">objectnamepattern</a> |<br>
- * <a href="#value">value</a> <a href="#predrhs">predrhs</a>
- *
- * <dt id="predrhs">predrhs:
- * <dd><a href="#compare">compare</a> <a href="#value">value</a> |<br>
- * [<b>NOT</b>] <b>BETWEEN</b> <a href="#value">value</a> <b>AND</b>
- * <a href="#value">value</a> |<br>
- * [<b>NOT</b>] <b>IN (</b> <a href="#value">value</a>
- * <a href="#commavalues">commavalues</a> <b>)</b> |<br>
- * [<b>NOT</b>] <b>LIKE</b> <a href="#stringvalue">stringvalue</a>
- *
- * <dt id="commavalues">commavalues:
- * <dd>[ <b>,</b> <a href="#value">value</a> <a href="#commavalues">commavalues</a> ]
- *
- * <dt id="compare">compare:
- * <dd><b>=</b> | <b><</b> | <b>></b> |
- * <b><=</b> | <b>>=</b> | <b><></b> | <b>!=</b>
- *
- * <dt id="value">value:
- * <dd><a href="#factor">factor</a> [<a href="#plusorminus">plusorminus</a>
- * <a href="#value">value</a>]
- *
- * <dt id="plusorminus">plusorminus:
- * <dd><b>+</b> | <b>-</b>
- *
- * <dt id="factor">factor:
- * <dd><a href="#term">term</a> [<a href="#timesordivide">timesordivide</a>
- * <a href="#factor">factor</a>]
- *
- * <dt id="timesordivide">timesordivide:
- * <dd><b>*</b> | <b>/</b>
- *
- * <dt id="term">term:
- * <dd><a href="#attr">attr</a> | <a href="#literal">literal</a> |
- * <b>(</b> <a href="#value">value</a> <b>)</b>
- *
- * <dt id="attr">attr:
- * <dd><a href="#name">name</a> [<b>#</b> <a href="#name">name</a>]
- *
- * <dt id="name">name:
- * <dd><a href="#identifier">identifier</a> [<b>.</b><a href="#name">name</a>]
- *
- * <dt id="identifier">identifier:
- * <dd><i>Java-identifier</i> | <i>double-quoted-identifier</i>
- *
- * <dt id="literal">literal:
- * <dd><a href="#booleanlit">booleanlit</a> | <i>longlit</i> |
- * <i>doublelit</i> | <i>stringlit</i>
- *
- * <dt id="booleanlit">booleanlit:
- * <dd><b>FALSE</b> | <b>TRUE</b>
- *
- * <dt id="stringvalue">stringvalue:
- * <dd><i>stringlit</i>
- *
- * <dt id="objectnamepattern">objectnamepattern:
- * <dd><i>stringlit</i>
- *
- * </dl>
- *
- *
- * <h4>Semantics</h4>
- *
- * <p>The meaning of the grammar is described in the table below.
- * This defines a function <i>q</i> that maps a string to a Java object
- * such as a {@link QueryExp} or a {@link ValueExp}.</p>
- *
- * <table border="1" cellpadding="5">
- * <tr><th>String <i>s</i></th><th><i>q(s)</th></tr>
- *
- * <tr><td><i>query1</i> <b>OR</b> <i>query2</i>
- * <td>{@link Query#or Query.or}(<i>q(query1)</i>, <i>q(query2)</i>)
- *
- * <tr><td><i>query1</i> <b>AND</b> <i>query2</i>
- * <td>{@link Query#and Query.and}(<i>q(query1)</i>, <i>q(query2)</i>)
- *
- * <tr><td><b>(</b> <i>queryOrValue</i> <b>)</b>
- * <td><i>q(queryOrValue)</i>
- *
- * <tr><td><b>NOT</b> <i>query</i>
- * <td>{@link Query#not Query.not}(<i>q(query)</i>)
- *
- * <tr><td><b>INSTANCEOF</b> <i>stringLiteral</i>
- * <td>{@link Query#isInstanceOf Query.isInstanceOf}(<!--
- * -->{@link Query#value(String) Query.value}(<i>q(stringLiteral)</i>))
- *
- * <tr><td><b>LIKE</b> <i>stringLiteral</i>
- * <td>{@link ObjectName#ObjectName(String) new ObjectName}(<!--
- * --><i>q(stringLiteral)</i>)
- *
- * <tr><td><i>value1</i> <b>=</b> <i>value2</i>
- * <td>{@link Query#eq Query.eq}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b><</b> <i>value2</i>
- * <td>{@link Query#lt Query.lt}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b>></b> <i>value2</i>
- * <td>{@link Query#gt Query.gt}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b><=</b> <i>value2</i>
- * <td>{@link Query#leq Query.leq}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b>>=</b> <i>value2</i>
- * <td>{@link Query#geq Query.geq}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b><></b> <i>value2</i>
- * <td>{@link Query#not Query.not}({@link Query#eq Query.eq}(<!--
- * --><i>q(value1)</i>, <i>q(value2)</i>))
- *
- * <tr><td><i>value1</i> <b>!=</b> <i>value2</i>
- * <td>{@link Query#not Query.not}({@link Query#eq Query.eq}(<!--
- * --><i>q(value1)</i>, <i>q(value2)</i>))
- *
- * <tr><td><i>value1</i> <b>BETWEEN</b> <i>value2</i> AND <i>value3</i>
- * <td>{@link Query#between Query.between}(<i>q(value1)</i>,
- * <i>q(value2)</i>, <i>q(value3)</i>)
- *
- * <tr><td><i>value1</i> <b>NOT BETWEEN</b> <i>value2</i> AND <i>value3</i>
- * <td>{@link Query#not Query.not}({@link Query#between Query.between}(<!--
- * --><i>q(value1)</i>, <i>q(value2)</i>, <i>q(value3)</i>))
- *
- * <tr><td><i>value1</i> <b>IN (</b> <i>value2</i>, <i>value3</i> <b>)</b>
- * <td>{@link Query#in Query.in}(<i>q(value1)</i>,
- * <code>new ValueExp[] {</code>
- * <i>q(value2)</i>, <i>q(value3)</i><code>}</code>)
- *
- * <tr><td><i>value1</i> <b>NOT IN (</b> <i>value2</i>, <i>value3</i> <b>)</b>
- * <td>{@link Query#not Query.not}({@link Query#in Query.in}(<i>q(value1)</i>,
- * <code>new ValueExp[] {</code>
- * <i>q(value2)</i>, <i>q(value3)</i><code>}</code>))
- *
- * <tr><td><i>value</i> <b>LIKE</b> <i>stringLiteral</i>
- * <td>{@link Query#match Query.match}(<i>q(value)</i>,
- * <i>q(stringLiteral)</i>)
- *
- * <tr><td><i>value</i> <b>NOT LIKE</b> <i>stringLiteral</i>
- * <td>{@link Query#not Query.not}({@link Query#match Query.match}(<i>q(value)</i>,
- * <i>q(stringLiteral)</i>))
- *
- * <tr><td><i>value1</i> <b>+</b> <i>value2</i>
- * <td>{@link Query#plus Query.plus}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b>-</b> <i>value2</i>
- * <td>{@link Query#minus Query.minus}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b>*</b> <i>value2</i>
- * <td>{@link Query#times Query.times}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>value1</i> <b>/</b> <i>value2</i>
- * <td>{@link Query#div Query.div}(<i>q(value1)</i>, <i>q(value2)</i>)
- *
- * <tr><td><i>name</i>
- * <td>{@link Query#attr(String) Query.attr}(<i>q(name)</i>)
- *
- * <tr><td><i>name1<b>#</b>name2</i>
- * <td>{@link Query#attr(String,String) Query.attr}(<i>q(name1)</i>,
- * <i>q(name2)</i>)
- *
- * <tr><td><b>FALSE</b>
- * <td>{@link Query#value(boolean) Query.value}(false)
- *
- * <tr><td><b>TRUE</b>
- * <td>{@link Query#value(boolean) Query.value}(true)
- *
- * <tr><td><i>decimalLiteral</i>
- * <td>{@link Query#value(long) Query.value}(<!--
- * -->{@link Long#valueOf(String) Long.valueOf}(<i>decimalLiteral</i>))
- *
- * <tr><td><i>floatingPointLiteral</i>
- * <td>{@link Query#value(double) Query.value}(<!--
- * -->{@link Double#valueOf(String) Double.valueOf}(<!--
- * --><i>floatingPointLiteral</i>))
- * </table>
- *
* @since 1.5
*/
public class Query extends Object {
@@ -600,6 +291,11 @@
* <p>Returns a new attribute expression. See {@link AttributeValueExp}
* for a detailed description of the semantics of the expression.</p>
*
+ * <p>Evaluating this expression for a given
+ * <code>objectName</code> includes performing {@link
+ * MBeanServer#getAttribute MBeanServer.getAttribute(objectName,
+ * name)}.</p>
+ *
* @param name The name of the attribute.
*
* @return An attribute expression for the attribute named {@code name}.
@@ -944,73 +640,6 @@
}
/**
- * <p>Return a string representation of the given query. The string
- * returned by this method can be converted back into an equivalent
- * query using {@link #fromString fromString}.</p>
- *
- * <p>(Two queries are equivalent if they produce the same result in
- * all cases. Equivalent queries are not necessarily identical:
- * for example the queries {@code Query.lt(Query.attr("A"), Query.attr("B"))}
- * and {@code Query.not(Query.ge(Query.attr("A"), Query.attr("B")))} are
- * equivalent but not identical.)</p>
- *
- * <p>The string returned by this method is only guaranteed to be converted
- * back into an equivalent query if {@code query} was constructed, or
- * could have been constructed, using the methods of this class.
- * If you make a custom query {@code myQuery} by implementing
- * {@link QueryExp} yourself then the result of
- * {@code Query.toString(myQuery)} is unspecified.</p>
- *
- * @param query the query to convert. If it is null, the result will
- * also be null.
- * @return the string representation of the query, or null if the
- * query is null.
- *
- * @since 1.7
- */
- public static String toString(QueryExp query) {
- if (query == null)
- return null;
-
- // This is ugly. At one stage we had a non-public class called
- // ToQueryString with the toQueryString() method, and every class
- // mentioned here inherited from that class. But that interfered
- // with serialization of custom subclasses of e.g. QueryEval. Even
- // though we could make it work by adding a public constructor to this
- // non-public class, that seemed fragile because according to the
- // serialization spec it shouldn't work. If only non-public interfaces
- // could have non-public methods.
- if (query instanceof ObjectName)
- return ((ObjectName) query).toQueryString();
- if (query instanceof QueryEval)
- return ((QueryEval) query).toQueryString();
-
- return query.toString();
- }
-
- /**
- * <p>Produce a query from the given string. The query returned
- * by this method can be converted back into a string using
- * {@link #toString(QueryExp) toString}. The resultant string will
- * not necessarily be equal to {@code s}.</p>
- *
- * @param s the string to convert.
- *
- * @return a {@code QueryExp} derived by parsing the string, or
- * null if the string is null.
- *
- * @throws IllegalArgumentException if the string is not a valid
- * query string.
- *
- * @since 1.7
- */
- public static QueryExp fromString(String s) {
- if (s == null)
- return null;
- return new QueryParser(s).parseQuery();
- }
-
- /**
* Utility method to escape strings used with
* Query.{initial|any|final}SubString() methods.
*/
--- a/jdk/src/share/classes/javax/management/QueryEval.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/QueryEval.java Wed Oct 21 16:50:44 2009 +0100
@@ -75,10 +75,4 @@
public static MBeanServer getMBeanServer() {
return server.get();
}
-
- // Subclasses in this package can override this method to return a different
- // string.
- String toQueryString() {
- return toString();
- }
}
--- a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,415 +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 javax.management;
-
-import com.sun.jmx.mbeanserver.NotificationMBeanSupport;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * <p>General-purpose notification filter. This filter can be used to
- * filter notifications from a possibly-remote MBean. Most filtering
- * decisions can be coded using this filter, which avoids having to
- * write a custom implementation of the {@link NotificationFilter}
- * class. Writing a custom implementation requires you to deploy it
- * on both the client and the server in the remote case, so using this class
- * instead is recommended where possible.</p>
- *
- * <p>Because this class was introduced in version 2.0 of the JMX API,
- * it may not be present on a remote JMX agent that is running an earlier
- * version. The method {@link JMX#getSpecificationVersion
- * JMX.getSpecificationVersion} can be used to determine the remote version.</p>
- *
- * <p>This class uses the {@linkplain Query Query API} to specify the
- * filtering logic. For example, to select only notifications where the
- * {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
- * you could use</p>
- *
- * <pre>
- * NotificationFilter filter =
- * new QueryNotificationFilter("Type = 'com.example.mytype'");
- * </pre>
- *
- * <p>or equivalently</p>
- *
- * <pre>
- * NotificationFilter filter =
- * new QueryNotificationFilter(
- * Query.eq(Query.attr("Type"), Query.value("com.example.mytype")));
- * </pre>
- *
- * <p>(This particular example could also use
- * {@link NotificationFilterSupport}.)</p>
- *
- * <p>Here are some other examples of filters you can specify with this class.</p>
- *
- * <dl>
- *
- * <dt>{@code QueryNotificationFilter("Type = 'com.example.type1' or
- * Type = 'com.example.type2'")}
- * <dd>Notifications where the type is either of the given strings.
- *
- * <dt>{@code QueryNotificationFilter("Type in ('com.example.type1',
- * 'com.example.type2')")}
- * <dd>Another way to write the previous example.
- *
- * <dt>{@code QueryNotificationFilter("SequenceNumber > 1000")}
- * <dd>Notifications where the {@linkplain Notification#getSequenceNumber()
- * sequence number} is greater than 1000.
- *
- * <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class, null)}
- * <dd>Notifications where the notification class is
- * {@link AttributeChangeNotification} or a subclass of it.
- *
- * <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class,
- * "AttributeName = 'Size'")}
- * <dd>Notifications where the notification class is
- * {@link AttributeChangeNotification} or a subclass, and where the
- * {@linkplain AttributeChangeNotification#getAttributeName() name of the
- * changed attribute} is {@code Size}.
- *
- * <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class,
- * "AttributeName = 'Size' and NewValue - OldValue > 100")}
- * <dd>As above, but the difference between the
- * {@linkplain AttributeChangeNotification#getNewValue() new value} and the
- * {@linkplain AttributeChangeNotification#getOldValue() old value} must be
- * greater than 100.
- *
- * <dt>{@code QueryNotificationFilter("like 'com.example.mydomain:*'")}
- * <dd>Notifications where the {@linkplain Notification#getSource() source}
- * is an ObjectName that matches the pattern.
- *
- * <dt>{@code QueryNotificationFilter("Source.canonicalName like
- * 'com.example.mydomain:%'")}
- * <dd>Another way to write the previous example.
- *
- * <dt>{@code QueryNotificationFilter(MBeanServerNotification.class,
- * "Type = 'JMX.mbean.registered' and MBeanName.canonicalName like
- * 'com.example.mydomain:%'")}
- * <dd>Notifications of class {@link MBeanServerNotification} representing
- * an object registered in the domain {@code com.example.mydomain}.
- *
- * </dl>
- *
- * <h4>How it works</h4>
- *
- * <p>Although the examples above are clear, looking closely at the
- * Query API reveals a subtlety. A {@link QueryExp} is evaluated on
- * an {@link ObjectName}, not a {@code Notification}.</p>
- *
- * <p>Every time a {@code Notification} is to be filtered by a
- * {@code QueryNotificationFilter}, a special {@link MBeanServer} is created.
- * This {@code MBeanServer} contains exactly one MBean, which represents the
- * {@code Notification}. If the {@linkplain Notification#getSource()
- * source} of the notification is an {@code ObjectName}, which is
- * recommended practice, then the name of the MBean representing the
- * {@code Notification} will be this {@code ObjectName}. Otherwise the
- * name is unspecified.</p>
- *
- * <p>The query specified in the {@code QueryNotificationFilter} constructor
- * is evaluated against this {@code MBeanServer} and {@code ObjectName},
- * and the filter returns true if and only if the query does. If the
- * query throws an exception, then the filter will return false.</p>
- *
- * <p>The MBean representing the {@code Notification} has one attribute for
- * every property of the {@code Notification}. Specifically, for every public
- * method {@code T getX()} in the {@code NotificationClass}, the MBean will
- * have an attribute called {@code X} of type {@code T}. For example, if the
- * {@code Notification} is an {@code AttributeChangeNotification}, then the
- * MBean will have an attribute called {@code AttributeName} of type
- * {@code "java.lang.String"}, corresponding to the method {@link
- * AttributeChangeNotification#getAttributeName}.</p>
- *
- * <p>Query evaluation usually involves calls to the methods of {@code
- * MBeanServer}. The methods have the following behavior:</p>
- *
- * <ul>
- * <li>The {@link MBeanServer#getAttribute getAttribute} method returns the
- * value of the corresponding property.
- * <li>The {@link MBeanServer#getObjectInstance getObjectInstance}
- * method returns an {@link ObjectInstance} where the {@link
- * ObjectInstance#getObjectName ObjectName} is the name of the MBean and the
- * {@link ObjectInstance#getClassName ClassName} is the class name of the
- * {@code Notification}.
- * <li>The {@link MBeanServer#isInstanceOf isInstanceOf} method returns true
- * if and only if the {@code Notification}'s {@code ClassLoader} can load the
- * named class, and the {@code Notification} is an {@linkplain Class#isInstance
- * instance} of that class.
- * </ul>
- *
- * <p>These are the only {@code MBeanServer} methods that are needed to
- * evaluate standard queries. The behavior of the other {@code MBeanServer}
- * methods is unspecified.</p>
- *
- * @since 1.7
- */
-public class QueryNotificationFilter implements NotificationFilter {
- private static final long serialVersionUID = -8408613922660635231L;
-
- private static final ObjectName DEFAULT_NAME =
- ObjectName.valueOf(":type=Notification");
- private static final QueryExp trueQuery;
- static {
- ValueExp zero = Query.value(0);
- trueQuery = Query.eq(zero, zero);
- }
-
- private final QueryExp query;
-
- /**
- * Construct a {@code QueryNotificationFilter} that evaluates the given
- * {@code QueryExp} to determine whether to accept a notification.
- *
- * @param query the {@code QueryExp} to evaluate. Can be null,
- * in which case all notifications are accepted.
- */
- public QueryNotificationFilter(QueryExp query) {
- if (query == null)
- this.query = trueQuery;
- else
- this.query = query;
- }
-
- /**
- * Construct a {@code QueryNotificationFilter} that evaluates the query
- * in the given string to determine whether to accept a notification.
- * The string is converted into a {@code QueryExp} using
- * {@link Query#fromString Query.fromString}.
- *
- * @param query the string specifying the query to evaluate. Can be null,
- * in which case all notifications are accepted.
- *
- * @throws IllegalArgumentException if the string is not a valid
- * query string.
- */
- public QueryNotificationFilter(String query) {
- this(Query.fromString(query));
- }
-
- /**
- * <p>Construct a {@code QueryNotificationFilter} that evaluates the query
- * in the given string to determine whether to accept a notification,
- * and where the notification must also be an instance of the given class.
- * The string is converted into a {@code QueryExp} using
- * {@link Query#fromString Query.fromString}.</p>
- *
- * @param notifClass the class that the notification must be an instance of.
- * Cannot be null.
- *
- * @param query the string specifying the query to evaluate. Can be null,
- * in which case all notifications are accepted.
- *
- * @throws IllegalArgumentException if the string is not a valid
- * query string, or if {@code notifClass} is null.
- */
- public QueryNotificationFilter(
- Class<? extends Notification> notifClass, String query) {
- this(Query.and(Query.isInstanceOf(Query.value(notNull(notifClass).getName())),
- Query.fromString(query)));
- }
-
- private static <T> T notNull(T x) {
- if (x == null)
- throw new IllegalArgumentException("Null argument");
- return x;
- }
-
- /**
- * Retrieve the query that this notification filter will evaluate for
- * each notification.
- *
- * @return the query.
- */
- public QueryExp getQuery() {
- return query;
- }
-
- public boolean isNotificationEnabled(Notification notification) {
- ObjectName name;
-
- Object source = notification.getSource();
- if (source instanceof ObjectName)
- name = (ObjectName) source;
- else
- name = DEFAULT_NAME;
-
- MBS mbsImpl = new MBS(notification, name);
- MBeanServer mbs = (MBeanServer) Proxy.newProxyInstance(
- MBeanServer.class.getClassLoader(),
- new Class<?>[] {MBeanServer.class},
- new ForwardIH(mbsImpl));
- return evalQuery(query, mbs, name);
- }
-
- private static boolean evalQuery(
- QueryExp query, MBeanServer mbs, ObjectName name) {
- MBeanServer oldMBS = QueryEval.getMBeanServer();
- try {
- if (mbs != null)
- query.setMBeanServer(mbs);
- return query.apply(name);
- } catch (Exception e) {
- return false;
- } finally {
- query.setMBeanServer(oldMBS);
- }
- }
-
- private static class ForwardIH implements InvocationHandler {
- private final MBS mbs;
-
- ForwardIH(MBS mbs) {
- this.mbs = mbs;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- Method forward;
- try {
- forward = MBS.class.getMethod(
- method.getName(), method.getParameterTypes());
- } catch (NoSuchMethodException e) {
- throw new UnsupportedOperationException(method.getName());
- }
- try {
- return forward.invoke(mbs, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- }
-
- private static class MBS {
- private final Notification notification;
- private final ObjectName objectName;
- private final ObjectInstance objectInstance;
- private volatile DynamicMBean mbean;
-
- MBS(Notification n, ObjectName name) {
- this.notification = n;
- this.objectName = name;
- this.objectInstance = new ObjectInstance(name, n.getClass().getName());
- }
-
- private void checkName(ObjectName name) throws InstanceNotFoundException {
- if (!objectName.equals(name))
- throw new InstanceNotFoundException(String.valueOf(name));
- }
-
- private DynamicMBean mbean(ObjectName name)
- throws InstanceNotFoundException, ReflectionException {
- if (mbean == null) {
- try {
- mbean = new NotificationMBeanSupport(notification);
- } catch (NotCompliantMBeanException e) {
- throw new ReflectionException(e);
- }
- }
- return mbean;
- }
-
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- checkName(name);
- return objectInstance;
- }
-
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- Set<ObjectName> names = queryNames(name, query);
- switch (names.size()) {
- case 0:
- return Collections.emptySet();
- case 1:
- return Collections.singleton(objectInstance);
- default:
- throw new UnsupportedOperationException("Internal error");
- }
- }
-
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- if ((name != null && !name.apply(objectName)) ||
- (query != null && !evalQuery(query, null, name)))
- return Collections.emptySet();
- return Collections.singleton(objectName);
- }
-
- public boolean isRegistered(ObjectName name) {
- return objectName.equals(name);
- }
-
- public Integer getMBeanCount() {
- return 1;
- }
-
- public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException,
- InstanceNotFoundException, ReflectionException {
- return mbean(name).getAttribute(attribute);
- }
-
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- return mbean(name).getAttributes(attributes);
- }
-
- public String getDefaultDomain() {
- return objectName.getDomain();
- }
-
- public String[] getDomains() {
- return new String[] {objectName.getDomain()};
- }
-
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, ReflectionException {
- return mbean(name).getMBeanInfo();
- }
-
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- try {
- mbean(name);
- ClassLoader loader = notification.getClass().getClassLoader();
- Class<?> c = Class.forName(className, false, loader);
- return c.isInstance(notification);
- } catch (ReflectionException e) {
- return false;
- } catch (ClassNotFoundException e) {
- return false;
- }
- }
-
- public ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- checkName(mbeanName);
- return notification.getClass().getClassLoader();
- }
- }
-}
--- a/jdk/src/share/classes/javax/management/QueryParser.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,626 +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 javax.management;
-
-import java.util.ArrayList;
-import java.util.Formatter;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * <p>Parser for JMX queries represented in an SQL-like language.</p>
- */
-/*
- * Note that if a query starts with ( then we don't know whether it is
- * a predicate or just a value that is parenthesized. So, inefficiently,
- * we try to parse a predicate and if that doesn't work we try to parse
- * a value.
- */
-class QueryParser {
- // LEXER STARTS HERE
-
- private static class Token {
- final String string;
- Token(String s) {
- this.string = s;
- }
-
- @Override
- public String toString() {
- return string;
- }
- }
-
- private static final Token
- END = new Token("<end of string>"),
- LPAR = new Token("("), RPAR = new Token(")"),
- COMMA = new Token(","), DOT = new Token("."), SHARP = new Token("#"),
- PLUS = new Token("+"), MINUS = new Token("-"),
- TIMES = new Token("*"), DIVIDE = new Token("/"),
- LT = new Token("<"), GT = new Token(">"),
- LE = new Token("<="), GE = new Token(">="),
- NE = new Token("<>"), EQ = new Token("="),
- NOT = new Id("NOT"), INSTANCEOF = new Id("INSTANCEOF"),
- FALSE = new Id("FALSE"), TRUE = new Id("TRUE"),
- BETWEEN = new Id("BETWEEN"), AND = new Id("AND"),
- OR = new Id("OR"), IN = new Id("IN"),
- LIKE = new Id("LIKE"), CLASS = new Id("CLASS");
-
- // Keywords that can appear where an identifier can appear.
- // If an attribute is one of these, then it must be quoted when
- // converting a query into a string.
- // We use a TreeSet so we can look up case-insensitively.
- private static final Set<String> idKeywords =
- new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
- static {
- for (Token t : new Token[] {NOT, INSTANCEOF, FALSE, TRUE, LIKE, CLASS})
- idKeywords.add(t.string);
- };
-
- public static String quoteId(String id) {
- if (id.contains("\"") || idKeywords.contains(id))
- return '"' + id.replace("\"", "\"\"") + '"';
- else
- return id;
- }
-
- private static class Id extends Token {
- Id(String id) {
- super(id);
- }
-
- // All other tokens use object identity, which means e.g. that one
- // occurrence of the string constant 'x' is not the same as another.
- // For identifiers, we ignore case when testing for equality so that
- // for a keyword such as AND you can also spell it as "And" or "and".
- // But we keep the original case of the identifier, so if it's not
- // a keyword we will distinguish between the attribute Foo and the
- // attribute FOO.
- @Override
- public boolean equals(Object o) {
- return (o instanceof Id && (((Id) o).toString().equalsIgnoreCase(toString())));
- }
- }
-
- private static class QuotedId extends Token {
- QuotedId(String id) {
- super(id);
- }
-
- @Override
- public String toString() {
- return '"' + string.replace("\"", "\"\"") + '"';
- }
- }
-
- private static class StringLit extends Token {
- StringLit(String s) {
- super(s);
- }
-
- @Override
- public String toString() {
- return '\'' + string.replace("'", "''") + '\'';
- }
- }
-
- private static class LongLit extends Token {
- long number;
-
- LongLit(long number) {
- super(Long.toString(number));
- this.number = number;
- }
- }
-
- private static class DoubleLit extends Token {
- double number;
-
- DoubleLit(double number) {
- super(Double.toString(number));
- this.number = number;
- }
- }
-
- private static class Tokenizer {
- private final String s;
- private final int len;
- private int i = 0;
-
- Tokenizer(String s) {
- this.s = s;
- this.len = s.length();
- }
-
- private int thisChar() {
- if (i == len)
- return -1;
- return s.codePointAt(i);
- }
-
- private void advance() {
- i += Character.charCount(thisChar());
- }
-
- private int thisCharAdvance() {
- int c = thisChar();
- advance();
- return c;
- }
-
- Token nextToken() {
- // In this method, c is the character we're looking at, and
- // thisChar() is the character after that. Everything must
- // preserve these invariants. When we return we then have
- // thisChar() being the start of the following token, so
- // the next call to nextToken() will begin from there.
- int c;
-
- // Skip space
- do {
- if (i == len)
- return null;
- c = thisCharAdvance();
- } while (Character.isWhitespace(c));
-
- // Now c is the first character of the token, and tokenI points
- // to the character after that.
- switch (c) {
- case '(': return LPAR;
- case ')': return RPAR;
- case ',': return COMMA;
- case '.': return DOT;
- case '#': return SHARP;
- case '*': return TIMES;
- case '/': return DIVIDE;
- case '=': return EQ;
- case '-': return MINUS;
- case '+': return PLUS;
-
- case '>':
- if (thisChar() == '=') {
- advance();
- return GE;
- } else
- return GT;
-
- case '<':
- c = thisChar();
- switch (c) {
- case '=': advance(); return LE;
- case '>': advance(); return NE;
- default: return LT;
- }
-
- case '!':
- if (thisCharAdvance() != '=')
- throw new IllegalArgumentException("'!' must be followed by '='");
- return NE;
-
- case '"':
- case '\'': {
- int quote = c;
- StringBuilder sb = new StringBuilder();
- while (true) {
- while ((c = thisChar()) != quote) {
- if (c < 0) {
- throw new IllegalArgumentException(
- "Unterminated string constant");
- }
- sb.appendCodePoint(thisCharAdvance());
- }
- advance();
- if (thisChar() == quote) {
- sb.appendCodePoint(quote);
- advance();
- } else
- break;
- }
- if (quote == '\'')
- return new StringLit(sb.toString());
- else
- return new QuotedId(sb.toString());
- }
- }
-
- // Is it a numeric constant?
- if (Character.isDigit(c) || c == '.') {
- StringBuilder sb = new StringBuilder();
- int lastc = -1;
- while (true) {
- sb.appendCodePoint(c);
- c = Character.toLowerCase(thisChar());
- if (c == '+' || c == '-') {
- if (lastc != 'e')
- break;
- } else if (!Character.isDigit(c) && c != '.' && c != 'e')
- break;
- lastc = c;
- advance();
- }
- String s = sb.toString();
- if (s.indexOf('.') >= 0 || s.indexOf('e') >= 0) {
- double d = parseDoubleCheckOverflow(s);
- return new DoubleLit(d);
- } else {
- // Like the Java language, we allow the numeric constant
- // x where -x = Long.MIN_VALUE, even though x is not
- // representable as a long (it is Long.MAX_VALUE + 1).
- // Code in the parser will reject this value if it is
- // not the operand of unary minus.
- long l = -Long.parseLong("-" + s);
- return new LongLit(l);
- }
- }
-
- // It must be an identifier.
- if (!Character.isJavaIdentifierStart(c)) {
- StringBuilder sb = new StringBuilder();
- Formatter f = new Formatter(sb);
- f.format("Bad character: %c (%04x)", c, c);
- throw new IllegalArgumentException(sb.toString());
- }
-
- StringBuilder id = new StringBuilder();
- while (true) { // identifier
- id.appendCodePoint(c);
- c = thisChar();
- if (!Character.isJavaIdentifierPart(c))
- break;
- advance();
- }
-
- return new Id(id.toString());
- }
- }
-
- /* Parse a double as a Java compiler would do it, throwing an exception
- * if the input does not fit in a double. We assume that the input
- * string is not "Infinity" and does not have a leading sign.
- */
- private static double parseDoubleCheckOverflow(String s) {
- double d = Double.parseDouble(s);
- if (Double.isInfinite(d))
- throw new NumberFormatException("Overflow: " + s);
- if (d == 0.0) { // Underflow checking is hard! CR 6604864
- String ss = s;
- int e = s.indexOf('e'); // we already forced E to lowercase
- if (e > 0)
- ss = s.substring(0, e);
- ss = ss.replace("0", "").replace(".", "");
- if (!ss.equals(""))
- throw new NumberFormatException("Underflow: " + s);
- }
- return d;
- }
-
- // PARSER STARTS HERE
-
- private final List<Token> tokens;
- private int tokenI;
- // The current token is always tokens[tokenI].
-
- QueryParser(String s) {
- // Construct the complete list of tokens immediately and append
- // a sentinel (END).
- tokens = new ArrayList<Token>();
- Tokenizer tokenizer = new Tokenizer(s);
- Token t;
- while ((t = tokenizer.nextToken()) != null)
- tokens.add(t);
- tokens.add(END);
- }
-
- private Token current() {
- return tokens.get(tokenI);
- }
-
- // If the current token is t, then skip it and return true.
- // Otherwise, return false.
- private boolean skip(Token t) {
- if (t.equals(current())) {
- tokenI++;
- return true;
- }
- return false;
- }
-
- // If the current token is one of the ones in 'tokens', then skip it
- // and return its index in 'tokens'. Otherwise, return -1.
- private int skipOne(Token... tokens) {
- for (int i = 0; i < tokens.length; i++) {
- if (skip(tokens[i]))
- return i;
- }
- return -1;
- }
-
- // If the current token is t, then skip it and return.
- // Otherwise throw an exception.
- private void expect(Token t) {
- if (!skip(t))
- throw new IllegalArgumentException("Expected " + t + ", found " + current());
- }
-
- private void next() {
- tokenI++;
- }
-
- QueryExp parseQuery() {
- QueryExp qe = query();
- if (current() != END)
- throw new IllegalArgumentException("Junk at end of query: " + current());
- return qe;
- }
-
- // The remainder of this class is a classical recursive-descent parser.
- // We only need to violate the recursive-descent scheme in one place,
- // where parentheses make the grammar not LL(1).
-
- private QueryExp query() {
- QueryExp lhs = andquery();
- while (skip(OR))
- lhs = Query.or(lhs, andquery());
- return lhs;
- }
-
- private QueryExp andquery() {
- QueryExp lhs = predicate();
- while (skip(AND))
- lhs = Query.and(lhs, predicate());
- return lhs;
- }
-
- private QueryExp predicate() {
- // Grammar hack. If we see a paren, it might be (query) or
- // it might be (value). We try to parse (query), and if that
- // fails, we parse (value). For example, if the string is
- // "(2+3)*4 < 5" then we will try to parse the query
- // "2+3)*4 < 5", which will fail at the ), so we'll back up to
- // the paren and let value() handle it.
- if (skip(LPAR)) {
- int parenIndex = tokenI - 1;
- try {
- QueryExp qe = query();
- expect(RPAR);
- return qe;
- } catch (IllegalArgumentException e) {
- // OK: try parsing a value
- }
- tokenI = parenIndex;
- }
-
- if (skip(NOT))
- return Query.not(predicate());
-
- if (skip(INSTANCEOF))
- return Query.isInstanceOf(stringvalue());
-
- if (skip(LIKE)) {
- StringValueExp sve = stringvalue();
- String s = sve.getValue();
- try {
- return new ObjectName(s);
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException(
- "Bad ObjectName pattern after LIKE: '" + s + "'", e);
- }
- }
-
- ValueExp lhs = value();
-
- return predrhs(lhs);
- }
-
- // The order of elements in the following arrays is important. The code
- // in predrhs depends on integer indexes. Change with caution.
- private static final Token[] relations = {
- EQ, LT, GT, LE, GE, NE,
- // 0, 1, 2, 3, 4, 5,
- };
- private static final Token[] betweenLikeIn = {
- BETWEEN, LIKE, IN
- // 0, 1, 2,
- };
-
- private QueryExp predrhs(ValueExp lhs) {
- Token start = current(); // for errors
-
- // Look for < > = etc
- int i = skipOne(relations);
- if (i >= 0) {
- ValueExp rhs = value();
- switch (i) {
- case 0: return Query.eq(lhs, rhs);
- case 1: return Query.lt(lhs, rhs);
- case 2: return Query.gt(lhs, rhs);
- case 3: return Query.leq(lhs, rhs);
- case 4: return Query.geq(lhs, rhs);
- case 5: return Query.not(Query.eq(lhs, rhs));
- // There is no Query.ne so <> is shorthand for the above.
- default:
- throw new AssertionError();
- }
- }
-
- // Must be BETWEEN LIKE or IN, optionally preceded by NOT
- boolean not = skip(NOT);
- i = skipOne(betweenLikeIn);
- if (i < 0)
- throw new IllegalArgumentException("Expected relation at " + start);
-
- QueryExp q;
- switch (i) {
- case 0: { // BETWEEN
- ValueExp lower = value();
- expect(AND);
- ValueExp upper = value();
- q = Query.between(lhs, lower, upper);
- break;
- }
-
- case 1: { // LIKE
- if (!(lhs instanceof AttributeValueExp)) {
- throw new IllegalArgumentException(
- "Left-hand side of LIKE must be an attribute");
- }
- AttributeValueExp alhs = (AttributeValueExp) lhs;
- StringValueExp sve = stringvalue();
- q = Query.match(alhs, sve);
- break;
- }
-
- case 2: { // IN
- expect(LPAR);
- List<ValueExp> values = new ArrayList<ValueExp>();
- values.add(value());
- while (skip(COMMA))
- values.add(value());
- expect(RPAR);
- q = Query.in(lhs, values.toArray(new ValueExp[values.size()]));
- break;
- }
-
- default:
- throw new AssertionError();
- }
-
- if (not)
- q = Query.not(q);
-
- return q;
- }
-
- private ValueExp value() {
- ValueExp lhs = factor();
- int i;
- while ((i = skipOne(PLUS, MINUS)) >= 0) {
- ValueExp rhs = factor();
- if (i == 0)
- lhs = Query.plus(lhs, rhs);
- else
- lhs = Query.minus(lhs, rhs);
- }
- return lhs;
- }
-
- private ValueExp factor() {
- ValueExp lhs = term();
- int i;
- while ((i = skipOne(TIMES, DIVIDE)) >= 0) {
- ValueExp rhs = term();
- if (i == 0)
- lhs = Query.times(lhs, rhs);
- else
- lhs = Query.div(lhs, rhs);
- }
- return lhs;
- }
-
- private ValueExp term() {
- boolean signed = false;
- int sign = +1;
- if (skip(PLUS))
- signed = true;
- else if (skip(MINUS)) {
- signed = true; sign = -1;
- }
-
- Token t = current();
- next();
-
- if (t instanceof DoubleLit)
- return Query.value(sign * ((DoubleLit) t).number);
- if (t instanceof LongLit) {
- long n = ((LongLit) t).number;
- if (n == Long.MIN_VALUE && sign != -1)
- throw new IllegalArgumentException("Illegal positive integer: " + n);
- return Query.value(sign * n);
- }
- if (signed)
- throw new IllegalArgumentException("Expected number after + or -");
-
- if (t == LPAR) {
- ValueExp v = value();
- expect(RPAR);
- return v;
- }
- if (t.equals(FALSE) || t.equals(TRUE)) {
- return Query.value(t.equals(TRUE));
- }
- if (t.equals(CLASS))
- return Query.classattr();
-
- if (t instanceof StringLit)
- return Query.value(t.string); // Not toString(), which would requote '
-
- // At this point, all that remains is something that will call Query.attr
-
- if (!(t instanceof Id) && !(t instanceof QuotedId))
- throw new IllegalArgumentException("Unexpected token " + t);
-
- String name1 = name(t);
-
- if (skip(SHARP)) {
- Token t2 = current();
- next();
- String name2 = name(t2);
- return Query.attr(name1, name2);
- }
- return Query.attr(name1);
- }
-
- // Initially, t is the first token of a supposed name and current()
- // is the second.
- private String name(Token t) {
- StringBuilder sb = new StringBuilder();
- while (true) {
- if (!(t instanceof Id) && !(t instanceof QuotedId))
- throw new IllegalArgumentException("Unexpected token " + t);
- sb.append(t.string);
- if (current() != DOT)
- break;
- sb.append('.');
- next();
- t = current();
- next();
- }
- return sb.toString();
- }
-
- private StringValueExp stringvalue() {
- // Currently the only way to get a StringValueExp when constructing
- // a QueryExp is via Query.value(String), so we only recognize
- // string literals here. But if we expand queries in the future
- // that might no longer be true.
- Token t = current();
- next();
- if (!(t instanceof StringLit))
- throw new IllegalArgumentException("Expected string: " + t);
- return Query.value(t.string);
- }
-}
--- a/jdk/src/share/classes/javax/management/SendNotification.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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 javax.management;
-
-/**
- * Interface implemented by objects that can be asked to send a notification.
- */
-public interface SendNotification {
- /**
- * Sends a notification.
- *
- * @param notification The notification to send.
- */
- public void sendNotification(Notification notification);
-}
--- a/jdk/src/share/classes/javax/management/StandardEmitterMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/StandardEmitterMBean.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,10 +25,6 @@
package javax.management;
-import com.sun.jmx.mbeanserver.MBeanInjector;
-import com.sun.jmx.mbeanserver.MBeanIntrospector;
-import static javax.management.JMX.MBeanOptions;
-
/**
* <p>An MBean whose management interface is determined by reflection
* on a Java interface, and that emits notifications.</p>
@@ -66,7 +62,7 @@
* @since 1.6
*/
public class StandardEmitterMBean extends StandardMBean
- implements NotificationEmitter, SendNotification {
+ implements NotificationEmitter {
private final NotificationEmitter emitter;
private final MBeanNotificationInfo[] notificationInfo;
@@ -80,10 +76,9 @@
* for {@code implementation} and {@code emitter} to be the same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
- * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
- * then the MBean's {@link #sendNotification
+ * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
- * SendNotification#sendNotification sendNotification}.</p>
+ * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
@@ -95,18 +90,20 @@
*
* @param implementation the implementation of the MBean interface.
* @param mbeanInterface a Standard MBean interface.
- * @param emitter the object that will handle notifications. If null,
- * a new {@code NotificationEmitter} will be constructed that also
- * implements {@link SendNotification}.
+ * @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
- * specified interface.
+ * specified interface, or if {@code emitter} is null.
*/
public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
NotificationEmitter emitter) {
- this(implementation, mbeanInterface, false, emitter);
+ super(implementation, mbeanInterface, false);
+ if (emitter == null)
+ throw new IllegalArgumentException("Null emitter");
+ this.emitter = emitter;
+ this.notificationInfo = emitter.getNotificationInfo();
}
/**
@@ -121,10 +118,9 @@
* same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
- * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
- * then the MBean's {@link #sendNotification
+ * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
- * SendNotification#sendNotification sendNotification}.</p>
+ * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
@@ -138,71 +134,21 @@
* @param mbeanInterface a Standard MBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
- * @param emitter the object that will handle notifications. If null,
- * a new {@code NotificationEmitter} will be constructed that also
- * implements {@link SendNotification}.
+ * @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
- * specified interface.
+ * specified interface, or if {@code emitter} is null.
*/
public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
boolean isMXBean,
NotificationEmitter emitter) {
- this(implementation, mbeanInterface,
- isMXBean ? MBeanOptions.MXBEAN : null, emitter);
- }
-
- /**
- * <p>Make an MBean whose management interface is specified by {@code
- * mbeanInterface}, with the given implementation and options, and where
- * notifications are handled by the given {@code NotificationEmitter}.
- * Options select whether to make a Standard MBean or an MXBean, and
- * whether the result of {@link #getWrappedObject()} is the {@code
- * StandardEmitterMBean} object or the given implementation. The resultant
- * MBean implements the {@code NotificationEmitter} interface by forwarding
- * its methods to {@code emitter}. It is legal and useful for {@code
- * implementation} and {@code emitter} to be the same object.</p>
- *
- * <p>If {@code emitter} is an instance of {@code
- * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
- * then the MBean's {@link #sendNotification
- * sendNotification} method will call {@code emitter.}{@link
- * SendNotification#sendNotification sendNotification}.</p>
- *
- * <p>The array returned by {@link #getNotificationInfo()} on the
- * new MBean is a copy of the array returned by
- * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
- * getNotificationInfo()} at the time of construction. If the array
- * returned by {@code emitter.getNotificationInfo()} later changes,
- * that will have no effect on this object's
- * {@code getNotificationInfo()}.</p>
- *
- * @param implementation the implementation of the MBean interface.
- * @param mbeanInterface a Standard MBean interface.
- * @param options MBeanOptions that control the operation of the resulting
- * MBean.
- * @param emitter the object that will handle notifications. If null,
- * a new {@code NotificationEmitter} will be constructed that also
- * implements {@link SendNotification}.
- *
- * @throws IllegalArgumentException if the {@code mbeanInterface}
- * does not follow JMX design patterns for Management Interfaces, or
- * if the given {@code implementation} does not implement the
- * specified interface.
- */
- public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
- MBeanOptions options,
- NotificationEmitter emitter) {
- super(implementation, mbeanInterface, options);
- MBeanNotificationInfo[] defaultMBNIs = defaultMBNIs(implementation);
+ super(implementation, mbeanInterface, isMXBean);
if (emitter == null)
- emitter = defaultEmitter(defaultMBNIs);
+ throw new IllegalArgumentException("Null emitter");
this.emitter = emitter;
- this.notificationInfo =
- firstNonEmpty(emitter.getNotificationInfo(), defaultMBNIs);
- injectEmitter();
+ this.notificationInfo = emitter.getNotificationInfo();
}
/**
@@ -213,10 +159,9 @@
* by forwarding its methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
- * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
- * then the MBean's {@link #sendNotification
+ * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
- * SendNotification#sendNotification sendNotification}.</p>
+ * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
@@ -230,17 +175,20 @@
* the given {@code mbeanInterface}.</p>
*
* @param mbeanInterface a StandardMBean interface.
- * @param emitter the object that will handle notifications. If null,
- * a new {@code NotificationEmitter} will be constructed that also
- * implements {@link SendNotification}.
+ * @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
- * if {@code this} does not implement the specified interface.
+ * if {@code this} does not implement the specified interface, or
+ * if {@code emitter} is null.
*/
protected StandardEmitterMBean(Class<?> mbeanInterface,
NotificationEmitter emitter) {
- this(mbeanInterface, false, emitter);
+ super(mbeanInterface, false);
+ if (emitter == null)
+ throw new IllegalArgumentException("Null emitter");
+ this.emitter = emitter;
+ this.notificationInfo = emitter.getNotificationInfo();
}
/**
@@ -252,10 +200,9 @@
* forwarding its methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
- * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
- * then the MBean's {@link #sendNotification
+ * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
- * SendNotification#sendNotification sendNotification}.</p>
+ * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
@@ -271,102 +218,20 @@
* @param mbeanInterface a StandardMBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
- * @param emitter the object that will handle notifications. If null,
- * a new {@code NotificationEmitter} will be constructed that also
- * implements {@link SendNotification}.
- *
- * @throws IllegalArgumentException if the {@code mbeanInterface}
- * does not follow JMX design patterns for Management Interfaces, or
- * if {@code this} does not implement the specified interface.
- */
- protected StandardEmitterMBean(Class<?> mbeanInterface, boolean isMXBean,
- NotificationEmitter emitter) {
- this(mbeanInterface, isMXBean ? MBeanOptions.MXBEAN : null, emitter);
- }
-
- /**
- * <p>Make an MBean whose management interface is specified by {@code
- * mbeanInterface}, with the given options, and where notifications are
- * handled by the given {@code NotificationEmitter}. This constructor can
- * be used to make either Standard MBeans or MXBeans. The resultant MBean
- * implements the {@code NotificationEmitter} interface by forwarding its
- * methods to {@code emitter}.</p>
- *
- * <p>If {@code emitter} is an instance of {@code
- * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
- * then the MBean's {@link #sendNotification
- * sendNotification} method will call {@code emitter.}{@link
- * SendNotification#sendNotification sendNotification}.</p>
- *
- * <p>The array returned by {@link #getNotificationInfo()} on the
- * new MBean is a copy of the array returned by
- * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
- * getNotificationInfo()} at the time of construction. If the array
- * returned by {@code emitter.getNotificationInfo()} later changes,
- * that will have no effect on this object's
- * {@code getNotificationInfo()}.</p>
- *
- * <p>This constructor must be called from a subclass that implements
- * the given {@code mbeanInterface}.</p>
- *
- * @param mbeanInterface a StandardMBean interface.
- * @param options MBeanOptions that control the operation of the resulting
- * MBean.
- * @param emitter the object that will handle notifications. If null,
- * a new {@code NotificationEmitter} will be constructed that also
- * implements {@link SendNotification}.
+ * @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
- * if {@code this} does not implement the specified interface.
+ * if {@code this} does not implement the specified interface, or
+ * if {@code emitter} is null.
*/
- protected StandardEmitterMBean(Class<?> mbeanInterface, MBeanOptions options,
+ protected StandardEmitterMBean(Class<?> mbeanInterface, boolean isMXBean,
NotificationEmitter emitter) {
- super(mbeanInterface, options);
- MBeanNotificationInfo[] defaultMBNIs = defaultMBNIs(this);
+ super(mbeanInterface, isMXBean);
if (emitter == null)
- emitter = defaultEmitter(defaultMBNIs);
+ throw new IllegalArgumentException("Null emitter");
this.emitter = emitter;
- this.notificationInfo =
- firstNonEmpty(emitter.getNotificationInfo(), defaultMBNIs);
- injectEmitter();
- }
-
- private static MBeanNotificationInfo[] defaultMBNIs(Object mbean) {
- return MBeanIntrospector.findNotificationsFromAnnotations(
- mbean.getClass());
- }
-
- private NotificationEmitter defaultEmitter(MBeanNotificationInfo[] defaultMBNIs) {
- MBeanNotificationInfo[] mbnis =
- firstNonEmpty(getNotificationInfo(), defaultMBNIs);
- // Will be null unless getNotificationInfo() is overridden,
- // since the notificationInfo field has not been set at this point.
- if (mbnis == null)
- mbnis = getMBeanInfo().getNotifications();
- return new NotificationBroadcasterSupport(mbnis);
- }
-
- private static <T> T[] firstNonEmpty(T[]... items) {
- for (T[] t : items) {
- if (t != null && t.length != 0)
- return t;
- }
- return null;
- }
-
- private void injectEmitter() {
- if (emitter instanceof SendNotification) {
- try {
- Object resource = getImplementation();
- SendNotification send = (SendNotification) emitter;
- MBeanInjector.injectSendNotification(resource, send);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
+ this.notificationInfo = emitter.getNotificationInfo();
}
public void removeNotificationListener(NotificationListener listener)
@@ -394,10 +259,10 @@
/**
* <p>Sends a notification.</p>
*
- * <p>If the {@code emitter} parameter to the constructor was
- * an instance of {@link SendNotification}, such as {@link
- * NotificationBroadcasterSupport}, then this method will call {@code
- * emitter.}{@link SendNotification#sendNotification
+ * <p>If the {@code emitter} parameter to the constructor was an
+ * instance of {@code NotificationBroadcasterSupport} then this
+ * method will call {@code emitter.}{@link
+ * NotificationBroadcasterSupport#sendNotification
* sendNotification}.</p>
*
* @param n the notification to send.
@@ -406,12 +271,13 @@
* constructor was not a {@code NotificationBroadcasterSupport}.
*/
public void sendNotification(Notification n) {
- if (emitter instanceof SendNotification)
- ((SendNotification) emitter).sendNotification(n);
+ if (emitter instanceof NotificationBroadcasterSupport)
+ ((NotificationBroadcasterSupport) emitter).sendNotification(n);
else {
final String msg =
"Cannot sendNotification when emitter is not an " +
- "instance of SendNotification: " + emitter.getClass().getName();
+ "instance of NotificationBroadcasterSupport: " +
+ emitter.getClass().getName();
throw new ClassCastException(msg);
}
}
--- a/jdk/src/share/classes/javax/management/StandardMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/StandardMBean.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,27 +25,20 @@
package javax.management;
+import static com.sun.jmx.defaults.JmxProperties.MISC_LOGGER;
import com.sun.jmx.mbeanserver.DescriptorCache;
import com.sun.jmx.mbeanserver.Introspector;
-import com.sun.jmx.mbeanserver.MBeanInjector;
-import com.sun.jmx.mbeanserver.MBeanInstantiator;
-import com.sun.jmx.mbeanserver.MBeanIntrospector;
import com.sun.jmx.mbeanserver.MBeanSupport;
import com.sun.jmx.mbeanserver.MXBeanSupport;
import com.sun.jmx.mbeanserver.StandardMBeanSupport;
import com.sun.jmx.mbeanserver.Util;
-import java.lang.reflect.Method;
+
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.WeakHashMap;
import java.util.logging.Level;
-import javax.management.openmbean.MXBeanMappingFactory;
import javax.management.openmbean.OpenMBeanAttributeInfo;
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
import javax.management.openmbean.OpenMBeanConstructorInfo;
@@ -55,9 +48,6 @@
import javax.management.openmbean.OpenMBeanParameterInfo;
import javax.management.openmbean.OpenMBeanParameterInfoSupport;
-import static com.sun.jmx.defaults.JmxProperties.MISC_LOGGER;
-import static javax.management.JMX.MBeanOptions;
-
/**
* <p>An MBean whose management interface is determined by reflection
* on a Java interface.</p>
@@ -133,121 +123,7 @@
*
* @since 1.5
*/
-public class StandardMBean implements DynamicWrapperMBean, MBeanRegistration {
-
- /**
- * <p>Options controlling the behavior of {@code StandardMBean} instances.</p>
- */
- public static class Options extends JMX.MBeanOptions {
- private static final long serialVersionUID = 5107355471177517164L;
-
- private boolean wrappedVisible;
- private boolean forwardRegistration;
-
- /**
- * <p>Construct an {@code Options} object where all options have
- * their default values.</p>
- */
- public Options() {}
-
- @Override
- public Options clone() {
- return (Options) super.clone();
- }
-
- /**
- * <p>Defines whether the {@link StandardMBean#getWrappedObject()
- * getWrappedObject} method returns the wrapped object.</p>
- *
- * <p>If this option is true, then {@code getWrappedObject()} will return
- * the same object as {@link StandardMBean#getImplementation()
- * getImplementation}. Otherwise, it will return the
- * StandardMBean instance itself. The setting of this option
- * affects the behavior of {@link MBeanServer#getClassLoaderFor
- * MBeanServer.getClassLoaderFor} and {@link MBeanServer#isInstanceOf
- * MBeanServer.isInstanceOf}. The default value is false for
- * compatibility reasons, but true is a better value for most new code.</p>
- *
- * @return true if this StandardMBean's {@link
- * StandardMBean#getWrappedObject getWrappedObject} returns the wrapped
- * object.
- */
- public boolean isWrappedObjectVisible() {
- return this.wrappedVisible;
- }
-
- /**
- * <p>Set the {@link #isWrappedObjectVisible WrappedObjectVisible} option
- * to the given value.</p>
- * @param visible the new value.
- */
- public void setWrappedObjectVisible(boolean visible) {
- this.wrappedVisible = visible;
- }
-
- /**
- * <p>Defines whether the {@link MBeanRegistration MBeanRegistration}
- * callbacks are forwarded to the wrapped object.</p>
- *
- * <p>If this option is true, then
- * {@link #preRegister(MBeanServer, ObjectName) preRegister},
- * {@link #postRegister(Boolean) postRegister},
- * {@link #preDeregister preDeregister} and
- * {@link #postDeregister postDeregister} methods are forwarded
- * to the wrapped object, in addition to the behaviour specified
- * for the StandardMBean instance itself.
- * The default value is false for compatibility reasons, but true
- * is a better value for most new code.</p>
- *
- * @return true if the <code>MBeanRegistration</code> callbacks
- * are forwarded to the wrapped object.
- */
- public boolean isMBeanRegistrationForwarded() {
- return this.forwardRegistration;
- }
-
- /**
- * <p>Set the
- * {@link #isMBeanRegistrationForwarded MBeanRegistrationForwarded}
- * option to the given value.</p>
- * @param forward the new value.
- */
- public void setMBeanRegistrationForwarded(boolean forward) {
- this.forwardRegistration = forward;
- }
-
- // Canonical objects for each of
- // (MXBean,!MXBean) x (WVisible,!WVisible) x (Forward,!Forward)
- private static final Options[] CANONICALS = {
- new Options(), new Options(), new Options(), new Options(),
- new Options(), new Options(), new Options(), new Options(),
- };
- static {
- CANONICALS[1].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- CANONICALS[2].setWrappedObjectVisible(true);
- CANONICALS[3].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- CANONICALS[3].setWrappedObjectVisible(true);
- CANONICALS[4].setMBeanRegistrationForwarded(true);
- CANONICALS[5].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- CANONICALS[5].setMBeanRegistrationForwarded(true);
- CANONICALS[6].setWrappedObjectVisible(true);
- CANONICALS[6].setMBeanRegistrationForwarded(true);
- CANONICALS[7].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- CANONICALS[7].setWrappedObjectVisible(true);
- CANONICALS[7].setMBeanRegistrationForwarded(true);
- }
- @Override
- MBeanOptions[] canonicals() {
- return CANONICALS;
- }
-
- @Override
- boolean same(MBeanOptions opts) {
- return (super.same(opts) && opts instanceof Options &&
- ((Options) opts).wrappedVisible == wrappedVisible &&
- ((Options) opts).forwardRegistration ==forwardRegistration);
- }
- }
+public class StandardMBean implements DynamicMBean, MBeanRegistration {
private final static DescriptorCache descriptors =
DescriptorCache.getInstance(JMX.proof);
@@ -263,11 +139,6 @@
private volatile MBeanInfo cachedMBeanInfo;
/**
- * The MBeanOptions for this StandardMBean.
- **/
- private MBeanOptions options;
-
- /**
* Make a DynamicMBean out of <var>implementation</var>, using the
* specified <var>mbeanInterface</var> class.
* @param implementation The implementation of this MBean.
@@ -282,14 +153,12 @@
* implementation is allowed. If null implementation is allowed,
* and a null implementation is passed, then the implementation
* is assumed to be <var>this</var>.
- * @param options MBeanOptions to apply to this instance.
* @exception IllegalArgumentException if the given
* <var>implementation</var> is null, and null is not allowed.
**/
- @SuppressWarnings("unchecked") // cast to T
private <T> void construct(T implementation, Class<T> mbeanInterface,
boolean nullImplementationAllowed,
- MBeanOptions options)
+ boolean isMXBean)
throws NotCompliantMBeanException {
if (implementation == null) {
// Have to use (T)this rather than mbeanInterface.cast(this)
@@ -298,23 +167,20 @@
implementation = Util.<T>cast(this);
else throw new IllegalArgumentException("implementation is null");
}
- if (options == null)
- options = new MBeanOptions();
- MXBeanMappingFactory mappingFactory = options.getMXBeanMappingFactory();
- boolean mx = (mappingFactory != null);
- if (mbeanInterface == null) {
- mbeanInterface = Util.cast(Introspector.getStandardOrMXBeanInterface(
- implementation.getClass(), mx));
- }
- if (mx) {
- this.mbean =
- new MXBeanSupport(implementation, mbeanInterface,
- mappingFactory);
+ if (isMXBean) {
+ if (mbeanInterface == null) {
+ mbeanInterface = Util.cast(Introspector.getMXBeanInterface(
+ implementation.getClass()));
+ }
+ this.mbean = new MXBeanSupport(implementation, mbeanInterface);
} else {
+ if (mbeanInterface == null) {
+ mbeanInterface = Util.cast(Introspector.getStandardMBeanInterface(
+ implementation.getClass()));
+ }
this.mbean =
new StandardMBeanSupport(implementation, mbeanInterface);
}
- this.options = options.canonical();
}
/**
@@ -343,7 +209,7 @@
**/
public <T> StandardMBean(T implementation, Class<T> mbeanInterface)
throws NotCompliantMBeanException {
- construct(implementation, mbeanInterface, false, null);
+ construct(implementation, mbeanInterface, false, false);
}
/**
@@ -363,7 +229,7 @@
**/
protected StandardMBean(Class<?> mbeanInterface)
throws NotCompliantMBeanException {
- construct(null, mbeanInterface, true, null);
+ construct(null, mbeanInterface, true, false);
}
/**
@@ -400,17 +266,7 @@
public <T> StandardMBean(T implementation, Class<T> mbeanInterface,
boolean isMXBean) {
try {
- MBeanOptions opts = new MBeanOptions();
- if (mbeanInterface == null) {
- mbeanInterface = Util.cast(Introspector.getStandardOrMXBeanInterface(
- implementation.getClass(), isMXBean));
- }
- if (isMXBean) {
- MXBeanMappingFactory f = MXBeanMappingFactory.forInterface(
- mbeanInterface);
- opts.setMXBeanMappingFactory(f);
- }
- construct(implementation, mbeanInterface, false, opts);
+ construct(implementation, mbeanInterface, false, isMXBean);
} catch (NotCompliantMBeanException e) {
throw new IllegalArgumentException(e);
}
@@ -441,77 +297,7 @@
**/
protected StandardMBean(Class<?> mbeanInterface, boolean isMXBean) {
try {
- MBeanOptions opts = new MBeanOptions();
- if (mbeanInterface == null) {
- mbeanInterface = Introspector.getStandardOrMXBeanInterface(
- getClass(), isMXBean);
- }
- if (isMXBean) {
- MXBeanMappingFactory f = MXBeanMappingFactory.forInterface(
- mbeanInterface);
- opts.setMXBeanMappingFactory(f);
- }
- construct(null, mbeanInterface, true, opts);
- } catch (NotCompliantMBeanException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * <p>Make a DynamicMBean out of the object
- * <var>implementation</var>, using the specified
- * <var>mbeanInterface</var> class and the specified options.</p>
- *
- * @param implementation The implementation of this MBean.
- * @param mbeanInterface The Management Interface exported by this
- * MBean's implementation. If <code>null</code>, then this
- * object will use standard JMX design pattern to determine
- * the management interface associated with the given
- * implementation.
- * @param options MBeanOptions that control the operation of the resulting
- * MBean.
- * @param <T> Allows the compiler to check
- * that {@code implementation} does indeed implement the class
- * described by {@code mbeanInterface}. The compiler can only
- * check this if {@code mbeanInterface} is a class literal such
- * as {@code MyMBean.class}.
- *
- * @exception IllegalArgumentException if the given
- * <var>implementation</var> is null, or if the <var>mbeanInterface</var>
- * does not follow JMX design patterns for Management Interfaces, or
- * if the given <var>implementation</var> does not implement the
- * specified interface.
- **/
- public <T> StandardMBean(T implementation,
- Class<T> mbeanInterface,
- MBeanOptions options) {
- try {
- construct(implementation, mbeanInterface, false, options);
- } catch (NotCompliantMBeanException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * <p>Make a DynamicMBean out of <var>this</var>, using the specified
- * <var>mbeanInterface</var> class and the specified options.</p>
- *
- * <p>Calls {@link #StandardMBean(Object, Class, JMX.MBeanOptions)
- * this(this,mbeanInterface,options)}.
- * This constructor is reserved to subclasses.</p>
- *
- * @param mbeanInterface The Management Interface exported by this
- * MBean.
- * @param options MBeanOptions that control the operation of the resulting
- * MBean.
- *
- * @exception IllegalArgumentException if the <var>mbeanInterface</var>
- * does not follow JMX design patterns for Management Interfaces, or
- * if <var>this</var> does not implement the specified interface.
- **/
- protected StandardMBean(Class<?> mbeanInterface, MBeanOptions options) {
- try {
- construct(null, mbeanInterface, true, options);
+ construct(null, mbeanInterface, true, isMXBean);
} catch (NotCompliantMBeanException e) {
throw new IllegalArgumentException(e);
}
@@ -527,9 +313,7 @@
*
* @exception IllegalArgumentException if the given
* <var>implementation</var> is null.
- * @exception IllegalStateException if the
- * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
- * option is true.
+ *
* @exception NotCompliantMBeanException if the given
* <var>implementation</var> does not implement the
* Standard MBean (or MXBean) interface that was
@@ -543,24 +327,12 @@
if (implementation == null)
throw new IllegalArgumentException("implementation is null");
- if(options instanceof Options &&
- ((Options) options).isMBeanRegistrationForwarded())
- throw new IllegalStateException("Implementation can't be changed " +
- "because MBeanRegistrationForwarded option is true");
-
- setImplementation2(implementation);
- }
-
- private <T> void setImplementation2(T implementation)
- throws NotCompliantMBeanException {
- Class<? super T> intf = Util.cast(getMBeanInterface());
-
- if (this.mbean.isMXBean()) {
+ if (isMXBean()) {
this.mbean = new MXBeanSupport(implementation,
- intf,
- options.getMXBeanMappingFactory());
+ Util.<Class<Object>>cast(getMBeanInterface()));
} else {
- this.mbean = new StandardMBeanSupport(implementation, intf);
+ this.mbean = new StandardMBeanSupport(implementation,
+ Util.<Class<Object>>cast(getMBeanInterface()));
}
}
@@ -571,67 +343,7 @@
* @see #setImplementation
**/
public Object getImplementation() {
- return mbean.getWrappedObject();
- }
-
- /**
- * <p>Get the wrapped implementation object or return this object.</p>
- *
- * <p>For compatibility reasons, this method only returns the wrapped
- * implementation object if the {@link Options#isWrappedObjectVisible
- * WrappedObjectVisible} option was specified when this StandardMBean
- * was created. Otherwise it returns {@code this}.</p>
- *
- * <p>If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor
- * getClassLoaderFor} and {@link MBeanServer#isInstanceOf
- * isInstanceOf} methods to refer to the wrapped implementation and
- * not this StandardMBean object, then you must set the
- * {@code WrappedObjectVisible} option, for example using:</p>
- *
- * <pre>
- * StandardMBean.Options opts = new StandardMBean.Options();
- * opts.setWrappedObjectVisible(true);
- * StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts);
- * </pre>
- *
- * @return The wrapped implementation object, or this StandardMBean
- * instance.
- */
- public Object getWrappedObject() {
- if (options instanceof Options &&
- ((Options) options).isWrappedObjectVisible())
- return getImplementation();
- else
- return this;
- }
-
- /**
- * <p>Get the ClassLoader of the wrapped implementation object or of this
- * object.</p>
- *
- * <p>For compatibility reasons, this method only returns the ClassLoader
- * of the wrapped implementation object if the {@link
- * Options#isWrappedObjectVisible WrappedObjectVisible} option was
- * specified when this StandardMBean was created. Otherwise it returns
- * {@code this.getClass().getClassLoader()}.</p>
- *
- * <p>If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor
- * getClassLoaderFor} and {@link MBeanServer#isInstanceOf
- * isInstanceOf} methods to refer to the wrapped implementation and
- * not this StandardMBean object, then you must set the
- * {@code WrappedObjectVisible} option, for example using:</p>
- *
- * <pre>
- * StandardMBean.Options opts = new StandardMBean.Options();
- * opts.setWrappedObjectVisible(true);
- * StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts);
- * </pre>
- *
- * @return The ClassLoader of the wrapped Cimplementation object, or of
- * this StandardMBean instance.
- */
- public ClassLoader getWrappedClassLoader() {
- return getWrappedObject().getClass().getClassLoader();
+ return mbean.getResource();
}
/**
@@ -647,20 +359,7 @@
* @return The class of the implementation of this Standard MBean (or MXBean).
**/
public Class<?> getImplementationClass() {
- return mbean.getWrappedObject().getClass();
- }
-
- /**
- * Return the MBeanOptions that were specified or implied for this StandardMBean
- * instance. If an MBeanOptions object was supplied when this StandardMBean
- * instance was constructed, and if that object has not been modified in the
- * meantime, then the returned object will be equal to that object, although
- * it might not be the same object.
- * @return The MBeanOptions that were specified or implied for this StandardMBean
- * instance.
- */
- public MBeanOptions getOptions() {
- return options.uncanonical();
+ return mbean.getResource().getClass();
}
// ------------------------------------------------------------------
@@ -749,7 +448,7 @@
MBeanSupport<?> msupport = mbean;
final MBeanInfo bi = msupport.getMBeanInfo();
- final Object impl = msupport.getWrappedObject();
+ final Object impl = msupport.getResource();
final boolean immutableInfo = immutableInfo(this.getClass());
@@ -1027,7 +726,7 @@
* @return the MBeanNotificationInfo[] for the new MBeanInfo.
**/
MBeanNotificationInfo[] getNotifications(MBeanInfo info) {
- return info.getNotifications();
+ return null;
}
/**
@@ -1116,6 +815,10 @@
cachedMBeanInfo = info;
}
+ private boolean isMXBean() {
+ return mbean.isMXBean();
+ }
+
private static <T> boolean identicalArrays(T[] a, T[] b) {
if (a == b)
return true;
@@ -1323,145 +1026,6 @@
return natts;
}
- // ------------------------------------------------------------------
- // Resolve from a type name to a Class.
- // ------------------------------------------------------------------
- private static Class<?> resolveClass(MBeanFeatureInfo info, String type,
- Class<?> mbeanItf)
- throws ClassNotFoundException {
- String t = (String) info.getDescriptor().
- getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
- if (t == null) {
- t = type;
- }
- Class<?> clazz = MBeanInstantiator.primitiveType(t);
- if(clazz == null)
- clazz = Class.forName(t, false, mbeanItf.getClassLoader());
- return clazz;
- }
-
- // ------------------------------------------------------------------
- // Return the subset of valid Management methods
- // ------------------------------------------------------------------
- private static Method getManagementMethod(final Class<?> mbeanType,
- String opName, Class<?>... parameters) throws NoSuchMethodException,
- SecurityException {
- Method m = mbeanType.getMethod(opName, parameters);
- if (mbeanType.isInterface()) {
- return m;
- }
- final List<Method> methods = new ArrayList<Method>();
- try {
- MBeanIntrospector.getAnnotatedMethods(mbeanType, methods);
- }catch (SecurityException ex) {
- throw ex;
- }catch (NoSuchMethodException ex) {
- throw ex;
- }catch (Exception ex) {
- NoSuchMethodException nsme =
- new NoSuchMethodException(ex.toString());
- nsme.initCause(ex);
- throw nsme;
- }
-
- if(methods.contains(m)) return m;
-
- throw new NoSuchMethodException("Operation " + opName +
- " not found in management interface " + mbeanType.getName());
- }
- /**
- * Retrieve the set of MBean attribute accessor <code>Method</code>s
- * located in the <code>mbeanInterface</code> MBean interface that
- * correspond to the <code>attr</code> <code>MBeanAttributeInfo</code>
- * parameter.
- * @param mbeanInterface the management interface.
- * Can be a standard MBean or MXBean interface, or a Java class
- * annotated with {@link MBean @MBean} or {@link MXBean @MXBean}.
- * @param attr The attribute we want the accessors for.
- * @return The set of accessors.
- * @throws java.lang.NoSuchMethodException if no accessor exists
- * for the given {@link MBeanAttributeInfo MBeanAttributeInfo}.
- * @throws java.lang.IllegalArgumentException if at least one
- * of the two parameters is null.
- * @throws java.lang.ClassNotFoundException if the class named in the
- * attribute type is not found.
- * @throws java.lang.SecurityException if this exception is
- * encountered while introspecting the MBean interface.
- */
- public static Set<Method> findAttributeAccessors(Class<?> mbeanInterface,
- MBeanAttributeInfo attr)
- throws NoSuchMethodException,
- ClassNotFoundException {
- if (mbeanInterface == null || attr == null) {
- throw new IllegalArgumentException("mbeanInterface or attr " +
- "parameter is null");
- }
- String attributeName = attr.getName();
- Set<Method> methods = new HashSet<Method>();
- Class<?> clazz = resolveClass(attr, attr.getType(), mbeanInterface);
- if (attr.isReadable()) {
- String radical = "get";
- if(attr.isIs()) radical = "is";
- Method getter = getManagementMethod(mbeanInterface, radical +
- attributeName);
- if (getter.getReturnType().equals(clazz)) {
- methods.add(getter);
- } else {
- throw new NoSuchMethodException("Invalid getter return type, " +
- "should be " + clazz + ", found " +
- getter.getReturnType());
- }
- }
- if (attr.isWritable()) {
- Method setter = getManagementMethod(mbeanInterface, "set" +
- attributeName,
- clazz);
- if (setter.getReturnType().equals(Void.TYPE)) {
- methods.add(setter);
- } else {
- throw new NoSuchMethodException("Invalid setter return type, " +
- "should be void, found " + setter.getReturnType());
- }
- }
- return methods;
- }
-
- /**
- * Retrieve the MBean operation <code>Method</code>
- * located in the <code>mbeanInterface</code> MBean interface that
- * corresponds to the provided <code>op</code>
- * <code>MBeanOperationInfo</code> parameter.
- * @param mbeanInterface the management interface.
- * Can be a standard MBean or MXBean interface, or a Java class
- * annotated with {@link MBean @MBean} or {@link MXBean @MXBean}.
- * @param op The operation we want the method for.
- * @return the method corresponding to the provided MBeanOperationInfo.
- * @throws java.lang.NoSuchMethodException if no method exists
- * for the given {@link MBeanOperationInfo MBeanOperationInfo}.
- * @throws java.lang.IllegalArgumentException if at least one
- * of the two parameters is null.
- * @throws java.lang.ClassNotFoundException if one of the
- * classes named in the operation signature array is not found.
- * @throws java.lang.SecurityException if this exception is
- * encountered while introspecting the MBean interface.
- */
- public static Method findOperationMethod(Class<?> mbeanInterface,
- MBeanOperationInfo op)
- throws ClassNotFoundException, NoSuchMethodException {
- if (mbeanInterface == null || op == null) {
- throw new IllegalArgumentException("mbeanInterface or op " +
- "parameter is null");
- }
- List<Class<?>> classes = new ArrayList<Class<?>>();
- for (MBeanParameterInfo info : op.getSignature()) {
- Class<?> clazz = resolveClass(info, info.getType(), mbeanInterface);
- classes.add(clazz);
- }
- Class<?>[] signature = new Class<?>[classes.size()];
- classes.toArray(signature);
- return getManagementMethod(mbeanInterface, op.getName(), signature);
- }
-
/**
* <p>Allows the MBean to perform any operations it needs before
* being registered in the MBean server. If the name of the MBean
@@ -1470,14 +1034,10 @@
* registered in the MBean server.</p>
*
* <p>The default implementation of this method returns the {@code name}
- * parameter. If the
- * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
- * option is set to true, then this method is forwarded to the object
- * returned by the {@link #getImplementation getImplementation()} method.
- * The name returned by this call is then returned by this method.
- * It does nothing else for Standard MBeans. For MXBeans, it records
- * the {@code MBeanServer} and {@code ObjectName} parameters so they can
- * be used to translate inter-MXBean references.</p>
+ * parameter. It does nothing else for
+ * Standard MBeans. For MXBeans, it records the {@code MBeanServer}
+ * and {@code ObjectName} parameters so they can be used to translate
+ * inter-MXBean references.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.preRegister(...)}.
@@ -1512,13 +1072,7 @@
*/
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
- // Forward preRegister before to call register and
- // inject parameters.
- if(shouldForwardMBeanRegistration())
- name = ((MBeanRegistration)getImplementation()).
- preRegister(server, name);
mbean.register(server, name);
- MBeanInjector.inject(mbean.getWrappedObject(), server, name);
return name;
}
@@ -1526,11 +1080,7 @@
* <p>Allows the MBean to perform any operations needed after having been
* registered in the MBean server or after the registration has failed.</p>
*
- * <p>If the
- * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
- * option is set to true, then this method is forwarded to the object
- * returned by the {@link #getImplementation getImplementation()} method.
- * The default implementation of this method does nothing else for
+ * <p>The default implementation of this method does nothing for
* Standard MBeans. For MXBeans, it undoes any work done by
* {@link #preRegister preRegister} if registration fails.</p>
*
@@ -1548,21 +1098,13 @@
public void postRegister(Boolean registrationDone) {
if (!registrationDone)
mbean.unregister();
- if(shouldForwardMBeanRegistration())
- ((MBeanRegistration)getImplementation()).
- postRegister(registrationDone);
}
/**
* <p>Allows the MBean to perform any operations it needs before
* being unregistered by the MBean server.</p>
*
- * <p>If the
- * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
- * option is set to true, then this method is forwarded to the object
- * returned by the {@link #getImplementation getImplementation()} method.
- * Other than that, the default implementation of this method does nothing.
- * </p>
+ * <p>The default implementation of this method does nothing.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.preDeregister(...)}.</p>
@@ -1574,19 +1116,13 @@
* @since 1.6
*/
public void preDeregister() throws Exception {
- if(shouldForwardMBeanRegistration())
- ((MBeanRegistration)getImplementation()).preDeregister();
}
/**
* <p>Allows the MBean to perform any operations needed after having been
* unregistered in the MBean server.</p>
*
- * <p>If the
- * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
- * option is set to true, then this method is forwarded to the object
- * returned by the {@link #getImplementation getImplementation()} method.
- * The default implementation of this method does nothing else for
+ * <p>The default implementation of this method does nothing for
* Standard MBeans. For MXBeans, it removes any information that
* was recorded by the {@link #preRegister preRegister} method.</p>
*
@@ -1599,15 +1135,8 @@
*/
public void postDeregister() {
mbean.unregister();
- if(shouldForwardMBeanRegistration())
- ((MBeanRegistration)getImplementation()).postDeregister();
}
- private boolean shouldForwardMBeanRegistration() {
- return (getImplementation() instanceof MBeanRegistration) &&
- (options instanceof Options &&
- ((Options) options).isMBeanRegistrationForwarded());
- }
//
// MBeanInfo immutability
//
--- a/jdk/src/share/classes/javax/management/event/EventClient.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1104 +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 javax.management.event;
-
-import com.sun.jmx.event.DaemonThreadFactory;
-import com.sun.jmx.event.LeaseRenewer;
-import com.sun.jmx.event.ReceiverBuffer;
-import com.sun.jmx.event.RepeatedSingletonJob;
-import com.sun.jmx.mbeanserver.PerThreadGroupPool;
-import com.sun.jmx.remote.util.ClassLogger;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executor;
-
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServerConnection;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
-
-/**
- * <p>This class is used to manage its notification listeners on the client
- * side in the same way as on the MBean server side. This class needs to work
- * with an {@link EventClientDelegateMBean} on the server side.</p>
- *
- * <P>A user can specify an {@link EventRelay} object to specify how to receive
- * notifications forwarded by the {@link EventClientDelegateMBean}. By default,
- * the class {@link FetchingEventRelay} is used.</p>
- *
- * <p>A user can specify an {@link java.util.concurrent.Executor Executor}
- * to distribute notifications to local listeners. If no executor is
- * specified, the thread in the {@link EventRelay} which calls {@link
- * EventReceiver#receive EventReceiver.receive} will be reused to distribute
- * the notifications (in other words, to call the {@link
- * NotificationListener#handleNotification handleNotification} method of the
- * appropriate listeners). It is useful to make a separate thread do this
- * distribution in some cases. For example, if network communication is slow,
- * the forwarding thread can concentrate on communication while, locally,
- * the distributing thread distributes the received notifications. Another
- * usage is to share a thread pool between many clients, for scalability.
- * Note, though, that if the {@code Executor} can create more than one thread
- * then it is possible that listeners will see notifications in a different
- * order from the order in which they were sent.</p>
- *
- * <p>An object of this class sends notifications to listeners added with
- * {@link #addEventClientListener}. The {@linkplain Notification#getType()
- * type} of each such notification is one of {@link #FAILED}, {@link #NONFATAL},
- * or {@link #NOTIFS_LOST}.</p>
- *
- * @since JMX 2.0
- */
-public class EventClient implements EventConsumer, NotificationManager {
-
- /**
- * <p>A notification string type used by an {@code EventClient} object
- * to inform a listener added by {@link #addEventClientListener} that
- * it failed to get notifications from a remote server, and that it is
- * possible that no more notifications will be delivered.</p>
- *
- * @see #addEventClientListener
- * @see EventReceiver#failed
- */
- public static final String FAILED = "jmx.event.service.failed";
-
- /**
- * <p>Reports that an unexpected exception has been received by the {@link
- * EventRelay} object but that it is non-fatal. For example, a notification
- * received is not serializable or its class is not found.</p>
- *
- * @see #addEventClientListener
- * @see EventReceiver#nonFatal
- */
- public static final String NONFATAL = "jmx.event.service.nonfatal";
-
- /**
- * <p>A notification string type used by an {@code EventClient} object
- * to inform a listener added by {@link #addEventClientListener
- * addEventClientListener} that it has detected that notifications have
- * been lost. The {@link Notification#getUserData() userData} of the
- * notification is a Long which is an upper bound on the number of lost
- * notifications that have just been detected.</p>
- *
- * @see #addEventClientListener
- */
- public static final String NOTIFS_LOST = "jmx.event.service.notifs.lost";
-
- /**
- * The default lease time that EventClient instances will request, in
- * milliseconds. This value is {@value}.
- *
- * @see EventClientDelegateMBean#lease
- */
- public static final long DEFAULT_REQUESTED_LEASE_TIME = 300000;
-
- /**
- * <p>Constructs a default {@code EventClient} object.</p>
- *
- * <p>This object creates a {@link FetchingEventRelay} object to
- * receive notifications forwarded by the {@link EventClientDelegateMBean}.
- * The {@link EventClientDelegateMBean} that it works with is the
- * one registered with the {@linkplain EventClientDelegate#OBJECT_NAME
- * default ObjectName}. The thread from the {@link FetchingEventRelay}
- * object that fetches the notifications is also used to distribute them.
- *
- * @param conn An {@link MBeanServerConnection} object used to communicate
- * with an {@link EventClientDelegateMBean} MBean.
- *
- * @throws IllegalArgumentException If {@code conn} is null.
- * @throws IOException If an I/O error occurs when communicating with the
- * {@code EventClientDelegateMBean}.
- */
- public EventClient(MBeanServerConnection conn) throws IOException {
- this(EventClientDelegate.getProxy(conn));
- }
-
- /**
- * Constructs an {@code EventClient} object with a specified
- * {@link EventClientDelegateMBean}.
- *
- * <p>This object creates a {@link FetchingEventRelay} object to receive
- * notifications forwarded by the {@link EventClientDelegateMBean}. The
- * thread from the {@link FetchingEventRelay} object that fetches the
- * notifications is also used to distribute them.
- *
- * @param delegate An {@link EventClientDelegateMBean} object to work with.
- *
- * @throws IllegalArgumentException If {@code delegate} is null.
- * @throws IOException If an I/O error occurs when communicating with the
- * the {@link EventClientDelegateMBean}.
- */
- public EventClient(EventClientDelegateMBean delegate)
- throws IOException {
- this(delegate, null, null, null, DEFAULT_REQUESTED_LEASE_TIME);
- }
-
- /**
- * Constructs an {@code EventClient} object with the specified
- * {@link EventClientDelegateMBean}, {@link EventRelay}
- * object, and distributing thread.
- *
- * @param delegate An {@link EventClientDelegateMBean} object to work with.
- * Usually, this will be a proxy constructed using
- * {@link EventClientDelegate#getProxy}.
- * @param eventRelay An object used to receive notifications
- * forwarded by the {@link EventClientDelegateMBean}. If {@code null}, a
- * {@link FetchingEventRelay} object will be used.
- * @param distributingExecutor Used to distribute notifications to local
- * listeners. Only one job at a time will be submitted to this Executor.
- * If {@code distributingExecutor} is {@code null}, the thread that calls
- * {@link EventReceiver#receive EventReceiver.receive} from the {@link
- * EventRelay} object is used.
- * @param leaseScheduler An object that will be used to schedule the
- * periodic {@linkplain EventClientDelegateMBean#lease lease updates}.
- * If {@code null}, a default scheduler will be used.
- * @param requestedLeaseTime The lease time used to keep this client alive
- * in the {@link EventClientDelegateMBean}. A value of zero is equivalent
- * to the {@linkplain #DEFAULT_REQUESTED_LEASE_TIME default value}.
- *
- * @throws IllegalArgumentException If {@code delegate} is null.
- * @throws IOException If an I/O error occurs when communicating with the
- * {@link EventClientDelegateMBean}.
- */
- public EventClient(EventClientDelegateMBean delegate,
- EventRelay eventRelay,
- Executor distributingExecutor,
- ScheduledExecutorService leaseScheduler,
- long requestedLeaseTime)
- throws IOException {
- if (delegate == null) {
- throw new IllegalArgumentException("Null EventClientDelegateMBean");
- }
-
- if (requestedLeaseTime == 0)
- requestedLeaseTime = DEFAULT_REQUESTED_LEASE_TIME;
- else if (requestedLeaseTime < 0) {
- throw new IllegalArgumentException(
- "Negative lease time: " + requestedLeaseTime);
- }
-
- eventClientDelegate = delegate;
-
- if (eventRelay != null) {
- this.eventRelay = eventRelay;
- } else {
- try {
- this.eventRelay = new FetchingEventRelay(delegate);
- } catch (IOException ioe) {
- throw ioe;
- } catch (Exception e) {
- // impossible?
- final IOException ioee = new IOException(e.toString());
- ioee.initCause(e);
- throw ioee;
- }
- }
-
- if (distributingExecutor == null)
- distributingExecutor = callerExecutor;
- this.distributingExecutor = distributingExecutor;
- this.dispatchingJob = new DispatchingJob();
-
- clientId = this.eventRelay.getClientId();
-
- this.requestedLeaseTime = requestedLeaseTime;
- if (leaseScheduler == null)
- leaseScheduler = defaultLeaseScheduler();
- leaseRenewer = new LeaseRenewer(leaseScheduler, renewLease);
-
- if (logger.traceOn()) {
- logger.trace("init", "New EventClient: "+clientId);
- }
- }
-
- private static ScheduledExecutorService defaultLeaseScheduler() {
- // The default lease scheduler uses a ScheduledThreadPoolExecutor
- // with a maximum of 20 threads. This means that if you have many
- // EventClient instances and some of them get blocked (because of an
- // unresponsive network, for example), then even the instances that
- // are connected to responsive servers may have their leases expire.
- // XXX check if the above is true and possibly fix.
- PerThreadGroupPool.Create<ScheduledThreadPoolExecutor> create =
- new PerThreadGroupPool.Create<ScheduledThreadPoolExecutor>() {
- public ScheduledThreadPoolExecutor createThreadPool(ThreadGroup group) {
- ThreadFactory daemonThreadFactory = new DaemonThreadFactory(
- "JMX EventClient lease renewer %d");
- ScheduledThreadPoolExecutor executor =
- new ScheduledThreadPoolExecutor(20, daemonThreadFactory);
- executor.setKeepAliveTime(1, TimeUnit.SECONDS);
- executor.allowCoreThreadTimeOut(true);
- if (setRemoveOnCancelPolicy != null) {
- try {
- setRemoveOnCancelPolicy.invoke(executor, true);
- } catch (Exception e) {
- logger.trace("setRemoveOnCancelPolicy", e);
- }
- }
- // By default, a ScheduledThreadPoolExecutor will keep jobs
- // in its queue even after they have been cancelled. They
- // will only be removed when their scheduled time arrives.
- // Since the job references the LeaseRenewer which references
- // this EventClient, this can lead to a moderately large number
- // of objects remaining referenced until the renewal time
- // arrives. Hence the above call, which removes the job from
- // the queue as soon as it is cancelled. Since the call is
- // new with JDK 7, we invoke it via reflection to make it
- // easier to use this code on JDK 6.
- return executor;
- }
- };
- return leaseRenewerThreadPool.getThreadPoolExecutor(create);
- }
-
- private static final Method setRemoveOnCancelPolicy;
- static {
- Method m;
- try {
- m = ScheduledThreadPoolExecutor.class.getMethod(
- "setRemoveOnCancelPolicy", boolean.class);
- } catch (Exception e) {
- m = null;
- }
- setRemoveOnCancelPolicy = m;
- }
-
- /**
- * <p>Closes this EventClient, removes all listeners and stops receiving
- * notifications.</p>
- *
- * <p>This method calls {@link
- * EventClientDelegateMBean#removeClient(String)} and {@link
- * EventRelay#stop}. Both operations occur even if one of them
- * throws an {@code IOException}.
- *
- * @throws IOException if an I/O error occurs when communicating with
- * {@link EventClientDelegateMBean}, or if {@link EventRelay#stop}
- * throws an {@code IOException}.
- */
- public void close() throws IOException {
- if (logger.traceOn()) {
- logger.trace("close", clientId);
- }
-
- synchronized(listenerInfoMap) {
- if (closed) {
- return;
- }
-
- closed = true;
- listenerInfoMap.clear();
- }
-
- if (leaseRenewer != null)
- leaseRenewer.close();
-
- IOException ioe = null;
- try {
- eventRelay.stop();
- } catch (IOException e) {
- ioe = e;
- logger.debug("close", "EventRelay.stop", e);
- }
-
- try {
- eventClientDelegate.removeClient(clientId);
- } catch (Exception e) {
- if (e instanceof IOException)
- ioe = (IOException) e;
- else
- ioe = new IOException(e);
- logger.debug("close",
- "Got exception when removing "+clientId, e);
- }
-
- if (ioe != null)
- throw ioe;
- }
-
- /**
- * <p>Determine if this {@code EventClient} is closed.</p>
- *
- * @return True if the {@code EventClient} is closed.
- */
- public boolean closed() {
- return closed;
- }
-
- /**
- * <p>Return the {@link EventRelay} associated with this
- * {@code EventClient}.</p>
- *
- * @return The {@link EventRelay} object used.
- */
- public EventRelay getEventRelay() {
- return eventRelay;
- }
-
- /**
- * <p>Return the lease time that this {@code EventClient} requests
- * on every lease renewal.</p>
- *
- * @return The requested lease time.
- *
- * @see EventClientDelegateMBean#lease
- */
- public long getRequestedLeaseTime() {
- return requestedLeaseTime;
- }
-
- /**
- * @see javax.management.MBeanServerConnection#addNotificationListener(
- * ObjectName, NotificationListener, NotificationFilter, Object).
- */
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, IOException {
- if (logger.traceOn()) {
- logger.trace("addNotificationListener", "");
- }
-
- checkState();
-
- Integer listenerId;
- try {
- listenerId =
- eventClientDelegate.addListener(clientId, name, filter);
- } catch (EventClientNotFoundException ecnfe) {
- final IOException ioe = new IOException(ecnfe.getMessage());
- ioe.initCause(ecnfe);
- throw ioe;
- }
-
- synchronized(listenerInfoMap) {
- listenerInfoMap.put(listenerId, new ListenerInfo(
- name,
- listener,
- filter,
- handback,
- false));
- }
-
- startListening();
- }
-
- /**
- * @see javax.management.MBeanServerConnection#removeNotificationListener(
- * ObjectName, NotificationListener).
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
- if (logger.traceOn()) {
- logger.trace("removeNotificationListener", "");
- }
- checkState();
-
- for (Integer id : getListenerInfo(name, listener, false)) {
- removeListener(id);
- }
- }
-
- /**
- * @see javax.management.MBeanServerConnection#removeNotificationListener(
- * ObjectName, NotificationListener, NotificationFilter, Object).
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
- if (logger.traceOn()) {
- logger.trace("removeNotificationListener", "with all arguments.");
- }
- checkState();
- final Integer listenerId =
- getListenerInfo(name, listener, filter, handback, false);
-
- removeListener(listenerId);
- }
-
- /**
- * @see javax.management.event.EventConsumer#unsubscribe(
- * ObjectName, NotificationListener).
- */
- public void unsubscribe(ObjectName name,
- NotificationListener listener)
- throws ListenerNotFoundException, IOException {
- if (logger.traceOn()) {
- logger.trace("unsubscribe", "");
- }
- checkState();
- final Integer listenerId =
- getMatchedListenerInfo(name, listener, true);
-
- synchronized(listenerInfoMap) {
- if (listenerInfoMap.remove(listenerId) == null) {
- throw new ListenerNotFoundException();
- }
- }
-
- stopListening();
-
- try {
- eventClientDelegate.removeListenerOrSubscriber(clientId, listenerId);
- } catch (InstanceNotFoundException e) {
- logger.trace("unsubscribe", "removeSubscriber", e);
- } catch (EventClientNotFoundException cnfe) {
- logger.trace("unsubscribe", "removeSubscriber", cnfe);
- }
- }
-
- /**
- * @see javax.management.event.EventConsumer#subscribe(
- * ObjectName, NotificationListener, NotificationFilter, Object).
- */
- public void subscribe(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback) throws IOException {
- if (logger.traceOn()) {
- logger.trace("subscribe", "");
- }
-
- checkState();
-
- Integer listenerId;
- try {
- listenerId =
- eventClientDelegate.addSubscriber(clientId, name, filter);
- } catch (EventClientNotFoundException ecnfe) {
- final IOException ioe = new IOException(ecnfe.getMessage());
- ioe.initCause(ecnfe);
- throw ioe;
- }
-
- synchronized(listenerInfoMap) {
- listenerInfoMap.put(listenerId, new ListenerInfo(
- name,
- listener,
- filter,
- handback,
- true));
- }
-
- startListening();
- }
-
- /**
- * <p>Adds a set of listeners to the remote MBeanServer. This method can
- * be used to copy the listeners from one {@code EventClient} to another.</p>
- *
- * <p>A listener is represented by a {@link ListenerInfo} object. The listener
- * is added by calling {@link #subscribe(ObjectName,
- * NotificationListener, NotificationFilter, Object)} if the method
- * {@link ListenerInfo#isSubscription() isSubscription}
- * returns {@code true}; otherwise it is added by calling
- * {@link #addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object)}.</p>
- *
- * <P>The method returns the listeners which were added successfully. The
- * elements in the returned collection are a subset of the elements in
- * {@code listeners}. If all listeners were added successfully, the two
- * collections are the same. If no listener was added successfully, the
- * returned collection is empty.</p>
- *
- * @param listeners the listeners to add.
- *
- * @return The listeners that were added successfully.
- *
- * @throws IOException If an I/O error occurs.
- *
- * @see #getListeners()
- */
- public Collection<ListenerInfo> addListeners(Collection<ListenerInfo> listeners)
- throws IOException {
- if (logger.traceOn()) {
- logger.trace("addListeners", "");
- }
-
- checkState();
-
- if (listeners == null || listeners.isEmpty())
- return Collections.emptySet();
-
- final List<ListenerInfo> list = new ArrayList<ListenerInfo>();
- for (ListenerInfo l : listeners) {
- try {
- if (l.isSubscription()) {
- subscribe(l.getObjectName(),
- l.getListener(),
- l.getFilter(),
- l.getHandback());
- } else {
- addNotificationListener(l.getObjectName(),
- l.getListener(),
- l.getFilter(),
- l.getHandback());
- }
-
- list.add(l);
- } catch (Exception e) {
- if (logger.traceOn()) {
- logger.trace("addListeners", "failed to add: "+l, e);
- }
- }
- }
-
- return list;
- }
-
- /**
- * <p>Returns the collection of listeners that have been added through
- * this {@code EventClient} and not subsequently removed. The returned
- * collection contains one entry for every listener added with
- * {@link #addNotificationListener addNotificationListener} or
- * {@link #subscribe subscribe} and not subsequently removed with
- * {@link #removeNotificationListener removeNotificationListener} or
- * {@link #unsubscribe unsubscribe}, respectively.</p>
- *
- * @return A collection of listener information. Empty if there are no
- * current listeners or if this {@code EventClient} has been {@linkplain
- * #close closed}.
- *
- * @see #addListeners
- */
- public Collection<ListenerInfo> getListeners() {
- if (logger.traceOn()) {
- logger.trace("getListeners", "");
- }
-
- synchronized(listenerInfoMap) {
- return Collections.unmodifiableCollection(listenerInfoMap.values());
- }
- }
-
- /**
- * Adds a listener to receive the {@code EventClient} notifications specified in
- * {@link #getEventClientNotificationInfo}.
- *
- * @param listener A listener to receive {@code EventClient} notifications.
- * @param filter A filter to select which notifications are to be delivered
- * to the listener, or {@code null} if all notifications are to be delivered.
- * @param handback An object to be given to the listener along with each
- * notification. Can be null.
- * @throws NullPointerException If listener is null.
- * @see #removeEventClientListener
- */
- public void addEventClientListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
- if (logger.traceOn()) {
- logger.trace("addEventClientListener", "");
- }
- broadcaster.addNotificationListener(listener, filter, handback);
- }
-
- /**
- * Removes a listener added to receive {@code EventClient} notifications specified in
- * {@link #getEventClientNotificationInfo}.
- *
- * @param listener A listener to receive {@code EventClient} notifications.
- * @throws NullPointerException If listener is null.
- * @throws ListenerNotFoundException If the listener is not added to
- * this {@code EventClient}.
- */
- public void removeEventClientListener(NotificationListener listener)
- throws ListenerNotFoundException {
- if (logger.traceOn()) {
- logger.trace("removeEventClientListener", "");
- }
- broadcaster.removeNotificationListener(listener);
- }
-
- /**
- * <p>Get the types of notification that an {@code EventClient} can send
- * to listeners added with {@link #addEventClientListener
- * addEventClientListener}.</p>
- *
- * @return Types of notification emitted by this {@code EventClient}.
- *
- * @see #FAILED
- * @see #NONFATAL
- * @see #NOTIFS_LOST
- */
- public MBeanNotificationInfo[] getEventClientNotificationInfo() {
- return myInfo.clone();
- }
-
- private static boolean match(ListenerInfo li,
- ObjectName name,
- NotificationListener listener,
- boolean subscribed) {
- return li.getObjectName().equals(name) &&
- li.getListener() == listener &&
- li.isSubscription() == subscribed;
- }
-
- private static boolean match(ListenerInfo li,
- ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback,
- boolean subscribed) {
- return li.getObjectName().equals(name) &&
- li.getFilter() == filter &&
- li.getListener() == listener &&
- li.getHandback() == handback &&
- li.isSubscription() == subscribed;
- }
-
-// ---------------------------------------------------
-// private classes
-// ---------------------------------------------------
- private class DispatchingJob extends RepeatedSingletonJob {
- public DispatchingJob() {
- super(distributingExecutor);
- }
-
- public boolean isSuspended() {
- return closed || buffer.size() == 0;
- }
-
- public void task() {
- TargetedNotification[] tns ;
- int lost = 0;
-
- synchronized(buffer) {
- tns = buffer.removeNotifs();
- lost = buffer.removeLost();
- }
-
- if ((tns == null || tns.length == 0)
- && lost == 0) {
- return;
- }
-
- // forwarding
- if (tns != null && tns.length > 0) {
- if (logger.traceOn()) {
- logger.trace("DispatchingJob-task",
- "Forwarding: "+tns.length);
- }
- for (TargetedNotification tn : tns) {
- final ListenerInfo li = listenerInfoMap.get(tn.getListenerID());
- try {
- li.getListener().handleNotification(tn.getNotification(),
- li.getHandback());
- } catch (Exception e) {
- logger.fine(
- "DispatchingJob.task", "listener got exception", e);
- }
- }
- }
-
- if (lost > 0) {
- if (logger.traceOn()) {
- logger.trace("DispatchingJob-task",
- "lost: "+lost);
- }
- final Notification n = new Notification(NOTIFS_LOST,
- EventClient.this,
- myNotifCounter.getAndIncrement(),
- System.currentTimeMillis(),
- "Lost notifications.");
- n.setUserData(new Long(lost));
- broadcaster.sendNotification(n);
- }
- }
- }
-
-
- private class EventReceiverImpl implements EventReceiver {
- public void receive(NotificationResult nr) {
- if (logger.traceOn()) {
- logger.trace("MyEventReceiver-receive", "");
- }
-
- synchronized(buffer) {
- buffer.addNotifs(nr);
-
- dispatchingJob.resume();
- }
- }
-
- public void failed(Throwable t) {
- if (logger.traceOn()) {
- logger.trace("MyEventReceiver-failed", "", t);
- }
- final Notification n = new Notification(FAILED,
- this,
- myNotifCounter.getAndIncrement(),
- System.currentTimeMillis());
- n.setSource(t);
- broadcaster.sendNotification(n);
- }
-
- public void nonFatal(Exception e) {
- if (logger.traceOn()) {
- logger.trace("MyEventReceiver-nonFatal", "", e);
- }
-
- final Notification n = new Notification(NONFATAL,
- this,
- myNotifCounter.getAndIncrement(),
- System.currentTimeMillis());
- n.setSource(e);
- broadcaster.sendNotification(n);
- }
- }
-
-// ----------------------------------------------------
-// private class
-// ----------------------------------------------------
-
-
-// ----------------------------------------------------
-// private methods
-// ----------------------------------------------------
- private Integer getListenerInfo(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback,
- boolean subscribed) throws ListenerNotFoundException {
-
- synchronized(listenerInfoMap) {
- for (Map.Entry<Integer, ListenerInfo> entry :
- listenerInfoMap.entrySet()) {
- ListenerInfo li = entry.getValue();
- if (match(li, name, listener, filter, handback, subscribed)) {
- return entry.getKey();
- }
- }
- }
-
- throw new ListenerNotFoundException();
- }
-
- private Integer getMatchedListenerInfo(ObjectName name,
- NotificationListener listener,
- boolean subscribed) throws ListenerNotFoundException {
-
- synchronized(listenerInfoMap) {
- for (Map.Entry<Integer, ListenerInfo> entry :
- listenerInfoMap.entrySet()) {
- ListenerInfo li = entry.getValue();
- if (li.getObjectName().equals(name) &&
- li.getListener() == listener &&
- li.isSubscription() == subscribed) {
- return entry.getKey();
- }
- }
- }
-
- throw new ListenerNotFoundException();
- }
-
- private Collection<Integer> getListenerInfo(ObjectName name,
- NotificationListener listener,
- boolean subscribed) throws ListenerNotFoundException {
-
- final ArrayList<Integer> ids = new ArrayList<Integer>();
- synchronized(listenerInfoMap) {
- for (Map.Entry<Integer, ListenerInfo> entry :
- listenerInfoMap.entrySet()) {
- ListenerInfo li = entry.getValue();
- if (match(li, name, listener, subscribed)) {
- ids.add(entry.getKey());
- }
- }
- }
-
- if (ids.isEmpty()) {
- throw new ListenerNotFoundException();
- }
-
- return ids;
- }
-
- private void checkState() throws IOException {
- synchronized(listenerInfoMap) {
- if (closed) {
- throw new IOException("Ended!");
- }
- }
- }
-
- private void startListening() throws IOException {
- synchronized(listenerInfoMap) {
- if (!startedListening && listenerInfoMap.size() > 0) {
- eventRelay.setEventReceiver(myReceiver);
- }
-
- startedListening = true;
-
- if (logger.traceOn()) {
- logger.trace("startListening", "listening");
- }
- }
- }
-
- private void stopListening() throws IOException {
- synchronized(listenerInfoMap) {
- if (listenerInfoMap.size() == 0 && startedListening) {
- eventRelay.setEventReceiver(null);
-
- startedListening = false;
-
- if (logger.traceOn()) {
- logger.trace("stopListening", "non listening");
- }
- }
- }
- }
-
- private void removeListener(Integer id)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
- synchronized(listenerInfoMap) {
- if (listenerInfoMap.remove(id) == null) {
- throw new ListenerNotFoundException();
- }
-
- stopListening();
- }
-
- try {
- eventClientDelegate.removeListenerOrSubscriber(clientId, id);
- } catch (EventClientNotFoundException cnfe) {
- logger.trace("removeListener", "ecd.removeListener", cnfe);
- }
- }
-
-
-// ----------------------------------------------------
-// private variables
-// ----------------------------------------------------
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "EventClient");
-
- private final Executor distributingExecutor;
- private final EventClientDelegateMBean eventClientDelegate;
- private final EventRelay eventRelay;
- private volatile String clientId = null;
- private final long requestedLeaseTime;
-
- private final ReceiverBuffer buffer = new ReceiverBuffer();
-
- private final EventReceiverImpl myReceiver =
- new EventReceiverImpl();
- private final DispatchingJob dispatchingJob;
-
- private final HashMap<Integer, ListenerInfo> listenerInfoMap =
- new HashMap<Integer, ListenerInfo>();
-
- private volatile boolean closed = false;
-
- private volatile boolean startedListening = false;
-
- // Could change synchronization here. But at worst a race will mean
- // sequence numbers are not contiguous, which may not matter much.
- private final AtomicLong myNotifCounter = new AtomicLong();
-
- private final static MBeanNotificationInfo[] myInfo =
- new MBeanNotificationInfo[] {
- new MBeanNotificationInfo(
- new String[] {FAILED, NONFATAL, NOTIFS_LOST},
- Notification.class.getName(),
- "Notifications that can be sent to a listener added with " +
- "EventClient.addEventClientListener")};
-
- private final NotificationBroadcasterSupport broadcaster =
- new NotificationBroadcasterSupport();
-
- private final static Executor callerExecutor = new Executor() {
- // DirectExecutor using caller thread
- public void execute(Runnable r) {
- r.run();
- }
- };
-
- private static void checkInit(final MBeanServerConnection conn,
- final ObjectName delegateName)
- throws IOException {
- if (conn == null) {
- throw new IllegalArgumentException("No connection specified");
- }
- if (delegateName != null &&
- (!conn.isRegistered(delegateName))) {
- throw new IllegalArgumentException(
- delegateName +
- ": not found");
- }
- if (delegateName == null &&
- (!conn.isRegistered(
- EventClientDelegate.OBJECT_NAME))) {
- throw new IllegalArgumentException(
- EventClientDelegate.OBJECT_NAME +
- ": not found");
- }
- }
-
-// ----------------------------------------------------
-// private event lease issues
-// ----------------------------------------------------
- private Callable<Long> renewLease = new Callable<Long>() {
- public Long call() throws IOException, EventClientNotFoundException {
- return eventClientDelegate.lease(clientId, requestedLeaseTime);
- }
- };
-
- private final LeaseRenewer leaseRenewer;
-
-// ------------------------------------------------------------------------
- /**
- * Constructs an {@code MBeanServerConnection} that uses an {@code EventClient} object,
- * if the underlying connection has an {@link EventClientDelegateMBean}.
- * <P> The {@code EventClient} object creates a default
- * {@link FetchingEventRelay} object to
- * receive notifications forwarded by the {@link EventClientDelegateMBean}.
- * The {@link EventClientDelegateMBean} it works with is the
- * default one registered with the ObjectName
- * {@link EventClientDelegate#OBJECT_NAME
- * OBJECT_NAME}.
- * The thread from the {@link FetchingEventRelay} object that fetches the
- * notifications is also used to distribute them.
- *
- * @param conn An {@link MBeanServerConnection} object used to communicate
- * with an {@link EventClientDelegateMBean}.
- * @throws IllegalArgumentException If the value of {@code conn} is null,
- * or the default {@link EventClientDelegateMBean} is not registered.
- * @throws IOException If an I/O error occurs.
- */
- public static MBeanServerConnection getEventClientConnection(
- final MBeanServerConnection conn)
- throws IOException {
- return getEventClientConnection(conn, null);
- }
-
- /**
- * Constructs an MBeanServerConnection that uses an {@code EventClient}
- * object with a user-specific {@link EventRelay}
- * object.
- * <P>
- * The {@link EventClientDelegateMBean} which it works with is the
- * default one registered with the ObjectName
- * {@link EventClientDelegate#OBJECT_NAME
- * OBJECT_NAME}
- * The thread that calls {@link EventReceiver#receive
- * EventReceiver.receive} from the {@link EventRelay} object is used
- * to distribute notifications to their listeners.
- *
- * @param conn An {@link MBeanServerConnection} object used to communicate
- * with an {@link EventClientDelegateMBean}.
- * @param eventRelay A user-specific object used to receive notifications
- * forwarded by the {@link EventClientDelegateMBean}. If null, the default
- * {@link FetchingEventRelay} object is used.
- * @throws IllegalArgumentException If the value of {@code conn} is null,
- * or the default {@link EventClientDelegateMBean} is not registered.
- * @throws IOException If an I/O error occurs.
- */
- public static MBeanServerConnection getEventClientConnection(
- final MBeanServerConnection conn,
- final EventRelay eventRelay)
- throws IOException {
-
- if (newEventConn == null) {
- throw new IllegalArgumentException(
- "Class not found: EventClientConnection");
- }
-
- checkInit(conn,null);
- final Callable<EventClient> factory = new Callable<EventClient>() {
- final public EventClient call() throws Exception {
- EventClientDelegateMBean ecd = EventClientDelegate.getProxy(conn);
- return new EventClient(ecd, eventRelay, null, null,
- DEFAULT_REQUESTED_LEASE_TIME);
- }
- };
-
- try {
- return (MBeanServerConnection)newEventConn.invoke(null,
- conn, factory);
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private static Method newEventConn = null;
- static {
- try {
- Class<?> c = Class.forName(
- "com.sun.jmx.remote.util.EventClientConnection",
- false, Thread.currentThread().getContextClassLoader());
- newEventConn = c.getMethod("getEventConnectionFor",
- MBeanServerConnection.class, Callable.class);
- } catch (Exception e) {
- // OK: we're running in a subset of our classes
- }
- }
-
- /**
- * <p>Get the client id of this {@code EventClient} in the
- * {@link EventClientDelegateMBean}.
- *
- * @return the client id.
- *
- * @see EventClientDelegateMBean#addClient(String, Object[], String[])
- * EventClientDelegateMBean.addClient
- */
- public String getClientId() {
- return clientId;
- }
-
- private static final PerThreadGroupPool<ScheduledThreadPoolExecutor>
- leaseRenewerThreadPool = PerThreadGroupPool.make();
-}
--- a/jdk/src/share/classes/javax/management/event/EventClientDelegate.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,824 +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.
- *
- * @since JMX 2.0
- */
-
-package javax.management.event;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.UUID;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.remote.NotificationResult;
-import com.sun.jmx.event.EventBuffer;
-import com.sun.jmx.event.LeaseManager;
-import com.sun.jmx.interceptor.SingleMBeanForwarder;
-import com.sun.jmx.mbeanserver.Util;
-import com.sun.jmx.remote.util.ClassLogger;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.management.DynamicMBean;
-import javax.management.MBeanException;
-import javax.management.MBeanPermission;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.MBeanServerNotification;
-import javax.management.ObjectInstance;
-import javax.management.StandardMBean;
-import javax.management.remote.MBeanServerForwarder;
-
-/**
- * This is the default implementation of the MBean
- * {@link EventClientDelegateMBean}.
- */
-public class EventClientDelegate implements EventClientDelegateMBean {
-
- private EventClientDelegate(MBeanServer server) {
- if (server == null) {
- throw new NullPointerException("Null MBeanServer.");
- }
-
- if (logger.traceOn()) {
- logger.trace("EventClientDelegate", "new one");
- }
- mbeanServer = server;
- eventSubscriber = EventSubscriber.getEventSubscriber(mbeanServer);
- }
-
- /**
- * Returns an {@code EventClientDelegate} instance for the given
- * {@code MBeanServer}. Calling this method more than once with the same
- * {@code server} argument may return the same object or a different object
- * each time. See {@link EventClientDelegateMBean} for an example use of
- * this method.
- *
- * @param server An MBean server instance to work with.
- * @return An {@code EventClientDelegate} instance.
- * @throws NullPointerException If {@code server} is null.
- */
- public static EventClientDelegate getEventClientDelegate(MBeanServer server) {
- EventClientDelegate delegate = null;
- synchronized(delegateMap) {
- final WeakReference<EventClientDelegate> wrf = delegateMap.get(server);
- delegate = (wrf == null) ? null : wrf.get();
-
- if (delegate == null) {
- delegate = new EventClientDelegate(server);
- try {
- // TODO: this may not work with federated MBean, because
- // the delegate will *not* emit notifications for those MBeans.
- delegate.mbeanServer.addNotificationListener(
- MBeanServerDelegate.DELEGATE_NAME,
- delegate.cleanListener, null, null);
- } catch (InstanceNotFoundException e) {
- logger.fine(
- "getEventClientDelegate",
- "Could not add MBeanServerDelegate listener", e);
- }
- delegateMap.put(server,
- new WeakReference<EventClientDelegate>(delegate));
- }
- }
-
- return delegate;
- }
-
- // Logic for the MBeanServerForwarder that simulates the existence of the
- // EventClientDelegate MBean. Things are complicated by the fact that
- // there may not be anything in the chain after this forwarder when it is
- // created - the connection to a real MBeanServer might only come later.
- // Recall that there are two ways of creating a JMXConnectorServer -
- // either you specify its MBeanServer when you create it, or you specify
- // no MBeanServer and register it in an MBeanServer later. In the latter
- // case, the forwarder chain points nowhere until this registration
- // happens. Since EventClientDelegate wants to add a listener to the
- // MBeanServerDelegate, we can't create an EventClientDelegate until
- // there is an MBeanServer. So the forwarder initially has
- // a dummy ECD where every method throws an exception, and
- // the real ECD is created as soon as doing so does not produce an
- // exception.
- // TODO: rewrite so that the switch from the dummy to the real ECD happens
- // just before we would otherwise have thrown UnsupportedOperationException.
- // This is more correct, because it's not guaranteed that we will see the
- // moment where the real MBeanServer is attached, if it happens by virtue
- // of a setMBeanServer on some other forwarder later in the chain.
-
- private static class Forwarder extends SingleMBeanForwarder {
- private MBeanServer loopMBS;
-
- private static class UnsupportedInvocationHandler
- implements InvocationHandler {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- throw new UnsupportedOperationException(
- "EventClientDelegate unavailable: no MBeanServer, or " +
- "MBeanServer inaccessible");
- }
- }
-
- private static DynamicMBean makeUnsupportedECD() {
- EventClientDelegateMBean unsupported = (EventClientDelegateMBean)
- Proxy.newProxyInstance(
- EventClientDelegateMBean.class.getClassLoader(),
- new Class<?>[] {EventClientDelegateMBean.class},
- new UnsupportedInvocationHandler());
- return new StandardMBean(
- unsupported, EventClientDelegateMBean.class, false);
- }
-
- private volatile boolean madeECD;
-
- Forwarder() {
- super(OBJECT_NAME, makeUnsupportedECD(), true);
- }
-
- synchronized void setLoopMBS(MBeanServer loopMBS) {
- this.loopMBS = loopMBS;
- }
-
- @Override
- public synchronized void setMBeanServer(final MBeanServer mbs) {
- super.setMBeanServer(mbs);
-
- if (!madeECD) {
- try {
- EventClientDelegate ecd =
- AccessController.doPrivileged(
- new PrivilegedAction<EventClientDelegate>() {
- public EventClientDelegate run() {
- return getEventClientDelegate(loopMBS);
- }
- });
- DynamicMBean mbean = new StandardMBean(
- ecd, EventClientDelegateMBean.class, false);
- setSingleMBean(mbean);
- madeECD = true;
- } catch (Exception e) {
- // OK: assume no MBeanServer
- logger.fine("setMBeanServer", "isRegistered", e);
- }
- }
- }
- }
-
- /**
- * <p>Create a new {@link MBeanServerForwarder} that simulates the existence
- * of an {@code EventClientDelegateMBean} with the {@linkplain
- * #OBJECT_NAME default name}. This forwarder intercepts MBean requests
- * that are targeted for that MBean and handles them itself. All other
- * requests are forwarded to the next element in the forwarder chain.</p>
- *
- * @param nextMBS the next {@code MBeanServer} in the chain of forwarders,
- * which might be another {@code MBeanServerForwarder} or a plain {@code
- * MBeanServer}. This is the object to which {@code MBeanServer} requests
- * that do not concern the {@code EventClientDelegateMBean} are sent.
- * It will be the value of {@link MBeanServerForwarder#getMBeanServer()
- * getMBeanServer()} on the returned object, and can be changed with {@link
- * MBeanServerForwarder#setMBeanServer setMBeanServer}. It can be null but
- * must be set to a non-null value before any {@code MBeanServer} requests
- * arrive.
- *
- * @param loopMBS the {@code MBeanServer} to which requests from the
- * {@code EventClientDelegateMBean} should be sent. For example,
- * when you invoke the {@link EventClientDelegateMBean#addListener
- * addListener} operation on the {@code EventClientDelegateMBean}, it will
- * result in a call to {@link
- * MBeanServer#addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object) addNotificationListener} on this object.
- * If this parameter is null, then these requests will be sent to the
- * newly-created {@code MBeanServerForwarder}. Usually the parameter will
- * either be null or will be the result of {@link
- * javax.management.remote.JMXConnectorServer#getSystemMBeanServerForwarder()
- * getSystemMBeanServerForwarder()} for the connector server in which
- * this forwarder will be installed.
- *
- * @return a new {@code MBeanServerForwarder} that simulates the existence
- * of an {@code EventClientDelegateMBean}.
- *
- * @see javax.management.remote.JMXConnectorServer#installStandardForwarders
- */
- public static MBeanServerForwarder newForwarder(
- MBeanServer nextMBS, MBeanServer loopMBS) {
- Forwarder mbsf = new Forwarder();
- // We must setLoopMBS before setMBeanServer, because when we
- // setMBeanServer that will call getEventClientDelegate(loopMBS).
- if (loopMBS == null)
- loopMBS = mbsf;
- mbsf.setLoopMBS(loopMBS);
- if (nextMBS != null)
- mbsf.setMBeanServer(nextMBS);
- return mbsf;
- }
-
- /**
- * Returns a proxy of the default {@code EventClientDelegateMBean}.
- *
- * @param conn An {@link MBeanServerConnection} to work with.
- */
- @SuppressWarnings("cast") // cast for jdk 1.5
- public static EventClientDelegateMBean getProxy(MBeanServerConnection conn) {
- return (EventClientDelegateMBean)MBeanServerInvocationHandler.
- newProxyInstance(conn,
- OBJECT_NAME,
- EventClientDelegateMBean.class,
- false);
- }
-
- public String addClient(String className, Object[] params, String[] sig)
- throws MBeanException {
- return addClient(className, null, params, sig, true);
- }
-
- public String addClient(String className,
- ObjectName classLoader,
- Object[] params,
- String[] sig) throws MBeanException {
- return addClient(className, classLoader, params, sig, false);
- }
-
- private String addClient(String className,
- ObjectName classLoader,
- Object[] params,
- String[] sig,
- boolean classLoaderRepository) throws MBeanException {
- try {
- return addClientX(
- className, classLoader, params, sig, classLoaderRepository);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new MBeanException(e);
- }
- }
-
- private String addClientX(String className,
- ObjectName classLoader,
- Object[] params,
- String[] sig,
- boolean classLoaderRepository) throws Exception {
- if (className == null) {
- throw new IllegalArgumentException("Null class name.");
- }
-
- final Object o;
-
- // The special treatment of standard EventForwarders is so that no
- // special permissions are necessary to use them. Otherwise you
- // couldn't use EventClient if you didn't have permission to call
- // MBeanServer.instantiate. We do require that permission for
- // non-standard forwarders, because otherwise you could instantiate
- // any class with possibly adverse consequences. We also avoid using
- // MBeanInstantiator because it looks up constructors by loading each
- // class in the sig array, which means a remote user could cause any
- // class to be loaded. That's probably not hugely risky but still.
- if (className.startsWith("javax.management.event.")) {
- Class<?> c = Class.forName(
- className, false, this.getClass().getClassLoader());
- Constructor<?> foundCons = null;
- if (sig == null)
- sig = new String[0];
- for (Constructor<?> cons : c.getConstructors()) {
- Class<?>[] types = cons.getParameterTypes();
- String[] consSig = new String[types.length];
- for (int i = 0; i < types.length; i++)
- consSig[i] = types[i].getName();
- if (Arrays.equals(sig, consSig)) {
- foundCons = cons;
- break;
- }
- }
- if (foundCons == null) {
- throw new NoSuchMethodException(
- "Constructor for " + className + " with argument types " +
- Arrays.toString(sig));
- }
- o = foundCons.newInstance(params);
- } else if (classLoaderRepository) {
- o = mbeanServer.instantiate(className, params, sig);
- } else {
- o = mbeanServer.instantiate(className, classLoader, params, sig);
- }
-
- if (!(o instanceof EventForwarder)) {
- throw new IllegalArgumentException(
- className+" is not an EventForwarder class.");
- }
-
- final EventForwarder forwarder = (EventForwarder)o;
- final String clientId = UUID.randomUUID().toString();
- ClientInfo clientInfo = new ClientInfo(clientId, forwarder);
-
- clientInfoMap.put(clientId, clientInfo);
-
- forwarder.setClientId(clientId);
-
- if (logger.traceOn()) {
- logger.trace("addClient", clientId);
- }
-
- return clientId;
- }
-
- public Integer[] getListenerIds(String clientId)
- throws IOException, EventClientNotFoundException {
- ClientInfo clientInfo = getClientInfo(clientId);
-
- if (clientInfo == null) {
- throw new EventClientNotFoundException("The client is not found.");
- }
-
- Map<Integer, AddedListener> listenerInfoMap = clientInfo.listenerInfoMap;
- synchronized (listenerInfoMap) {
- Set<Integer> ids = listenerInfoMap.keySet();
- return ids.toArray(new Integer[ids.size()]);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The execution of this method includes a call to
- * {@link MBeanServer#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)}.</p>
- */
- public Integer addListener(String clientId,
- final ObjectName name,
- NotificationFilter filter)
- throws EventClientNotFoundException, InstanceNotFoundException {
-
- if (logger.traceOn()) {
- logger.trace("addListener", "");
- }
-
- return getClientInfo(clientId).addListenerInfo(name, filter);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The execution of this method can include call to
- * {@link MBeanServer#removeNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)}.</p>
- */
- public void removeListenerOrSubscriber(String clientId, Integer listenerId)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- EventClientNotFoundException,
- IOException {
- if (logger.traceOn()) {
- logger.trace("removeListener", ""+listenerId);
- }
- getClientInfo(clientId).removeListenerInfo(listenerId);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The execution of this method includes a call to
- * {@link MBeanServer#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)} for
- * every MBean matching {@code name}. If {@code name} is
- * an {@code ObjectName} pattern, then the execution of this
- * method will include a call to {@link MBeanServer#queryNames}.</p>
- */
- public Integer addSubscriber(String clientId, ObjectName name,
- NotificationFilter filter)
- throws EventClientNotFoundException, IOException {
- if (logger.traceOn()) {
- logger.trace("addSubscriber", "");
- }
- return getClientInfo(clientId).subscribeListenerInfo(name, filter);
- }
-
- public NotificationResult fetchNotifications(String clientId,
- long startSequenceNumber,
- int maxNotifs,
- long timeout)
- throws EventClientNotFoundException {
- if (logger.traceOn()) {
- logger.trace("fetchNotifications", "for "+clientId);
- }
- return getClientInfo(clientId).fetchNotifications(startSequenceNumber,
- maxNotifs,
- timeout);
- }
-
- public void removeClient(String clientId)
- throws EventClientNotFoundException {
- if (clientId == null)
- throw new EventClientNotFoundException("Null clientId");
- if (logger.traceOn()) {
- logger.trace("removeClient", clientId);
- }
- ClientInfo ci = null;
- ci = clientInfoMap.remove(clientId);
-
- if (ci == null) {
- throw new EventClientNotFoundException("clientId is "+clientId);
- } else {
- ci.clean();
- }
- }
-
- public long lease(String clientId, long timeout)
- throws IOException, EventClientNotFoundException {
- if (logger.traceOn()) {
- logger.trace("lease", "for "+clientId);
- }
- return getClientInfo(clientId).lease(timeout);
- }
-
- // ------------------------------------
- // private classes
- // ------------------------------------
- private class ClientInfo {
- final String clientId;
- final NotificationListener clientListener;
- final Map<Integer, AddedListener> listenerInfoMap =
- new HashMap<Integer, AddedListener>();
-
- ClientInfo(String clientId, EventForwarder forwarder) {
- this.clientId = clientId;
- this.forwarder = forwarder;
- clientListener =
- new ForwardingClientListener(listenerInfoMap, forwarder);
- }
-
- Integer addOrSubscribeListenerInfo(
- ObjectName name, NotificationFilter filter, boolean subscribe)
- throws InstanceNotFoundException, IOException {
-
- final Integer listenerId = nextListenerId();
- AddedListener listenerInfo = new AddedListener(
- listenerId, filter, name, subscribe);
- if (subscribe) {
- eventSubscriber.subscribe(name,
- clientListener,
- filter,
- listenerInfo);
- } else {
- mbeanServer.addNotificationListener(name,
- clientListener,
- filter,
- listenerInfo);
- }
-
- synchronized(listenerInfoMap) {
- listenerInfoMap.put(listenerId, listenerInfo);
- }
-
- return listenerId;
- }
-
- Integer addListenerInfo(ObjectName name,
- NotificationFilter filter) throws InstanceNotFoundException {
- try {
- return addOrSubscribeListenerInfo(name, filter, false);
- } catch (IOException e) { // can't happen
- logger.warning(
- "EventClientDelegate.addListenerInfo",
- "unexpected exception", e);
- throw new RuntimeException(e);
- }
- }
-
- Integer subscribeListenerInfo(ObjectName name,
- NotificationFilter filter) throws IOException {
- try {
- return addOrSubscribeListenerInfo(name, filter, true);
- } catch (InstanceNotFoundException e) { // can't happen
- logger.warning(
- "EventClientDelegate.subscribeListenerInfo",
- "unexpected exception", e);
- throw new RuntimeException(e);
- }
- }
-
- private final AtomicInteger nextListenerId = new AtomicInteger();
-
- private Integer nextListenerId() {
- return nextListenerId.getAndIncrement();
- }
-
- NotificationResult fetchNotifications(long startSequenceNumber,
- int maxNotifs,
- long timeout) {
-
- if (!(forwarder instanceof FetchingEventForwarder)) {
- throw new IllegalArgumentException(
- "This client is using Event Postal Service!");
- }
-
- return ((FetchingEventForwarder)forwarder).
- fetchNotifications(startSequenceNumber,
- maxNotifs, timeout);
- }
-
- void removeListenerInfo(Integer listenerId)
- throws InstanceNotFoundException, ListenerNotFoundException, IOException {
- AddedListener listenerInfo;
- synchronized(listenerInfoMap) {
- listenerInfo = listenerInfoMap.remove(listenerId);
- }
-
- if (listenerInfo == null) {
- throw new ListenerNotFoundException("The listener is not found.");
- }
-
- if (listenerInfo.subscription) {
- eventSubscriber.unsubscribe(listenerInfo.name,
- clientListener);
- } else {
- mbeanServer.removeNotificationListener(listenerInfo.name,
- clientListener,
- listenerInfo.filter,
- listenerInfo);
- }
- }
-
- void clean(ObjectName name) {
- synchronized(listenerInfoMap) {
- for (Map.Entry<Integer, AddedListener> entry :
- listenerInfoMap.entrySet()) {
- AddedListener li = entry.getValue();
- if (name.equals(li.name)) {
- listenerInfoMap.remove(entry.getKey());
- }
- }
- }
- }
-
- void clean() {
- synchronized(listenerInfoMap) {
- for (AddedListener li : listenerInfoMap.values()) {
- try {
- mbeanServer.removeNotificationListener(li.name,
- clientListener);
- } catch (Exception e) {
- logger.trace("ClientInfo.clean", "removeNL", e);
- }
- }
- listenerInfoMap.clear();
- }
-
- try {
- forwarder.close();
- } catch (Exception e) {
- logger.trace(
- "ClientInfo.clean", "forwarder.close", e);
- }
-
- if (leaseManager != null) {
- leaseManager.stop();
- }
- }
-
- long lease(long timeout) {
- return leaseManager.lease(timeout);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (o instanceof ClientInfo &&
- clientId.equals(((ClientInfo)o).clientId)) {
- return true;
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return clientId.hashCode();
- }
-
- private EventForwarder forwarder = null;
-
- private final Runnable leaseExpiryCallback = new Runnable() {
- public void run() {
- try {
- removeClient(clientId);
- } catch (Exception e) {
- logger.trace(
- "ClientInfo.leaseExpiryCallback", "removeClient", e);
- }
- }
- };
-
- private LeaseManager leaseManager = new LeaseManager(leaseExpiryCallback);
- }
-
- private class ForwardingClientListener implements NotificationListener {
- public ForwardingClientListener(Map<Integer, AddedListener> listenerInfoMap,
- EventForwarder forwarder) {
- this.listenerInfoMap = listenerInfoMap;
- this.forwarder = forwarder;
- }
-
- public void handleNotification(Notification n, Object o) {
- if (n == null || (!(o instanceof AddedListener))) {
- if (logger.traceOn()) {
- logger.trace("ForwardingClientListener-handleNotification",
- "received a unknown notif");
- }
- return;
- }
-
- AddedListener li = (AddedListener) o;
-
- if (checkListenerPermission(li.name,li.acc)) {
- try {
- forwarder.forward(n, li.listenerId);
- } catch (Exception e) {
- if (logger.traceOn()) {
- logger.trace(
- "ForwardingClientListener-handleNotification",
- "forwarding failed.", e);
- }
- }
- }
- }
-
- private final Map<Integer, AddedListener> listenerInfoMap;
- private final EventForwarder forwarder;
- }
-
- private class AddedListener {
- final int listenerId;
- final NotificationFilter filter;
- final ObjectName name;
- final boolean subscription;
- final AccessControlContext acc;
-
- public AddedListener(
- int listenerId,
- NotificationFilter filter,
- ObjectName name,
- boolean subscription) {
- this.listenerId = listenerId;
- this.filter = filter;
- this.name = name;
- this.subscription = subscription;
- acc = AccessController.getContext();
- }
- }
-
- private class CleanListener implements NotificationListener {
- public void handleNotification(Notification notification,
- Object handback) {
- if (notification instanceof MBeanServerNotification) {
- if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(
- notification.getType())) {
- final ObjectName name =
- ((MBeanServerNotification)notification).getMBeanName();
-
- final Collection <ClientInfo> list =
- Collections.unmodifiableCollection(clientInfoMap.values());
-
- for (ClientInfo ci : list) {
- ci.clean(name);
- }
- }
-
- }
- }
- }
-
- // -------------------------------------------------
- // private method
- // -------------------------------------------------
- private ClientInfo getClientInfo(String clientId)
- throws EventClientNotFoundException {
- ClientInfo clientInfo = null;
- clientInfo = clientInfoMap.get(clientId);
-
- if (clientInfo == null) {
- throw new EventClientNotFoundException(
- "Client not found (id " + clientId + ")");
- }
-
- return clientInfo;
- }
-
- /**
- * Explicitly check the MBeanPermission for
- * the current access control context.
- */
- private boolean checkListenerPermission(final ObjectName name,
- final AccessControlContext acc) {
- if (logger.traceOn()) {
- logger.trace("checkListenerPermission", "");
- }
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- try {
- final String serverName = getMBeanServerName();
-
- ObjectInstance oi = (ObjectInstance)
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<Object>() {
- public Object run()
- throws InstanceNotFoundException {
- return mbeanServer.getObjectInstance(name);
- }
- });
-
- String classname = oi.getClassName();
- MBeanPermission perm = new MBeanPermission(
- serverName,
- classname,
- null,
- name,
- "addNotificationListener");
- sm.checkPermission(perm, acc);
- } catch (Exception e) {
- if (logger.debugOn()) {
- logger.debug("checkListenerPermission", "refused.", e);
- }
- return false;
- }
- }
- return true;
- }
-
- private String getMBeanServerName() {
- if (mbeanServerName != null) return mbeanServerName;
- else return (mbeanServerName = getMBeanServerName(mbeanServer));
- }
-
- private static String getMBeanServerName(final MBeanServer server) {
- final PrivilegedAction<String> action = new PrivilegedAction<String>() {
- public String run() {
- return Util.getMBeanServerSecurityName(server);
- }
- };
- return AccessController.doPrivileged(action);
- }
-
- // ------------------------------------
- // private variables
- // ------------------------------------
- private final MBeanServer mbeanServer;
- private volatile String mbeanServerName = null;
- private Map<String, ClientInfo> clientInfoMap =
- new ConcurrentHashMap<String, ClientInfo>();
-
- private final CleanListener cleanListener = new CleanListener();
- private final EventSubscriber eventSubscriber;
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "EventClientDelegate");
-
- private static final
- Map<MBeanServer, WeakReference<EventClientDelegate>> delegateMap =
- new WeakHashMap<MBeanServer, WeakReference<EventClientDelegate>>();
-}
--- a/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +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 javax.management.event;
-
-import com.sun.jmx.mbeanserver.Util;
-import java.io.IOException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.NotificationFilter;
-import javax.management.ObjectName;
-import javax.management.remote.NotificationResult;
-
-/**
- * <p>This interface specifies necessary methods on the MBean server
- * side for a JMX remote client to manage its notification listeners as
- * if they are local.
- * Users do not usually work directly with this MBean; instead, the {@link
- * EventClient} class is designed to be used directly by the user.</p>
- *
- * <p>A default implementation of this interface can be added to an MBean
- * Server in one of several ways.</p>
- *
- * <ul>
- * <li><p>The most usual is to insert an {@link
- * javax.management.remote.MBeanServerForwarder MBeanServerForwarder} between
- * the {@linkplain javax.management.remote.JMXConnectorServer Connector Server}
- * and the MBean Server, that will intercept accesses to the Event Client
- * Delegate MBean and treat them as the real MBean would. This forwarder is
- * inserted by default with the standard RMI Connector Server, and can also
- * be created explicitly using {@link EventClientDelegate#newForwarder
- * EventClientDelegate.newForwarder}.
- *
- * <li><p>A variant on the above is to replace the MBean Server that is
- * used locally with a forwarder as described above. Since
- * {@code MBeanServerForwarder} extends {@code MBeanServer}, you can use
- * a forwarder anywhere you would have used the original MBean Server. The
- * code to do this replacement typically looks something like this:</p>
- *
- * <pre>
- * MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // or whatever
- * mbs = EventClientDelegate.newForwarder(mbs, null);
- * // now use mbs just as you did before, but it will have an EventClientDelegate
- * </pre>
- *
- * <li><p>The final way is to create an instance of {@link EventClientDelegate}
- * and register it in the MBean Server under the standard {@linkplain
- * #OBJECT_NAME name}:</p>
- *
- * <pre>
- * MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // or whatever
- * EventClientDelegate ecd = EventClientDelegate.getEventClientDelegate(mbs);
- * mbs.registerMBean(ecd, EventClientDelegateMBean.OBJECT_NAME);
- * <pre>
- * </ul>
- *
- * @since JMX 2.0
- */
-public interface EventClientDelegateMBean {
- /**
- * The string representation of {@link #OBJECT_NAME}.
- */
- // This shouldn't really be necessary but an apparent javadoc bug
- // meant that the {@value} tags didn't work if this was a
- // field in EventClientDelegate, even a public field.
- public static final String OBJECT_NAME_STRING =
- "javax.management.event:type=EventClientDelegate";
-
- /**
- * The standard <code>ObjectName</code> used to register the default
- * <code>EventClientDelegateMBean</code>. The name is
- * <code>{@value #OBJECT_NAME_STRING}</code>.
- */
- public final static ObjectName OBJECT_NAME =
- ObjectName.valueOf(OBJECT_NAME_STRING);
-
- /**
- * A unique listener identifier specified for an EventClient.
- * Any notification associated with this id is intended for
- * the EventClient which receives the notification, rather than
- * a listener added using that EventClient.
- */
- public static final int EVENT_CLIENT_LISTENER_ID = -100;
-
- /**
- * Adds a new client to the <code>EventClientDelegateMBean</code> with
- * a user-specified
- * {@link EventForwarder} to forward notifications to the client. The
- * <code>EventForwarder</code> is created by calling
- * {@link javax.management.MBeanServer#instantiate(String, Object[],
- * String[])}.
- *
- * @param className The class name used to create an
- * {@code EventForwarder}.
- * @param params An array containing the parameters of the constructor to
- * be invoked.
- * @param sig An array containing the signature of the constructor to be
- * invoked
- * @return A client identifier.
- * @exception IOException Reserved for a remote call to throw on the client
- * side.
- * @exception MBeanException An exception thrown when creating the user
- * specified <code>EventForwarder</code>.
- */
- public String addClient(String className, Object[] params, String[] sig)
- throws IOException, MBeanException;
-
- /**
- * Adds a new client to the <code>EventClientDelegateMBean</code> with
- * a user-specified
- * {@link EventForwarder} to forward notifications to the client. The
- * <code>EventForwarder</code> is created by calling
- * {@link javax.management.MBeanServer#instantiate(String, ObjectName,
- * Object[], String[])}. A user-specified class loader is used to create
- * this <code>EventForwarder</code>.
- *
- * @param className The class name used to create an
- * {@code EventForwarder}.
- * @param classLoader An ObjectName registered as a
- * <code>ClassLoader</code> MBean.
- * @param params An array containing the parameters of the constructor to
- * be invoked.
- * @param sig An array containing the signature of the constructor to be
- * invoked
- * @return A client identifier.
- * @exception IOException Reserved for a remote call to throw on the client
- * side.
- * @exception MBeanException An exception thrown when creating the user
- * specified <code>EventForwarder</code>.
- */
- public String addClient(String className,
- ObjectName classLoader,
- Object[] params,
- String[] sig) throws IOException, MBeanException;
-
- /**
- * Removes an added client. Calling this method will remove all listeners
- * added with the client.
- *
- * @exception EventClientNotFoundException If the {@code clientId} is
- * not found.
- * @exception IOException Reserved for a remote call to throw on the client
- * side.
- */
- public void removeClient(String clientID)
- throws EventClientNotFoundException, IOException;
-
- /**
- * Returns the identifiers of listeners added or subscribed to with the
- * specified client identifier.
- * <P> If no listener is currently registered with the client, an empty
- * array is returned.
- * @param clientID The client identifier with which the listeners are
- * added or subscribed to.
- * @return An array of listener identifiers.
- * @exception EventClientNotFoundException If the {@code clientId} is
- * not found.
- * @exception IOException Reserved for a remote call to throw on the client
- * side.
- */
- public Integer[] getListenerIds(String clientID)
- throws EventClientNotFoundException, IOException;
-
- /**
- * Adds a listener to receive notifications from an MBean and returns
- * a non-negative integer as the identifier of the listener.
- * <P>This method is called by an {@link EventClient} to implement the
- * method {@link EventClient#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)}.
- *
- * @param name The name of the MBean onto which the listener should be added.
- * @param filter The filter object. If {@code filter} is null,
- * no filtering will be performed before handling notifications.
- * @param clientId The client identifier with which the listener is added.
- * @return A listener identifier.
- * @throws EventClientNotFoundException Thrown if the {@code clientId} is
- * not found.
- * @throws InstanceNotFoundException Thrown if the MBean is not found.
- * @throws IOException Reserved for a remote call to throw on the client
- * side.
- */
- public Integer addListener(String clientId,
- ObjectName name,
- NotificationFilter filter)
- throws InstanceNotFoundException, EventClientNotFoundException,
- IOException;
-
-
- /**
- * <p>Subscribes a listener to receive notifications from an MBean or a
- * set of MBeans represented by an {@code ObjectName} pattern. (It is
- * not an error if no MBeans match the pattern at the time this method is
- * called.)</p>
- *
- * <p>Returns a non-negative integer as the identifier of the listener.</p>
- *
- * <p>This method is called by an {@link EventClient} to execute its
- * method {@link EventClient#subscribe(ObjectName, NotificationListener,
- * NotificationFilter, Object)}.</p>
- *
- * @param clientId The remote client's identifier.
- * @param name The name of an MBean or an {@code ObjectName} pattern
- * representing a set of MBeans to which the listener should listen.
- * @param filter The filter object. If {@code filter} is null, no
- * filtering will be performed before notifications are handled.
- *
- * @return A listener identifier.
- *
- * @throws IllegalArgumentException If the {@code name} or
- * {@code listener} is null.
- * @throws EventClientNotFoundException If the client ID is not found.
- * @throws IOException Reserved for a remote client to throw if
- * an I/O error occurs.
- *
- * @see EventConsumer#subscribe(ObjectName, NotificationListener,
- * NotificationFilter,Object)
- * @see #removeListenerOrSubscriber(String, Integer)
- */
- public Integer addSubscriber(String clientId, ObjectName name,
- NotificationFilter filter)
- throws EventClientNotFoundException, IOException;
-
- /**
- * Removes a listener, to stop receiving notifications.
- * <P> This method is called by an {@link EventClient} to execute its
- * methods {@link EventClient#removeNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)},
- * {@link EventClient#removeNotificationListener(ObjectName,
- * NotificationListener)}, and {@link EventClient#unsubscribe}.
- *
- * @param clientId The client identifier with which the listener was added.
- * @param listenerId The listener identifier to be removed. This must be
- * an identifier returned by a previous {@link #addListener addListener}
- * or {@link #addSubscriber addSubscriber} call.
- *
- * @throws InstanceNotFoundException if the MBean on which the listener
- * was added no longer exists.
- * @throws ListenerNotFoundException if there is no listener with the
- * given {@code listenerId}.
- * @throws EventClientNotFoundException if the {@code clientId} is
- * not found.
- * @throws IOException Reserved for a remote call to throw on the client
- * side.
- */
- public void removeListenerOrSubscriber(String clientId, Integer listenerId)
- throws InstanceNotFoundException, ListenerNotFoundException,
- EventClientNotFoundException, IOException;
-
- /**
- * Called by a client to fetch notifications that are to be sent to its
- * listeners.
- *
- * @param clientId The client's identifier.
- * @param startSequenceNumber The first sequence number to
- * consider.
- * @param timeout The maximum waiting time.
- * @param maxNotifs The maximum number of notifications to return.
- *
- * @throws EventClientNotFoundException Thrown if the {@code clientId} is
- * not found.
- * @throws IllegalArgumentException if the client was {@linkplain
- * #addClient(String, Object[], String[]) added} with an {@link
- * EventForwarder} that is not a {@link FetchingEventForwarder}.
- * @throws IOException Reserved for a remote call to throw on the client
- * side.
- */
- public NotificationResult fetchNotifications(String clientId,
- long startSequenceNumber,
- int maxNotifs,
- long timeout)
- throws EventClientNotFoundException, IOException;
-
- /**
- * An {@code EventClient} calls this method to keep its {@code clientId}
- * alive in this MBean. The client will be removed if the lease times out.
- *
- * @param clientId The client's identifier.
- * @param timeout The time in milliseconds by which the lease is to be
- * extended. The value zero has no special meaning, so it will cause the
- * lease to time out immediately.
- *
- * @return The new lifetime of the lease in milliseconds. This may be
- * different from the requested time.
- *
- * @throws EventClientNotFoundException if the {@code clientId} is
- * not found.
- * @throws IOException reserved for a remote call to throw on the client
- * side.
- * @throws IllegalArgumentException if {@code clientId} is null or
- * {@code timeout} is negative.
- */
- public long lease(String clientId, long timeout)
- throws IOException, EventClientNotFoundException;
-}
--- a/jdk/src/share/classes/javax/management/event/EventClientNotFoundException.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +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 javax.management.event;
-
-import javax.management.JMException;
-
-/**
- * Thrown if an event client identifier is unknown.
- */
-public class EventClientNotFoundException extends JMException {
-
- /* Serial version */
- private static final long serialVersionUID = -3910667345840643089L;
-
- /**
- *Constructs a {@code ClientNotFoundException} without a detail message.
- */
- public EventClientNotFoundException() {
- super();
- }
-
- /**
- * Constructs a {@code ClientNotFoundException} with the specified detail message.
- * @param message The message.
- */
- public EventClientNotFoundException(String message) {
- super(message);
- }
-
- /**
- * Constructs a {@code ClientNotFoundException} with the specified detail message
- * and cause.
- *
- * @param message The message.
- * @param cause The cause (which is saved for later retrieval by the
- * {@code Throwable.getCause()} method). A null value is permitted, and indicates
- * that the cause is non-existent or unknown.
- */
- public EventClientNotFoundException(String message, Throwable cause) {
- super(message);
-
- initCause(cause);
- }
-
- /**
- * Constructs a new exception with the specified cause.
- * @param cause The cause (which is saved for later retrieval by the
- * {@code Throwable.getCause()} method). A null value is permitted, and indicates
- * that the cause is non-existent or unknown.
- */
- public EventClientNotFoundException(Throwable cause) {
- super();
-
- initCause(cause);
- }
-}
--- a/jdk/src/share/classes/javax/management/event/EventConsumer.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +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 javax.management.event;
-
-import java.io.IOException;
-import javax.management.ListenerNotFoundException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-
-/**
- * This interface specifies methods to subscribe a listener to receive events
- * from an MBean or a set of MBeans. The MBeans can already be registered in
- * an MBean server, or they can be pending registration, or they can be MBeans
- * that will never be registered, or they can be MBeans that will be registered
- * then unregistered.
- * @since JMX 2.0
- */
-public interface EventConsumer {
- /**
- * <p>Subscribes a listener to receive events from an MBean or a set
- * of MBeans represented by an {@code ObjectName} pattern.</p>
- *
- * <P> An event emitted by an MBean is forwarded to every listener that was
- * subscribed with the name of that MBean, or with a pattern that matches
- * that name.</p>
- *
- * @param name The name of an MBean or an {@code ObjectName} pattern
- * representing a set of MBeans to which the listener should listen.
- * @param listener The listener object that will handle the
- * notifications emitted by the MBeans.
- * @param filter The filter object. If {@code filter} is null, no
- * filtering will be performed before notification handling.
- * @param handback The context to be sent to the listener when a
- * notification is emitted.
- *
- * @throws IllegalArgumentException If the {@code name} or
- * {@code listener} is null.
- * @throws IOException for a remote client, thrown if
- * an I/O error occurs.
- * @see #unsubscribe(ObjectName, NotificationListener)
- */
- public void subscribe(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws IOException;
-
- /**
- * <p>Unsubscribes a listener which is listening to an MBean or a set of
- * MBeans represented by an {@code ObjectName} pattern.</p>
- *
- * <p>The listener to be removed must have been added by the {@link
- * #subscribe subscribe} method with the given {@code name}. If the {@code
- * name} is a pattern, then the {@code subscribe} must have used the same
- * pattern. If the same listener has been subscribed more than once to the
- * {@code name}, perhaps with different filters or handbacks, then all such
- * listeners are removed.</p>
- *
- * @param name The name of the MBean or an {@code ObjectName} pattern
- * representing a set of MBeans to which the listener was subscribed.
- * @param listener A listener that was previously subscribed to the
- * MBean(s).
- *
- * @throws ListenerNotFoundException The given {@code listener} was not
- * subscribed to the given {@code name}.
- * @throws IOException for a remote client, thrown if
- * an I/O error occurs.
- *
- * @see #subscribe
- */
- public void unsubscribe(ObjectName name,
- NotificationListener listener)
- throws ListenerNotFoundException, IOException;
-}
--- a/jdk/src/share/classes/javax/management/event/EventForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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 javax.management.event;
-
-import java.io.IOException;
-import javax.management.Notification;
-
-/**
- * This interface can be used to specify a custom forwarding mechanism for
- * {@code EventClientDelegateMBean} to forward events to the client.
- *
- * @see <a href="package-summary.html#transports">Custom notification
- * transports</a>
- */
-public interface EventForwarder {
- /**
- * Forwards a notification.
- * @param n The notification to be forwarded to a remote listener.
- * @param listenerId The identifier of the listener to receive the notification.
- * @throws IOException If it is closed or an I/O error occurs.
- */
- public void forward(Notification n, Integer listenerId)
- throws IOException;
-
- /**
- * Informs the {@code EventForwarder} to shut down.
- * <p> After this method is called, any call to the method
- * {@link #forward forward(Notification, Integer)} may get an {@code IOException}.
- * @throws IOException If an I/O error occurs.
- */
- public void close() throws IOException;
-
- /**
- * Sets an event client identifier created by {@link EventClientDelegateMBean}.
- * <P> This method will be called just after this {@code EventForwarder}
- * is constructed and before calling the {@code forward} method to forward any
- * notifications.
- */
- public void setClientId(String clientId) throws IOException;
-}
--- a/jdk/src/share/classes/javax/management/event/EventReceiver.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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 javax.management.event;
-
-import javax.management.remote.NotificationResult;
-
-/**
- * An object implementing this interface is passed by an {@link EventClient}
- * to its {@link EventRelay}, to allow the {@code EventRelay} to communicate
- * received notifications to the {@code EventClient}.
- *
- * @see <a href="package-summary.html#transports">Custom notification
- * transports</a>
- */
-public interface EventReceiver {
-
- /**
- * This method is implemented by {@code EventClient} as a callback to
- * receive notifications from {@code EventRelay}.
- * <P>The notifications are included in an object specified by the class
- * {@link NotificationResult}. In
- * addition to a set of notifications, the class object also contains two values:
- * {@code earliestSequenceNumber} and {@code nextSequenceNumber}.
- * These two values determine whether any notifications have been lost.
- * The {@code nextSequenceNumber} value of the last time is compared
- * to the received value {@code earliestSequenceNumber}. If the
- * received {@code earliesSequenceNumber} is greater, than the difference
- * signifies the number of lost notifications. A sender should
- * ensure the sequence of notifications sent, meaning that the value
- * {@code earliestSequenceNumber} of the next return should be always equal to
- * or greater than the value {@code nextSequenceNumber} of the last return.
- *
- * @param nr the received notifications and sequence numbers.
- */
- public void receive(NotificationResult nr);
-
- /**
- * Allows the {@link EventRelay} to report when it receives an unexpected
- * exception, which may be fatal and which may make it stop receiving
- * notifications.
- *
- * @param t The unexpected exception received while {@link EventRelay} was running.
- */
- public void failed(Throwable t);
-
- /**
- * Allows the {@link EventRelay} to report when it receives an unexpected
- * exception that is not fatal. For example, a notification received is not
- * serializable or its class is not found.
- *
- * @param e The unexpected exception received while notifications are being received.
- */
- public void nonFatal(Exception e);
-}
--- a/jdk/src/share/classes/javax/management/event/EventRelay.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +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 javax.management.event;
-
-import java.io.IOException;
-import java.util.concurrent.Executors; // for javadoc
-
-/**
- * This interface is used to specify a way to receive
- * notifications from a remote MBean server and then to forward the notifications
- * to an {@link EventClient}.
- *
- * @see <a href="package-summary.html#transports">Custom notification
- * transports</a>
- */
-public interface EventRelay {
- /**
- * Returns an identifier that is used by this {@code EventRelay} to identify
- * the client when communicating with the {@link EventClientDelegateMBean}.
- * <P> This identifier is obtained by calling
- * {@link EventClientDelegateMBean#addClient(String, Object[], String[])
- * EventClientDelegateMBean.addClient}.
- * <P> It is the {@code EventRelay} that calls {@code EventClientDelegateMBean} to obtain
- * the client identifier because it is the {@code EventRelay} that decides
- * how to get notifications from the {@code EventClientDelegateMBean},
- * by creating the appropriate {@link EventForwarder}.
- *
- * @return A client identifier.
- * @throws IOException If an I/O error occurs when communicating with
- * the {@code EventClientDelegateMBean}.
- */
- public String getClientId() throws IOException;
-
- /**
- * This method is called by {@link EventClient} to register a callback
- * to receive notifications from an {@link EventClientDelegateMBean} object.
- * A {@code null} value is allowed, which means that the {@code EventClient} suspends
- * reception of notifications, so that the {@code EventRelay} can decide to stop receiving
- * notifications from its {@code EventForwarder}.
- *
- * @param eventReceiver An {@link EventClient} callback to receive
- * events.
- */
- public void setEventReceiver(EventReceiver eventReceiver);
-
- /**
- * Stops receiving and forwarding notifications and performs any necessary
- * cleanup. After calling this method, the {@link EventClient} will never
- * call any other methods of this object.
- *
- * @throws IOException If an I/O exception appears.
- *
- * @see EventClient#close
- */
- public void stop() throws IOException;
-}
--- a/jdk/src/share/classes/javax/management/event/EventSubscriber.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +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 javax.management.event;
-
-import com.sun.jmx.remote.util.ClassLogger;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerNotification;
-import javax.management.Notification;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.Query;
-import javax.management.QueryEval;
-import javax.management.QueryExp;
-
-/**
- * <p>An object that can be used to subscribe for notifications from all MBeans
- * in an MBeanServer that match a pattern. For example, to listen for
- * notifications from all MBeans in the MBeanServer {@code mbs} that match
- * {@code com.example:type=Controller,name=*} you could write:</p>
- *
- * <pre>
- * EventSubscriber subscriber = EventSubscriber.getEventSubscriber(mbs);
- * ObjectName pattern = new ObjectName("com.example:type=Controller,name=*");
- * NotificationListener myListener = ...;
- * NotificationFilter myFilter = null; // or whatever
- * Object handback = null; // or whatever
- * subscriber.subscribe(pattern, myListener, myFilter, myHandback);
- * </pre>
- */
-public class EventSubscriber implements EventConsumer {
- /**
- * Returns an {@code EventSubscriber} object to subscribe for notifications
- * from the given {@code MBeanServer}. Calling this method more
- * than once with the same parameter may or may not return the same object.
- *
- * @param mbs the {@code MBeanServer} containing MBeans to be subscribed to.
- * @return An {@code EventSubscriber} object.
- *
- * @throws NullPointerException if mbs is null.
- */
- public static EventSubscriber getEventSubscriber(MBeanServer mbs) {
- if (mbs == null)
- throw new NullPointerException("Null MBeanServer");
-
- EventSubscriber eventSubscriber = null;
- synchronized (subscriberMap) {
- final WeakReference<EventSubscriber> wrf = subscriberMap.get(mbs);
- eventSubscriber = (wrf == null) ? null : wrf.get();
-
- if (eventSubscriber == null) {
- eventSubscriber = new EventSubscriber(mbs);
-
- subscriberMap.put(mbs,
- new WeakReference<EventSubscriber>(eventSubscriber));
- }
- }
-
- return eventSubscriber;
- }
-
- private EventSubscriber(final MBeanServer mbs) {
- logger.trace("EventSubscriber", "create a new one");
- this.mbeanServer = mbs;
-
- Exception x = null;
- try {
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<Void>() {
- public Void run() throws Exception {
- mbs.addNotificationListener(
- MBeanServerDelegate.DELEGATE_NAME,
- myMBeanServerListener, null, null);
- return null;
- }
- });
- } catch (PrivilegedActionException ex) {
- x = ex.getException();
- }
-
- // handle possible exceptions.
- //
- // Fail unless x is null or x is instance of InstanceNotFoundException
- // The logic here is that if the MBeanServerDelegate is not present,
- // we will assume that the connection will not emit any
- // MBeanServerNotifications.
- //
- if (x != null && !(x instanceof InstanceNotFoundException)) {
- if (x instanceof RuntimeException)
- throw (RuntimeException) x;
- throw new RuntimeException(
- "Can't add listener to MBean server delegate: " + x, x);
- }
- }
-
- public void subscribe(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws IOException {
-
- if (logger.traceOn())
- logger.trace("subscribe", "" + name);
-
- if (name == null)
- throw new IllegalArgumentException("Null MBean name");
-
- if (listener == null)
- throw new IllegalArgumentException("Null listener");
-
- final MyListenerInfo li = new MyListenerInfo(listener, filter, handback);
- List<MyListenerInfo> list;
-
- Map<ObjectName, List<MyListenerInfo>> map;
- Set<ObjectName> names;
- if (name.isPattern()) {
- map = patternSubscriptionMap;
- names = mbeanServer.queryNames(name, notificationBroadcasterExp);
- } else {
- map = exactSubscriptionMap;
- names = Collections.singleton(name);
- }
-
- synchronized (map) {
- list = map.get(name);
- if (list == null) {
- list = new ArrayList<MyListenerInfo>();
- map.put(name, list);
- }
- list.add(li);
- }
-
- for (ObjectName mbeanName : names) {
- try {
- mbeanServer.addNotificationListener(mbeanName,
- listener,
- filter,
- handback);
- } catch (Exception e) {
- logger.fine("subscribe", "addNotificationListener", e);
- }
- }
- }
-
- public void unsubscribe(ObjectName name,
- NotificationListener listener)
- throws ListenerNotFoundException, IOException {
- if (logger.traceOn())
- logger.trace("unsubscribe", "" + name);
-
- if (name == null)
- throw new IllegalArgumentException("Null MBean name");
-
- if (listener == null)
- throw new ListenerNotFoundException();
-
- Map<ObjectName, List<MyListenerInfo>> map;
- Set<ObjectName> names;
-
- if (name.isPattern()) {
- map = patternSubscriptionMap;
- names = mbeanServer.queryNames(name, notificationBroadcasterExp);
- } else {
- map = exactSubscriptionMap;
- names = Collections.singleton(name);
- }
-
- List<MyListenerInfo> toRemove = new ArrayList<MyListenerInfo>();
- synchronized (map) {
- List<MyListenerInfo> list = map.get(name);
- if (list == null) {
- throw new ListenerNotFoundException();
- }
-
- for (MyListenerInfo info : list) {
- if (info.listener == listener) {
- toRemove.add(info);
- }
- }
-
- if (toRemove.isEmpty()) {
- throw new ListenerNotFoundException();
- }
-
- for (MyListenerInfo info : toRemove) {
- list.remove(info);
- }
-
- if (list.isEmpty())
- map.remove(name);
- }
-
- for (ObjectName mbeanName : names) {
- for (MyListenerInfo i : toRemove) {
- try {
- mbeanServer.removeNotificationListener(mbeanName,
- i.listener, i.filter, i.handback);
- } catch (Exception e) {
- logger.fine("unsubscribe", "removeNotificationListener", e);
- }
- }
- }
- }
-
- // ---------------------------------
- // private stuff
- // ---------------------------------
- // used to receive MBeanServerNotification
- private NotificationListener myMBeanServerListener =
- new NotificationListener() {
- public void handleNotification(Notification n, Object hb) {
- if (!(n instanceof MBeanServerNotification) ||
- !MBeanServerNotification.
- REGISTRATION_NOTIFICATION.equals(n.getType())) {
- return;
- }
-
- final ObjectName name =
- ((MBeanServerNotification)n).getMBeanName();
- try {
- if (!mbeanServer.isInstanceOf(name,
- NotificationBroadcaster.class.getName())) {
- return;
- }
- } catch (Exception e) {
- // The only documented exception is InstanceNotFoundException,
- // which could conceivably happen if the MBean is unregistered
- // immediately after being registered.
- logger.fine("myMBeanServerListener.handleNotification",
- "isInstanceOf", e);
- return;
- }
-
- final List<MyListenerInfo> listeners = new ArrayList<MyListenerInfo>();
-
- // If there are subscribers for the exact name that has just arrived
- // then add their listeners to the list.
- synchronized (exactSubscriptionMap) {
- List<MyListenerInfo> exactListeners = exactSubscriptionMap.get(name);
- if (exactListeners != null)
- listeners.addAll(exactListeners);
- }
-
- // For every subscription pattern that matches the new name,
- // add all the listeners for that pattern to "listeners".
- synchronized (patternSubscriptionMap) {
- for (ObjectName on : patternSubscriptionMap.keySet()) {
- if (on.apply(name)) {
- listeners.addAll(patternSubscriptionMap.get(on));
- }
- }
- }
-
- // Add all the listeners just found to the new MBean.
- for (MyListenerInfo li : listeners) {
- try {
- mbeanServer.addNotificationListener(
- name,
- li.listener,
- li.filter,
- li.handback);
- } catch (Exception e) {
- logger.fine("myMBeanServerListener.handleNotification",
- "addNotificationListener", e);
- }
- }
- }
- };
-
- private static class MyListenerInfo {
- public final NotificationListener listener;
- public final NotificationFilter filter;
- public final Object handback;
-
- public MyListenerInfo(NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
-
- if (listener == null)
- throw new IllegalArgumentException("Null listener");
-
- this.listener = listener;
- this.filter = filter;
- this.handback = handback;
- }
- }
-
- // ---------------------------------
- // private methods
- // ---------------------------------
- // ---------------------------------
- // private variables
- // ---------------------------------
- private final MBeanServer mbeanServer;
-
- private final Map<ObjectName, List<MyListenerInfo>> exactSubscriptionMap =
- new HashMap<ObjectName, List<MyListenerInfo>>();
- private final Map<ObjectName, List<MyListenerInfo>> patternSubscriptionMap =
- new HashMap<ObjectName, List<MyListenerInfo>>();
-
-
-
- // trace issues
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "EventSubscriber");
-
- // Compatibility code, so we can run on Tiger:
- private static final QueryExp notificationBroadcasterExp;
- static {
- QueryExp broadcasterExp;
- try {
- final Method m = Query.class.getMethod("isInstanceOf", String.class);
- broadcasterExp = (QueryExp)m.invoke(Query.class,
- new Object[] {NotificationBroadcaster.class.getName()});
- } catch (Exception e) {
- broadcasterExp = new BroadcasterQueryExp();
- }
- notificationBroadcasterExp = broadcasterExp;
- }
- private static class BroadcasterQueryExp extends QueryEval implements QueryExp {
- private static final long serialVersionUID = 1234L;
- public boolean apply(ObjectName name) {
- try {
- return getMBeanServer().isInstanceOf(
- name, NotificationBroadcaster.class.getName());
- } catch (Exception e) {
- return false;
- }
- }
- }
-
- private static final
- Map<MBeanServerConnection, WeakReference<EventSubscriber>> subscriberMap =
- new WeakHashMap<MBeanServerConnection, WeakReference<EventSubscriber>>();
-}
--- a/jdk/src/share/classes/javax/management/event/FetchingEventForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +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 javax.management.event;
-
-import com.sun.jmx.event.EventBuffer;
-import com.sun.jmx.remote.util.ClassLogger;
-import java.io.IOException;
-import java.util.List;
-import javax.management.Notification;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
-
-/**
- * This class is used by {@link FetchingEventRelay}. When
- * {@link FetchingEventRelay} calls {@link
- * EventClientDelegateMBean#addClient(String, Object[], String[])} to get a new
- * client identifier, it uses
- * this class name as the first argument to ask {@code EventClientDelegateMBean}
- * to create an object of this class.
- * Then {@code EventClientDelegateMBean} forwards client notifications
- * to this object.
- * When {@link FetchingEventRelay} calls
- * {@link EventClientDelegateMBean#fetchNotifications(String, long, int, long)}
- * to fetch notifications, the {@code EventClientDelegateMBean} will forward
- * the call to this object.
- */
-public class FetchingEventForwarder implements EventForwarder {
-
- /**
- * Construct a new {@code FetchingEventForwarder} with the given
- * buffer size.
- * @param bufferSize the size of the buffer that will store notifications
- * until they have been fetched and acknowledged by the client.
- */
- public FetchingEventForwarder(int bufferSize) {
- if (logger.traceOn()) {
- logger.trace("Constructor", "buffer size is "+bufferSize);
- }
-
- buffer = new EventBuffer(bufferSize);
- this.bufferSize = bufferSize;
- }
-
- /**
- * Called by an {@link EventClientDelegateMBean} to forward a user call
- * {@link EventClientDelegateMBean#fetchNotifications(String, long, int, long)}.
- * A call of this method is considered to acknowledge reception of all
- * notifications whose sequence numbers are less the
- * {@code startSequenceNumber}, so all these notifications can be deleted
- * from this object.
- *
- * @param startSequenceNumber The first sequence number to
- * consider.
- * @param timeout The maximum waiting time in milliseconds.
- * If no notifications have arrived after this period of time, the call
- * will return with an empty list of notifications.
- * @param maxNotifs The maximum number of notifications to return.
- */
- public NotificationResult fetchNotifications(long startSequenceNumber,
- int maxNotifs, long timeout) {
- if (logger.traceOn()) {
- logger.trace("fetchNotifications",
- startSequenceNumber+" "+
- maxNotifs+" "+
- timeout);
- }
-
- return buffer.fetchNotifications(startSequenceNumber,
- timeout,
- maxNotifs);
- }
-
- /**
- * {@inheritDoc}
- * In this implementation, the notification is stored in the local buffer
- * waiting for {@link #fetchNotifications fetchNotifications} to pick
- * it up.
- */
- public void forward(Notification n, Integer listenerId) throws IOException {
- if (logger.traceOn()) {
- logger.trace("forward", n+" "+listenerId);
- }
-
- buffer.add(new TargetedNotification(n, listenerId));
- }
-
- public void close() throws IOException {
- if (logger.traceOn()) {
- logger.trace("close", "");
- }
-
- buffer.close();
- }
-
- public void setClientId(String clientId) throws IOException {
- if (logger.traceOn()) {
- logger.trace("setClientId", clientId);
- }
- this.clientId = clientId;
- }
-
- /**
- * Sets a user specific list to save notifications in server side
- * before forwarding to an FetchingEventRelay in client side.
- * <P> This method should be called before any notification is
- * forwarded to this forwader.
- *
- * @param list a user specific list to save notifications
- */
- protected void setList(List<TargetedNotification> list) {
- if (logger.traceOn()) {
- logger.trace("setList", "");
- }
-
- if (clientId == null) {
- buffer = new EventBuffer(bufferSize, list);
- } else {
- throw new IllegalStateException();
- }
- }
-
- private EventBuffer buffer;
- private int bufferSize;
- private String clientId;
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "FetchingEventForwarder");
-}
--- a/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,391 +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 javax.management.event;
-
-import com.sun.jmx.event.DaemonThreadFactory;
-import com.sun.jmx.event.RepeatedSingletonJob;
-import com.sun.jmx.remote.util.ClassLogger;
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import javax.management.MBeanException;
-import javax.management.remote.NotificationResult;
-
-/**
- * <p>This class is an implementation of the {@link EventRelay} interface. It calls
- * {@link EventClientDelegateMBean#fetchNotifications
- * fetchNotifications(String, long, int, long)} to get
- * notifications and then forwards them to an {@link EventReceiver} object.</p>
- *
- * <p>A {@code fetchExecutor} parameter can be specified when creating a
- * {@code FetchingEventRelay}. That is then the {@code Executor} that will
- * be used to perform the {@code fetchNotifications} operation. Only one
- * job at a time will be submitted to this {@code Executor}. The behavior
- * is unspecified if {@link Executor#execute} throws an exception, including
- * {@link java.util.concurrent.RejectedExecutionException
- * RejectedExecutionException}.
- *
- * @since JMX 2.0
- */
-public class FetchingEventRelay implements EventRelay {
- /**
- * The default buffer size: {@value #DEFAULT_BUFFER_SIZE}.
- */
- public final static int DEFAULT_BUFFER_SIZE = 1000;
-
- /**
- * The default waiting timeout: {@value #DEFAULT_WAITING_TIMEOUT}
- * in millseconds when fetching notifications from
- * an {@code EventClientDelegateMBean}.
- */
- public final static long DEFAULT_WAITING_TIMEOUT = 60000;
-
- /**
- * The default maximum notifications to fetch every time:
- * {@value #DEFAULT_MAX_NOTIFICATIONS}.
- */
- public final static int DEFAULT_MAX_NOTIFICATIONS = DEFAULT_BUFFER_SIZE;
-
- /**
- * Constructs a default {@code FetchingEventRelay} object by using the default
- * configuration: {@code DEFAULT_BUFFER_SIZE}, {@code DEFAULT_WAITING_TIMEOUT}
- * {@code DEFAULT_MAX_NOTIFICATIONS}. A single thread is created
- * to do fetching.
- *
- * @param delegate The {@code EventClientDelegateMBean} to work with.
- * @throws IOException If failed to work with the {@code delegate}.
- * @throws MBeanException if unable to add a client to the remote
- * {@code EventClientDelegateMBean} (see {@link
- * EventClientDelegateMBean#addClient(String, Object[], String[])
- * EventClientDelegateMBean.addClient}).
- * @throws IllegalArgumentException If {@code delegate} is {@code null}.
- */
- public FetchingEventRelay(EventClientDelegateMBean delegate)
- throws IOException, MBeanException {
- this(delegate, null);
- }
-
- /**
- * Constructs a {@code FetchingEventRelay} object by using the default
- * configuration: {@code DEFAULT_BUFFER_SIZE}, {@code DEFAULT_WAITING_TIMEOUT}
- * {@code DEFAULT_MAX_NOTIFICATIONS}, with a user-specific executor to do
- * the fetching.
- *
- * @param delegate The {@code EventClientDelegateMBean} to work with.
- * @param fetchExecutor Used to do the fetching. A new thread is created if
- * {@code null}.
- * @throws IOException If failed to work with the {@code delegate}.
- * @throws MBeanException if unable to add a client to the remote
- * {@code EventClientDelegateMBean} (see {@link
- * EventClientDelegateMBean#addClient(String, Object[], String[])
- * EventClientDelegateMBean.addClient}).
- * @throws IllegalArgumentException If {@code delegate} is {@code null}.
- */
- public FetchingEventRelay(EventClientDelegateMBean delegate,
- Executor fetchExecutor) throws IOException, MBeanException {
- this(delegate,
- DEFAULT_BUFFER_SIZE,
- DEFAULT_WAITING_TIMEOUT,
- DEFAULT_MAX_NOTIFICATIONS,
- fetchExecutor);
- }
-
- /**
- * Constructs a {@code FetchingEventRelay} object with user-specific
- * configuration and executor to fetch notifications via the
- * {@link EventClientDelegateMBean}.
- *
- * @param delegate The {@code EventClientDelegateMBean} to work with.
- * @param bufferSize The buffer size for saving notifications in
- * {@link EventClientDelegateMBean} before they are fetched.
- * @param timeout The waiting time in millseconds when fetching
- * notifications from an {@code EventClientDelegateMBean}.
- * @param maxNotifs The maximum notifications to fetch every time.
- * @param fetchExecutor Used to do the fetching. A new thread is created if
- * {@code null}.
- * @throws IOException if failed to communicate with the {@code delegate}.
- * @throws MBeanException if unable to add a client to the remote
- * {@code EventClientDelegateMBean} (see {@link
- * EventClientDelegateMBean#addClient(String, Object[], String[])
- * EventClientDelegateMBean.addClient}).
- * @throws IllegalArgumentException If {@code delegate} is {@code null}.
- */
- public FetchingEventRelay(EventClientDelegateMBean delegate,
- int bufferSize,
- long timeout,
- int maxNotifs,
- Executor fetchExecutor) throws IOException, MBeanException {
- this(delegate,
- bufferSize,
- timeout,
- maxNotifs,
- fetchExecutor,
- FetchingEventForwarder.class.getName(),
- new Object[] {bufferSize},
- new String[] {int.class.getName()});
- }
-
- /**
- * Constructs a {@code FetchingEventRelay} object with user-specific
- * configuration and executor to fetch notifications via the
- * {@link EventClientDelegateMBean}.
- *
- * @param delegate The {@code EventClientDelegateMBean} to work with.
- * @param bufferSize The buffer size for saving notifications in
- * {@link EventClientDelegateMBean} before they are fetched.
- * @param timeout The waiting time in millseconds when fetching
- * notifications from an {@code EventClientDelegateMBean}.
- * @param maxNotifs The maximum notifications to fetch every time.
- * @param fetchExecutor Used to do the fetching.
- * @param forwarderName the class name of a user specific EventForwarder
- * to create in server to forward notifications to this object. The class
- * should be a subclass of the class {@link FetchingEventForwarder}.
- * @param params the parameters passed to create {@code forwarderName}
- * @param sig the signature of the {@code params}
- * @throws IOException if failed to communicate with the {@code delegate}.
- * @throws MBeanException if unable to add a client to the remote
- * {@code EventClientDelegateMBean} (see {@link
- * EventClientDelegateMBean#addClient(String, Object[], String[])
- * EventClientDelegateMBean.addClient}).
- * @throws IllegalArgumentException if {@code bufferSize} or
- * {@code maxNotifs} is less than {@code 1}
- * @throws NullPointerException if {@code delegate} is {@code null}.
- */
- public FetchingEventRelay(EventClientDelegateMBean delegate,
- int bufferSize,
- long timeout,
- int maxNotifs,
- Executor fetchExecutor,
- String forwarderName,
- Object[] params,
- String[] sig) throws IOException, MBeanException {
-
- if (logger.traceOn()) {
- logger.trace("FetchingEventRelay", "delegateMBean "+
- bufferSize+" "+
- timeout+" "+
- maxNotifs+" "+
- fetchExecutor+" "+
- forwarderName+" ");
- }
-
- if (delegate == null) {
- throw new NullPointerException("Null EventClientDelegateMBean!");
- }
-
-
- if (bufferSize<=1) {
- throw new IllegalArgumentException(
- "The bufferSize cannot be less than 1, no meaning.");
- }
-
- if (maxNotifs<=1) {
- throw new IllegalArgumentException(
- "The maxNotifs cannot be less than 1, no meaning.");
- }
-
- clientId = delegate.addClient(
- forwarderName,
- params,
- sig);
-
- this.delegate = delegate;
- this.timeout = timeout;
- this.maxNotifs = maxNotifs;
-
- if (fetchExecutor == null) {
- ScheduledThreadPoolExecutor executor =
- new ScheduledThreadPoolExecutor(1, daemonThreadFactory);
- executor.setKeepAliveTime(1, TimeUnit.SECONDS);
- executor.allowCoreThreadTimeOut(true);
- fetchExecutor = executor;
- this.defaultExecutor = executor;
- } else
- this.defaultExecutor = null;
- this.fetchExecutor = fetchExecutor;
-
- startSequenceNumber = 0;
- fetchingJob = new MyJob();
- }
-
- public synchronized void setEventReceiver(EventReceiver eventReceiver) {
- if (logger.traceOn()) {
- logger.trace("setEventReceiver", ""+eventReceiver);
- }
-
- EventReceiver old = this.eventReceiver;
- this.eventReceiver = eventReceiver;
- if (old == null && eventReceiver != null)
- fetchingJob.resume();
- }
-
- public String getClientId() {
- return clientId;
- }
-
- public synchronized void stop() {
- if (logger.traceOn()) {
- logger.trace("stop", "");
- }
- if (stopped) {
- return;
- }
-
- stopped = true;
- clientId = null;
- if (defaultExecutor != null)
- defaultExecutor.shutdown();
- }
-
- private class MyJob extends RepeatedSingletonJob {
- public MyJob() {
- super(fetchExecutor);
- }
-
- public boolean isSuspended() {
- boolean b;
- synchronized(FetchingEventRelay.this) {
- b = stopped ||
- (eventReceiver == null) ||
- (clientId == null);
- }
-
- if (logger.traceOn()) {
- logger.trace("-MyJob-isSuspended", ""+b);
- }
- return b;
- }
-
- public void task() {
- logger.trace("MyJob-task", "");
- long fetchTimeout = timeout;
- NotificationResult nr = null;
- Throwable failedExcep = null;
- try {
- nr = delegate.fetchNotifications(
- clientId,
- startSequenceNumber,
- maxNotifs,
- fetchTimeout);
- } catch (Exception e) {
- if (isSerialOrClassNotFound(e)) {
- try {
- nr = fetchOne();
- } catch (Exception ee) {
- failedExcep = e;
- }
- } else {
- failedExcep = e;
- }
- }
-
- if (failedExcep != null &&
- !isSuspended()) {
- logger.fine("MyJob-task",
- "Failed to fetch notification, stopping...", failedExcep);
- try {
- eventReceiver.failed(failedExcep);
- } catch (Exception e) {
- logger.trace(
- "MyJob-task", "exception from eventReceiver.failed", e);
- }
-
- stop();
- } else if (nr != null) {
- try {
- eventReceiver.receive(nr);
- } catch (RuntimeException e) {
- logger.trace(
- "MyJob-task",
- "exception delivering notifs to EventClient", e);
- } finally {
- startSequenceNumber = nr.getNextSequenceNumber();
- }
- }
- }
- }
-
- private NotificationResult fetchOne() throws Exception {
- logger.trace("fetchOne", "");
-
- while (true) {
- try {
- // 1 notif to skip possible missing class
- return delegate.fetchNotifications(
- clientId,
- startSequenceNumber,
- 1,
- timeout);
- } catch (Exception e) {
- if (isSerialOrClassNotFound(e)) { // skip and continue
- if (logger.traceOn()) {
- logger.trace("fetchOne", "Ignore", e);
- }
- eventReceiver.nonFatal(e);
- startSequenceNumber++;
- } else {
- throw e;
- }
- }
- }
- }
-
- static boolean isSerialOrClassNotFound(Exception e) {
- Throwable cause = e.getCause();
-
- while (cause != null &&
- !(cause instanceof ClassNotFoundException) &&
- !(cause instanceof NotSerializableException)) {
- cause = cause.getCause();
- }
-
- return (cause instanceof ClassNotFoundException ||
- cause instanceof NotSerializableException);
- }
-
- private long startSequenceNumber = 0;
- private EventReceiver eventReceiver = null;
- private final EventClientDelegateMBean delegate;
- private String clientId;
- private boolean stopped = false;
-
- private final Executor fetchExecutor;
- private final ExecutorService defaultExecutor;
- private final MyJob fetchingJob;
-
- private final long timeout;
- private final int maxNotifs;
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event",
- "FetchingEventRelay");
- private static final ThreadFactory daemonThreadFactory =
- new DaemonThreadFactory("JMX FetchingEventRelay executor %d");
-}
--- a/jdk/src/share/classes/javax/management/event/ListenerInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +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 javax.management.event;
-
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-
-/**
- * This class specifies all the information required to register a user listener into
- * a remote MBean server. This class is not serializable because a user listener
- * is not serialized in order to be sent to the remote server.
- *
- * @since JMX 2.0
- */
-public class ListenerInfo {
-
- /**
- * Constructs a {@code ListenerInfo} object.
- *
- * @param name The name of the MBean to which the listener should
- * be added.
- * @param listener The listener object which will handle the
- * notifications emitted by the MBean.
- * @param filter The filter object. If the filter is null, no
- * filtering will be performed before notifications are handled.
- * @param handback The context to be sent to the listener when a
- * notification is emitted.
- * @param isSubscription If true, the listener is subscribed via
- * an {@code EventManager}. Otherwise it is added to a registered MBean.
- */
- public ListenerInfo(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback,
- boolean isSubscription) {
- this.name = name;
- this.listener = listener;
- this.filter = filter;
- this.handback = handback;
- this.isSubscription = isSubscription;
- }
-
- /**
- * Returns an MBean or an MBean pattern that the listener listens to.
- *
- * @return An MBean or an MBean pattern.
- */
- public ObjectName getObjectName() {
- return name;
- }
-
- /**
- * Returns the listener.
- *
- * @return The listener.
- */
- public NotificationListener getListener() {
- return listener;
- }
-
- /**
- * Returns the listener filter.
- *
- * @return The filter.
- */
- public NotificationFilter getFilter() {
- return filter;
- }
-
- /**
- * Returns the listener handback.
- *
- * @return The handback.
- */
- public Object getHandback() {
- return handback;
- }
-
- /**
- * Returns true if this is a subscription listener.
- *
- * @return True if this is a subscription listener.
- *
- * @see EventClient#addListeners
- */
- public boolean isSubscription() {
- return isSubscription;
- }
-
- /**
- * <p>Indicates whether some other object is "equal to" this one.
- * The return value is true if and only if {@code o} is an instance of
- * {@code ListenerInfo} and has equal values for all of its properties.</p>
- */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof ListenerInfo)) {
- return false;
- }
-
- ListenerInfo li = (ListenerInfo)o;
-
- boolean ret = name.equals(li.name) &&
- (listener == li.listener) &&
- (isSubscription == li.isSubscription);
-
- if (filter != null) {
- ret &= filter.equals(li.filter);
- } else {
- ret &= (li.filter == null);
- }
-
- if (handback != null) {
- ret &= handback.equals(li.handback);
- } else {
- ret &= (li.handback == null);
- }
-
- return ret;
- }
-
- @Override
- public int hashCode() {
- return name.hashCode() + listener.hashCode();
- }
-
- @Override
- public String toString() {
- return name.toString() + "_" +
- listener + "_" +
- filter + "_" +
- handback + "_" +
- isSubscription;
- }
-
- private final ObjectName name;
- private final NotificationListener listener;
- private final NotificationFilter filter;
- private final Object handback;
- private final boolean isSubscription;
-}
--- a/jdk/src/share/classes/javax/management/event/NotificationManager.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +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 javax.management.event;
-
-import java.io.IOException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-
-/**
- * This interface specifies methods to add and remove notification listeners
- * on named MBeans.
- */
-public interface NotificationManager {
- /**
- * <p>Adds a listener to a registered MBean.
- * Notifications emitted by the MBean will be forwarded
- * to the listener.
- *
- * @param name The name of the MBean on which the listener should
- * be added.
- * @param listener The listener object which will handle the
- * notifications emitted by the registered MBean.
- * @param filter The filter object. If filter is null, no
- * filtering will be performed before handling notifications.
- * @param handback The context to be sent to the listener when a
- * notification is emitted.
- *
- * @exception InstanceNotFoundException The MBean name provided
- * does not match any of the registered MBeans.
- * @exception IOException A communication problem occurred when
- * talking to the MBean server.
- *
- * @see #removeNotificationListener(ObjectName, NotificationListener)
- * @see #removeNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object)
- */
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- IOException;
-
- /**
- * <p>Removes a listener from a registered MBean.</p>
- *
- * <P> If the listener is registered more than once, perhaps with
- * different filters or callbacks, this method will remove all
- * those registrations.
- *
- * @param name The name of the MBean on which the listener should
- * be removed.
- * @param listener The listener to be removed.
- *
- * @exception InstanceNotFoundException The MBean name provided
- * does not match any of the registered MBeans.
- * @exception ListenerNotFoundException The listener is not
- * registered in the MBean.
- * @exception IOException A communication problem occurred when
- * talking to the MBean server.
- *
- * @see #addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object)
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException;
-
- /**
- * <p>Removes a listener from a registered MBean.</p>
- *
- * <p>The MBean must have a listener that exactly matches the
- * given <code>listener</code>, <code>filter</code>, and
- * <code>handback</code> parameters. If there is more than one
- * such listener, only one is removed.</p>
- *
- * <p>The <code>filter</code> and <code>handback</code> parameters
- * may be null if and only if they are null in a listener to be
- * removed.</p>
- *
- * @param name The name of the MBean on which the listener should
- * be removed.
- * @param listener The listener to be removed.
- * @param filter The filter that was specified when the listener
- * was added.
- * @param handback The handback that was specified when the
- * listener was added.
- *
- * @exception InstanceNotFoundException The MBean name provided
- * does not match any of the registered MBeans.
- * @exception ListenerNotFoundException The listener is not
- * registered in the MBean, or it is not registered with the given
- * filter and handback.
- * @exception IOException A communication problem occurred when
- * talking to the MBean server.
- *
- * @see #addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object)
- *
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException;
-}
--- a/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +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 javax.management.event;
-
-import com.sun.jmx.event.DaemonThreadFactory;
-import com.sun.jmx.event.RepeatedSingletonJob;
-import com.sun.jmx.remote.util.ClassLogger;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import javax.management.Notification;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
-
-
-/**
- * This class is used by {@link RMIPushEventRelay}. When
- * {@link RMIPushEventRelay} calls {@link
- * EventClientDelegateMBean#addClient(String, Object[], String[])} to get a new
- * client identifier, it uses this class name as the
- * first argument to ask {@code EventClientDelegateMBean} to create an object of
- * this class.
- * Then {@code EventClientDelegateMBean} forwards client notifications
- * to this object. This object then continues forwarding the notifications
- * to the {@code RMIPushEventRelay}.
- */
-public class RMIPushEventForwarder implements EventForwarder {
- private static final int DEFAULT_BUFFER_SIZE = 6000;
-
- /**
- * Creates a new instance of {@code RMIPushEventForwarder}.
- *
- * @param receiver An RMI stub exported to receive notifications
- * from this object for its {@link RMIPushEventRelay}.
- *
- * @param bufferSize The maximum number of notifications to store
- * while waiting for the last remote send to complete.
- */
- public RMIPushEventForwarder(RMIPushServer receiver, int bufferSize) {
- if (logger.traceOn()) {
- logger.trace("RMIEventForwarder", "new one");
- }
-
- if (bufferSize < 0) {
- throw new IllegalArgumentException(
- "Negative buffer size: " + bufferSize);
- } else if (bufferSize == 0)
- bufferSize = DEFAULT_BUFFER_SIZE;
-
- if (receiver == null) {
- throw new NullPointerException();
- }
-
- this.receiver = receiver;
- this.buffer = new ArrayBlockingQueue<TargetedNotification>(bufferSize);
- }
-
- public void forward(Notification n, Integer listenerId) {
- if (logger.traceOn()) {
- logger.trace("forward", "to the listener: "+listenerId);
- }
- synchronized(sendingJob) {
- TargetedNotification tn = new TargetedNotification(n, listenerId);
- while (!buffer.offer(tn)) {
- buffer.remove();
- passed++;
- }
- sendingJob.resume();
- }
- }
-
- public void close() {
- if (logger.traceOn()) {
- logger.trace("close", "called");
- }
-
- synchronized(sendingJob) {
- ended = true;
- buffer.clear();
- }
- }
-
- public void setClientId(String clientId) {
- if (logger.traceOn()) {
- logger.trace("setClientId", clientId);
- }
- }
-
- private class SendingJob extends RepeatedSingletonJob {
- public SendingJob() {
- super(executor);
- }
-
- public boolean isSuspended() {
- return ended || buffer.isEmpty();
- }
-
- public void task() {
- final long earliest = passed;
-
- List<TargetedNotification> tns =
- new ArrayList<TargetedNotification>(buffer.size());
- synchronized(sendingJob) {
- buffer.drainTo(tns);
- passed += tns.size();
- }
-
- if (logger.traceOn()) {
- logger.trace("SendingJob-task", "sending: "+tns.size());
- }
-
- if (!tns.isEmpty()) {
- try {
- TargetedNotification[] tnArray =
- new TargetedNotification[tns.size()];
- tns.toArray(tnArray);
- receiver.receive(new NotificationResult(earliest, passed, tnArray));
- } catch (RemoteException e) {
- if (logger.debugOn()) {
- logger.debug("SendingJob-task",
- "Got exception to forward notifs.", e);
- }
-
- long currentLost = passed - earliest;
- if (FetchingEventRelay.isSerialOrClassNotFound(e)) {
- // send one by one
- long tmpPassed = earliest;
- for (TargetedNotification tn : tns) {
- try {
- receiver.receive(new NotificationResult(earliest,
- ++tmpPassed, new TargetedNotification[]{tn}));
- } catch (RemoteException ioee) {
- logger.trace(
- "SendingJob-task", "send to remote", ioee);
- // sends nonFatal notifs?
- }
- }
-
- currentLost = passed - tmpPassed;
- }
-
- if (currentLost > 0) { // inform of the lost.
- try {
- receiver.receive(new NotificationResult(
- passed, passed,
- new TargetedNotification[]{}));
- } catch (RemoteException ee) {
- logger.trace(
- "SendingJob-task", "receiver.receive", ee);
- }
- }
- }
- }
- }
- }
-
- private long passed = 0;
-
- private static final ExecutorService executor =
- Executors.newCachedThreadPool(
- new DaemonThreadFactory("JMX RMIEventForwarder Executor"));
- private final SendingJob sendingJob = new SendingJob();
-
- private final BlockingQueue<TargetedNotification> buffer;
-
- private final RMIPushServer receiver;
- private boolean ended = false;
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "RMIEventForwarder");
-}
--- a/jdk/src/share/classes/javax/management/event/RMIPushEventRelay.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +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 javax.management.event;
-
-import com.sun.jmx.remote.util.ClassLogger;
-import java.io.IOException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import javax.management.MBeanException;
-import javax.management.remote.NotificationResult;
-
-/**
- * This class is an implementation of the {@link EventRelay} interface, using
- * push mode. It exports an RMI object that {@link RMIPushEventForwarder} uses
- * to forward notifications.
- *
- * @since JMX 2.0
- */
-public class RMIPushEventRelay implements EventRelay {
- /**
- * Constructs a default {@code RMIPushEventRelay} object
- * and exports its {@linkplain RMIPushServer notification
- * receiver} on any free port. This constructor is equivalent
- * to {@link #RMIPushEventRelay(EventClientDelegateMBean,
- * int, RMIClientSocketFactory, RMIServerSocketFactory, int)
- * RMIPushEventRelay(delegate, 0, null, null, <em><default buffer
- * size></em>)}.
- *
- * @param delegate The {@link EventClientDelegateMBean} proxy to work with.
- * @throws IOException if failed to communicate with
- * {@link EventClientDelegateMBean}.
- * @throws MBeanException if the {@link EventClientDelegateMBean} failed
- * to create an {@code EventForwarder} for this object.
- */
- public RMIPushEventRelay(EventClientDelegateMBean delegate)
- throws IOException, MBeanException {
- this(delegate, 0, null, null, 0);
- }
-
- /**
- * Constructs a {@code RMIPushEventRelay} object and exports its
- * {@linkplain RMIPushServer notification receiver} on a specified port.
- *
- * @param delegate The {@link EventClientDelegateMBean} proxy to work with.
- * @param port The port used to export an RMI object to receive notifications
- * from a server. If the port is zero, an anonymous port is used.
- * @param csf The client socket factory used to export the RMI object.
- * Can be null.
- * @param ssf The server socket factory used to export the RMI object.
- * Can be null.
- * @param bufferSize The number of notifications held on the server
- * while waiting for the previous transmission to complete. A value of
- * zero means the default buffer size.
- *
- * @throws IOException if failed to communicate with
- * {@link EventClientDelegateMBean}.
- * @throws MBeanException if the {@link EventClientDelegateMBean} failed
- * to create an {@code EventForwarder} for this object.
- *
- * @see RMIPushEventForwarder#RMIPushEventForwarder(RMIPushServer, int)
- */
- public RMIPushEventRelay(EventClientDelegateMBean delegate,
- int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf,
- int bufferSize)
- throws IOException, MBeanException {
-
- UnicastRemoteObject.exportObject(exportedReceiver, port, csf, ssf);
-
- clientId = delegate.addClient(
- RMIPushEventForwarder.class.getName(),
- new Object[] {exportedReceiver, bufferSize},
- new String[] {RMIPushServer.class.getName(),
- int.class.getName()});
- }
-
- public String getClientId() {
- return clientId;
- }
-
- public void setEventReceiver(EventReceiver receiver) {
- if (logger.traceOn()) {
- logger.trace("setEventReceiver", ""+receiver);
- }
- synchronized(lock) {
- this.receiver = receiver;
- }
- }
-
- public void stop() {
- if (logger.traceOn()) {
- logger.trace("stop", "");
- }
- synchronized(lock) {
- if (stopped) {
- return;
- } else {
- stopped = true;
- }
-
- if (clientId == null) {
- return;
- }
-
- try {
- UnicastRemoteObject.unexportObject(exportedReceiver, true);
- } catch (NoSuchObjectException nsoe) {
- logger.fine("RMIPushEventRelay.stop", "unexport", nsoe);
- // OK: we wanted it unexported, and apparently it already is
- }
- }
- }
-
- private volatile String clientId;
- private volatile EventReceiver receiver;
-
- private RMIPushServer exportedReceiver = new RMIPushServer() {
- public void receive(NotificationResult nr) throws RemoteException {
- if (logger.traceOn()) {
- logger.trace("EventPusherImpl-receive","");
- }
- receiver.receive(nr);
- // Any exception will be sent back to the client.
- }
- };
-
- private boolean stopped = false;
-
- private final int[] lock = new int[0];
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event",
- "PushEventRelay");
-}
--- a/jdk/src/share/classes/javax/management/event/RMIPushServer.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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 javax.management.event;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import javax.management.remote.NotificationResult;
-
-/**
- * The {@link RMIPushEventRelay} exports an RMI object of this class and
- * sends a client stub for that object to the associated
- * {@link RMIPushEventForwarder} in a remote MBean server. The
- * {@code RMIPushEventForwarder} then sends notifications to the
- * RMI object.
- */
-public interface RMIPushServer extends Remote {
- /**
- * <p>Dispatch the notifications in {@code nr} to the {@link RMIPushEventRelay}
- * associated with this object.</p>
- * @param nr the notification result to dispatch.
- * @throws java.rmi.RemoteException if the remote invocation of this method
- * failed.
- */
- public void receive(NotificationResult nr) throws RemoteException;
-}
--- a/jdk/src/share/classes/javax/management/event/package-info.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,312 +0,0 @@
-/**
- * <p>Defines the <em>Event Service</em>, which provides extended support
- * for JMX notifications.</p>
- *
- * <p>The Event Service provides greater control over
- * notification handling than the default technique using {@link
- * javax.management.MBeanServer#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)
- * MBeanServer.addNotificationListener} or {@link
- * javax.management.MBeanServerConnection#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)
- * MBeanServerConnection.addNotificationListener}.</p>
- *
- * <p>Here are some reasons you may want to use the Event Service:</p>
- *
- * <ul>
- * <li>To receive notifications from a set of MBeans defined by an
- * ObjectName pattern, such as {@code com.example.config:type=Cache,*}.
- *
- * <li>When the notification-handling behavior of the connector you are
- * using does not match your requirements. For example, with the standard
- * RMI connector you can lose notifications if there are very many of them
- * in the MBean Server you are connected to, even if you are only listening
- * for a small proportion of them.
- *
- * <li>To change the threading behavior of notification dispatch.
- *
- * <li>To define a different transport for notifications, for example to
- * arrange for them to be delivered through the Java Message Service (<a
- * href="http://java.sun.com/jms">JMS</a>). The Event Service comes with
- * one alternative transport as standard, a "push-mode" RMI transport.
- *
- * <li>To handle notifications on behalf of MBeans (often virtual) in a
- * namespace.
- * </ul>
- *
- * <p>The Event Service is new in version 2.0 of the JMX API, which is the
- * version introduced in version 7 of the Java SE platform. It is not usually
- * possible to use the Event Service when connecting remotely to an
- * MBean Server that is running an earlier version.</p>
- *
- *
- * <h3 id="handlingremote">Handling remote notifications with the Event
- * Service</h3>
- *
- * <p>Prior to version 2.0 of the JMX API, every connector
- * had to include logic to handle notifications. The standard {@linkplain
- * javax.management.remote.rmi RMI} and JMXMP connectors defined by <a
- * href="http://jcp.org/en/jsr/detail?id=160">JSR 160</a> handle notifications
- * in a way that is not always appropriate for applications. Specifically,
- * the connector server adds one listener to every MBean that might emit
- * notifications, and adds all received notifications to a fixed-size
- * buffer. This means that if there are very many notifications, a
- * remote client may miss some, even if it is only registered for a
- * very small subset of notifications. Furthermore, since every {@link
- * javax.management.NotificationBroadcaster NotificationBroadcaster} MBean
- * gets a listener from the connector server, MBeans cannot usefully optimize
- * by only sending notifications when there is a listener. Finally, since
- * the connector server uses just one listener per MBean, MBeans cannot
- * impose custom behavior per listener, such as security checks or localized
- * notifications.</p>
- *
- * <p>The Event Service does not have these restrictions. The RMI connector
- * that is included in this version of the JMX API uses the Event Service by
- * default, although it can be configured to have the previous behavior if
- * required.</p>
- *
- * <p>The Event Service can be used with <em>any</em> connector via the
- * method {@link javax.management.event.EventClient#getEventClientConnection
- * EventClient.getEventClientConnection}, like this:</p>
- *
- * <pre>
- * JMXConnector conn = ...;
- * MBeanServerConnection mbsc = conn.getMBeanServerConnection();
- * MBeanServerConnection eventMbsc = EventClient.getEventClientConnection(mbsc);
- * </pre>
- *
- * <p>If you add listeners using {@code eventMbsc.addNotificationListener}
- * instead of {@code mbsc.addNotificationListener}, then they will be handled
- * by the Event Service rather than by the connector's notification system.</p>
- *
- * <p>For the Event Service to work, either the {@link
- * javax.management.event.EventClientDelegateMBean EventClientDelegateMBean}
- * must be registered in the MBean Server, or the connector server must
- * be configured to simulate the existence of this MBean, for example
- * using {@link javax.management.event.EventClientDelegate#newForwarder
- * EventClientDelegate.newForwarder}. The standard RMI connector is so
- * configured by default. The {@code EventClientDelegateMBean} documentation
- * has further details.</p>
- *
- *
- * <h3 id="subscribepattern">Receiving notifications from a set of MBeans</h3>
- *
- * <p>The Event Server allows you to receive notifications from every MBean
- * that matches an {@link javax.management.ObjectName ObjectName} pattern.
- * For local clients (in the same JVM as the MBean Server), the {@link
- * javax.management.event.EventSubscriber EventSubscriber} class can be used for
- * this. For remote clients, or if the same code is to be used locally and
- * remotely, use an
- * {@link javax.management.event.EventClient EventClient}.</p>
- *
- * <p>EventSubscriber and EventClient correctly handle the case where a new
- * MBean is registered under a name that matches the pattern. Notifications
- * from the new MBean will also be received.</p>
- *
- * <p>Here is how to receive notifications from all MBeans in a local
- * {@code MBeanServer} that match {@code com.example.config:type=Cache,*}:</p>
- *
- * <pre>
- * MBeanServer mbs = ...;
- * NotificationListener listener = ...;
- * ObjectName pattern = new ObjectName("com.example.config:type=Cache,*");
- * EventSubscriber esub = EventSubscriber.getEventSubscriber(mbs);
- * esub.{@link javax.management.event.EventSubscriber#subscribe
- * subscribe}(pattern, listener, null, null);
- * </pre>
- *
- * <p>Here is how to do the same thing remotely:</p>
- *
- * <pre>
- * MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
- * EventClient events = new EventClient(mbsc);
- * NotificationListener listener = ...;
- * ObjectName pattern = new ObjectName("com.example.config:type=Cache,*");
- * events.{@link javax.management.event.EventClient#subscribe
- * subscribe}(pattern, listener, null, null);
- * </pre>
- *
- *
- * <h3 id="threading">Controlling threading behavior for notification
- * dispatch</h3>
- *
- * <p>The EventClient class can be used to control threading of listener
- * dispatch. For example, to arrange for all listeners to be invoked
- * in the same thread, you can create an {@code EventClient} like this:</p>
- *
- * <pre>
- * MBeanServerConnection mbsc = ...;
- * Executor singleThreadExecutor = {@link
- * java.util.concurrent.Executors#newSingleThreadExecutor()
- * Executors.newSingleThreadExecutor}();
- * EventClient events = new EventClient(
- * mbsc, null, singleThreadExecutor, EventClient.DEFAULT_LEASE_TIMEOUT);
- * events.addNotificationListener(...);
- * events.subscribe(...);
- * </pre>
- *
- *
- * <h3 id="leasing">Leasing</h3>
- *
- * <p>The {@code EventClient} uses a <em>lease</em> mechanism to ensure
- * that resources are eventually released on the server even if the client
- * does not explicitly clean up. (This can happen through network
- * partitioning, for example.)</p>
- *
- * <p>When an {@code EventClient} registers with the {@code
- * EventClientDelegateMBean} using one of the {@code addClient} methods,
- * an initial lease is created with a default expiry time. The {@code
- * EventClient} requests an explicit lease shortly after that, with a
- * configurable expiry time. Then the {@code EventClient} periodically
- * <em>renews</em> the lease before it expires, typically about half way
- * through the lifetime of the lease. If at any point the lease reaches
- * the expiry time of the last renewal then it expires, and {@code
- * EventClient} is unregistered as if it had called the {@link
- * javax.management.event.EventClientDelegateMBean#removeClient removeClient}
- * method.</p>
- *
- *
- * <h3 id="transports">Custom notification transports</h3>
- *
- * <p>When you create an {@code EventClient}, you can define the transport
- * that it uses to deliver notifications. The transport might use the
- * Java Message Service (<a href="http://java.sun.com/jms">JMS</a>) or
- * any other communication system. Specifying a transport is useful for
- * example when you want different network behavior from the default, or
- * different reliability guarantees. The default transport calls {@link
- * javax.management.event.EventClientDelegateMBean#fetchNotifications
- * EventClientDelegateMBean.fetchNotifications} repeatedly, which usually means
- * that there must be a network connection permanently open between the client
- * and the server. If the same client is connected to many servers this can
- * cause scalability problems. If notifications are relatively rare, then
- * JMS or the {@linkplain javax.management.event.RMIPushEventRelay push-mode
- * RMI transport} may be more suitable.</p>
- *
- * <p>A transport is implemented by an {@link javax.management.event.EventRelay
- * EventRelay} on the client side and a corresponding {@link
- * javax.management.event.EventForwarder EventForwarder}
- * on the server side. An example is the {@link
- * javax.management.event.RMIPushEventRelay RMIPushEventRelay} and its
- * {@link javax.management.event.RMIPushEventForwarder RMIPushEventForwarder}.</p>
- *
- * <p>To use a given transport with an {@code EventClient}, you first create
- * an instance of its {@code EventRelay}. Typically the {@code EventRelay}'s
- * constructor will have a parameter of type {@code MBeanServerConnection}
- * or {@code EventClientDelegateMBean}, so that it can communicate with the
- * {@code EventClientDelegateMBean} in the server. For example, the {@link
- * javax.management.event.RMIPushEventForwarder RMIPushEventForwarder}'s constructors
- * all take an {@code EventClientDelegateMBean} parameter, which is expected to
- * be a {@linkplain javax.management.JMX#newMBeanProxy(MBeanServerConnection,
- * ObjectName, Class) proxy} for the {@code EventClientDelegateMBean} in the
- * server.</p>
- *
- * <p>When it is created, the {@code EventRelay} will call
- * {@link javax.management.event.EventClientDelegateMBean#addClient(String,
- * Object[], String[]) EventClientDelegateMBean.addClient}. It passes the
- * name of the {@code EventForwarder} class and its constructor parameters.
- * The {@code EventClientDelegateMBean} will instantiate this class using
- * {@link javax.management.MBeanServer#instantiate(String, Object[], String[])
- * MBeanServer.instantiate}, and it will return a unique <em>client id</em>.</p>
- *
- * <p>Then you pass the newly-created {@code EventRelay} to one of the {@code
- * EventClient} constructors, and you have an {@code EventClient} that uses the
- * chosen transport.</p>
- *
- * <p>For example, when you create an {@code RMIPushEventRelay}, it
- * uses {@code MBeanServerDelegateMBean.addClient} to create an {@code
- * RMIEventForwarder} in the server. Notifications will then be delivered
- * through an RMI communication from the {@code RMIEventForwarder} to the
- * {@code RMIPushEventRelay}.</p>
- *
- *
- * <h4 id="writingcustomtransport">Writing a custom transport</h4>
- *
- * <p>To write a custom transport, you need to understand the sequence
- * of events when an {@code EventRelay} and its corresponding {@code
- * EventForwarder} are created, and when a notification is sent from the {@code
- * EventForwarder} to the {@code EventRelay}.</p>
- *
- * <p>When an {@code EventRelay} is created:</p>
- *
- * <ul>
- * <li><p>The {@code EventRelay} must call {@code
- * EventClientDelegateMBean.addClient} with the name of the {@code
- * EventForwarder} and the constructor parameters.</p>
- *
- * <li><p>{@code EventClientDelegateMBean.addClient} will do the following
- * steps:</p>
- *
- * <ul>
- * <li>create the {@code EventForwarder} using {@code MBeanServer.instantiate};
- * <li>allocate a unique client id;
- * <li>call the new {@code EventForwarder}'s {@link
- * javax.management.event.EventForwarder#setClientId setClientId} method with
- * the new client id;
- * <li>return the client id to the caller.
- * </ul>
- *
- * </ul>
- *
- * <p>When an {@code EventClient} is created with an {@code EventRelay}
- * parameter, it calls {@link javax.management.event.EventRelay#setEventReceiver
- * EventRelay.setEventReceiver} with an {@code EventReceiver} that the
- * {@code EventRelay} will use to deliver notifications.</p>
- *
- * <p>When a listener is added using the {@code EventClient}, the
- * {@code EventRelay} and {@code EventForwarder} are not involved.</p>
- *
- * <p>When an MBean emits a notification and a listener has been added
- * to that MBean using the {@code EventClient}:</p>
- *
- * <ul>
- * <li><p>The {@code EventForwarder}'s
- * {@link javax.management.event.EventForwarder#forward forward} method
- * is called with the notification and a <em>listener id</em>.</p>
- *
- * <li><p>The {@code EventForwarder} sends the notification and listener id
- * to the {@code EventRelay} using the custom transport.</p>
- *
- * <li><p>The {@code EventRelay} delivers the notification by calling
- * {@link javax.management.event.EventReceiver#receive EventReceiver.receive}.</p>
- * </ul>
- *
- * <p>When the {@code EventClient} is closed ({@link
- * javax.management.event.EventClient#close EventClient.close}):</p>
- *
- * <ul>
- * <li><p>The {@code EventClient} calls {@link
- * javax.management.event.EventRelay#stop EventRelay.stop}.</p>
- *
- * <li><p>The {@code EventClient} calls {@link
- * javax.management.event.EventClientDelegateMBean#removeClient
- * EventClientDelegateMBean.removeClient}.</p>
- *
- * <li><p>The {@code EventClientDelegateMBean} removes any listeners it
- * had added on behalf of this {@code EventClient}.</p>
- *
- * <li><p>The {@code EventClientDelegateMBean} calls
- * {@link javax.management.event.EventForwarder#close EventForwarder.close}.</p>
- * </ul>
- *
- *
- * <h4 id="threading">Threading and buffering</h3>
- *
- * <p>The {@link javax.management.event.EventForwarder#forward
- * EventForwarder.forward} method may be called in the thread that the
- * source MBean is using to send its notification. MBeans can expect
- * that notification sending does not block. Therefore a {@code forward}
- * method will typically add the notification to a queue, with a separate
- * thread that takes notifications off the queue and sends them.</p>
- *
- * <p>An {@code EventRelay} does not usually need to buffer notifications
- * before giving them to
- * {@link javax.management.event.EventReceiver#receive EventReceiver.receive}.
- * Although by default each such notification will be sent to potentially-slow
- * listeners, if this is a problem then an {@code Executor} can be given to
- * the {@code EventClient} constructor to cause the listeners to be called
- * in a different thread.</p>
- *
- * @since 1.7
- */
-
-package javax.management.event;
--- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -229,10 +229,9 @@
init(inDescr.descriptorMap);
}
+
/**
- * <p>Descriptor constructor taking an XML String or a
- * <i>fieldName=fieldValue</i> format String. The String parameter is
- * parsed as XML if it begins with a '<' character.</p>
+ * <p>Descriptor constructor taking an XML String.</p>
*
* <p>The format of the XML string is not defined, but an
* implementation must ensure that the string returned by
@@ -245,20 +244,17 @@
* programmer will have to reset or convert these fields
* correctly.</p>
*
- * @param inStr An XML-format or a fieldName=fieldValue formatted string
- * used to populate this Descriptor. The XML format is not defined, but any
+ * @param inStr An XML-formatted string used to populate this
+ * Descriptor. The format is not defined, but any
* implementation must ensure that the string returned by
* method {@link #toXMLString toXMLString} on an existing
* descriptor can be used to instantiate an equivalent
* descriptor when instantiated using this constructor.
*
- * @exception RuntimeOperationsException If the String inStr passed in
- * parameter is null or, when it is not an XML string, if the field name or
- * field value is illegal. If inStr is not an XML string then it must
- * contain an "=". "fieldValue", "fieldName", and "fieldValue" are illegal.
- * FieldName cannot be empty. "fieldName=" will cause the value to be empty.
+ * @exception RuntimeOperationsException If the String inStr
+ * passed in parameter is null
* @exception XMLParseException XML parsing problem while parsing
- * the XML-format input String
+ * the input String
* @exception MBeanException Wraps a distributed communication Exception.
*/
/* At some stage we should rewrite this code to be cleverer. Using
@@ -287,27 +283,14 @@
throw new RuntimeOperationsException(iae, msg);
}
- // parse parameter string into structures
-
- init(null);
-
- if(!inStr.startsWith("<")) {
- parseNamesValues(inStr);
- if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
- MODELMBEAN_LOGGER.logp(Level.FINEST,
- DescriptorSupport.class.getName(),
- "Descriptor(name=value)", "Exit");
- }
- return;
- }
-
final String lowerInStr = inStr.toLowerCase();
if (!lowerInStr.startsWith("<descriptor>")
|| !lowerInStr.endsWith("</descriptor>")) {
throw new XMLParseException("No <descriptor>, </descriptor> pair");
}
-
+ // parse xmlstring into structures
+ init(null);
// create dummy descriptor: should have same size
// as number of fields in xmlstring
// loop through structures and put them in descriptor
@@ -471,16 +454,6 @@
init(null);
- parseNamesValues(fields);
-
- if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
- MODELMBEAN_LOGGER.logp(Level.FINEST,
- DescriptorSupport.class.getName(),
- "Descriptor(String... fields)", "Exit");
- }
- }
-
- private void parseNamesValues(String... fields) {
for (int i=0; i < fields.length; i++) {
if ((fields[i] == null) || (fields[i].equals(""))) {
continue;
@@ -522,6 +495,11 @@
setField(fieldName,fieldValue);
}
+ if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
+ MODELMBEAN_LOGGER.logp(Level.FINEST,
+ DescriptorSupport.class.getName(),
+ "Descriptor(String... fields)", "Exit");
+ }
}
private void init(Map<String, ?> initMap) {
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -231,16 +231,14 @@
* @param descriptor An instance of Descriptor containing the
* appropriate metadata for this instance of the Attribute. If
* it is null, then a default descriptor will be created. If
- * the descriptor does not contain all the following fields,
- * the missing ones are added with their default values:
- * displayName, name, descriptorType.
+ * the descriptor does not contain the field "displayName" this field is added
+ * in the descriptor with its default value.
* @exception IntrospectionException There is a consistency
* problem in the definition of this attribute.
* @exception RuntimeOperationsException Wraps an
- * IllegalArgumentException. The descriptor is invalid, or
- * descriptor field "name" is present but not equal to name
- * parameter, or descriptor field "descriptorType" is present
- * but not equal to "attribute".
+ * IllegalArgumentException. The descriptor is invalid, or descriptor
+ * field "name" is not equal to name parameter, or descriptor field
+ * "descriptorType" is not equal to "attribute".
*
*/
@@ -295,7 +293,7 @@
}
/**
- * Constructs a ModelMBeanAttributeInfo object with a default descriptor.
+ * Constructs a ModelMBeanAttributeInfo object.
*
* @param name The name of the attribute
* @param type The type or class name of the attribute
@@ -306,14 +304,12 @@
* @param descriptor An instance of Descriptor containing the
* appropriate metadata for this instance of the Attribute. If
* it is null then a default descriptor will be created. If
- * the descriptor does not contain all the following fields,
- * the missing ones are added with their default values:
- * displayName, name, descriptorType.
+ * the descriptor does not contain the field "displayName" this field
+ * is added in the descriptor with its default value.
* @exception RuntimeOperationsException Wraps an
- * IllegalArgumentException. The descriptor is invalid, or
- * descriptor field "name" is present but not equal to name
- * parameter, or descriptor field "descriptorType" is present
- * but not equal to "attribute".
+ * IllegalArgumentException. The descriptor is invalid, or descriptor
+ * field "name" is not equal to name parameter, or descriptor field
+ * "descriptorType" is not equal to "attribute".
*
*/
public ModelMBeanAttributeInfo(String name,
@@ -392,9 +388,6 @@
* assigned. If the new Descriptor is invalid, then a
* RuntimeOperationsException wrapping an
* IllegalArgumentException is thrown.
- * If the descriptor does not contain all the following fields, the
- * missing ones are added with
- * their default values: displayName, name, descriptorType.
* @param inDescriptor replaces the Descriptor associated with the
* ModelMBeanAttributeInfo
*
@@ -415,6 +408,7 @@
* fails for any reason, this exception will be thrown.
*/
+ @Override
public Object clone()
{
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
@@ -429,6 +423,7 @@
* Returns a human-readable version of the
* ModelMBeanAttributeInfo instance.
*/
+ @Override
public String toString()
{
return
@@ -456,7 +451,8 @@
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone;
- if (in == null) {
+ boolean defaulted = (in == null);
+ if (defaulted) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
} else {
@@ -464,11 +460,11 @@
}
//Setting defaults.
- if (clone.getFieldValue("name")==null) {
+ if (defaulted && clone.getFieldValue("name")==null) {
clone.setField("name", this.getName());
MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to " + this.getName());
}
- if (clone.getFieldValue("descriptorType")==null) {
+ if (defaulted && clone.getFieldValue("descriptorType")==null) {
clone.setField("descriptorType", "attribute");
MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \"attribute\"");
}
@@ -483,13 +479,13 @@
"The isValid() method of the Descriptor object itself returned false,"+
"one or more required fields are invalid. Descriptor:" + clone.toString());
}
- if (! ((String)clone.getFieldValue("name")).equalsIgnoreCase(this.getName())) {
+ if (!getName().equalsIgnoreCase((String)clone.getFieldValue("name"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"name\" field does not match the object described. " +
" Expected: "+ this.getName() + " , was: " + clone.getFieldValue("name"));
}
- if (! ((String)clone.getFieldValue("descriptorType")).equalsIgnoreCase("attribute")) {
+ if (!"attribute".equalsIgnoreCase((String)clone.getFieldValue("descriptorType"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"descriptorType\" field does not match the object described. " +
" Expected: \"attribute\" ," + " was: " + clone.getFieldValue("descriptorType"));
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -78,9 +78,7 @@
* are meaningless for constructors, but are not considered invalid.</p>
*
* <p>The default descriptor will have the {@code name}, {@code
- * descriptorType}, {@code displayName} and {@code role} fields. The
- * default value of the {@code name} and {@code displayName} fields is
- * the name of the constructor.
+ * descriptorType}, {@code displayName} and {@code role} fields.
*
* <p>The <b>serialVersionUID</b> of this class is <code>3862947819818064362L</code>.
*
@@ -193,14 +191,14 @@
* appropriate metadata for this instance of the
* ModelMBeanConstructorInfo. If it is null, then a default
* descriptor will be created. If the descriptor does not
- * contain all the following fields, the missing ones are added with
- * their default values: displayName, name, role, descriptorType.
+ * contain the field "displayName" this field is added in the
+ * descriptor with its default value.
*
* @exception RuntimeOperationsException Wraps an
* IllegalArgumentException. The descriptor is invalid, or
- * descriptor field "name" is present but not equal to name
- * parameter, or descriptor field "descriptorType" is present
- * but not equal to "operation" or descriptor field "role" is
+ * descriptor field "name" is not equal to name
+ * parameter, or descriptor field "descriptorType" is
+ * not equal to "operation" or descriptor field "role" is
* present but not equal to "constructor".
*/
@@ -250,15 +248,14 @@
* @param signature MBeanParameterInfo objects describing the parameters(arguments) of the constructor.
* @param descriptor An instance of Descriptor containing the appropriate metadata
* for this instance of the MBeanConstructorInfo. If it is null then a default descriptor will be created.
- * If the descriptor does not
- * contain all the following fields, the missing ones are added with
- * their default values: displayName, name, role, descriptorType.
+ * If the descriptor does not contain the field "displayName" this field
+ * is added in the descriptor with its default value.
*
* @exception RuntimeOperationsException Wraps an
* IllegalArgumentException. The descriptor is invalid, or
- * descriptor field "name" is present but not equal to name
- * parameter, or descriptor field "descriptorType" is present
- * but not equal to "operation" or descriptor field "role" is
+ * descriptor field "name" is not equal to name
+ * parameter, or descriptor field "descriptorType" is
+ * not equal to "operation" or descriptor field "role" is
* present but not equal to "constructor".
*/
@@ -300,6 +297,7 @@
* Creates and returns a new ModelMBeanConstructorInfo which is a duplicate of this ModelMBeanConstructorInfo.
*
*/
+ @Override
public Object clone ()
{
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
@@ -320,6 +318,7 @@
*/
+ @Override
public Descriptor getDescriptor()
{
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
@@ -368,6 +367,7 @@
/**
* Returns a string containing the entire contents of the ModelMBeanConstructorInfo in human readable form.
*/
+ @Override
public String toString()
{
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
@@ -404,8 +404,9 @@
* @exception RuntimeOperationsException if Descriptor is invalid
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
- Descriptor clone;
- if (in == null) {
+ Descriptor clone;
+ boolean defaulted = (in == null);
+ if (defaulted) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
} else {
@@ -413,11 +414,11 @@
}
//Setting defaults.
- if (clone.getFieldValue("name")==null) {
+ if (defaulted && clone.getFieldValue("name")==null) {
clone.setField("name", this.getName());
MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to " + this.getName());
}
- if (clone.getFieldValue("descriptorType")==null) {
+ if (defaulted && clone.getFieldValue("descriptorType")==null) {
clone.setField("descriptorType", "operation");
MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \"operation\"");
}
@@ -436,12 +437,12 @@
"The isValid() method of the Descriptor object itself returned false,"+
"one or more required fields are invalid. Descriptor:" + clone.toString());
}
- if (! ((String)clone.getFieldValue("name")).equalsIgnoreCase(this.getName())) {
+ if (!getName().equalsIgnoreCase((String) clone.getFieldValue("name"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"name\" field does not match the object described. " +
" Expected: "+ this.getName() + " , was: " + clone.getFieldValue("name"));
}
- if (! ((String)clone.getFieldValue("descriptorType")).equalsIgnoreCase("operation")) {
+ if (!"operation".equalsIgnoreCase((String) clone.getFieldValue("descriptorType"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"descriptorType\" field does not match the object described. " +
" Expected: \"operation\" ," + " was: " + clone.getFieldValue("descriptorType"));
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -945,7 +945,8 @@
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone;
- if (in == null) {
+ boolean defaulted = (in == null);
+ if (defaulted) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
} else {
@@ -953,11 +954,11 @@
}
//Setting defaults.
- if (clone.getFieldValue("name")==null) {
+ if (defaulted && clone.getFieldValue("name")==null) {
clone.setField("name", this.getClassName());
MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to " + this.getClassName());
}
- if (clone.getFieldValue("descriptorType")==null) {
+ if (defaulted && clone.getFieldValue("descriptorType")==null) {
clone.setField("descriptorType", MMB);
MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \"" + MMB + "\"");
}
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -186,14 +186,14 @@
* @param descriptor An instance of Descriptor containing the
* appropriate metadata for this instance of the
* MBeanNotificationInfo. If it is null a default descriptor
- * will be created. If the descriptor does not contain all the
- * fields "name", "descriptorType", "displayName" and "severity",
+ * will be created. If the descriptor does not contain the
+ * fields "displayName" or "severity",
* the missing ones are added with their default values.
*
* @exception RuntimeOperationsException Wraps an
* {@link IllegalArgumentException}. The descriptor is invalid, or
- * descriptor field "name" is present but not equal to parameter name, or
- * descriptor field "descriptorType" is present but not equal to "notification".
+ * descriptor field "name" is not equal to parameter name, or
+ * descriptor field "descriptorType" is not equal to "notification".
*
**/
public ModelMBeanNotificationInfo(String[] notifTypes,
@@ -341,7 +341,8 @@
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone;
- if (in == null) {
+ boolean defaulted = (in == null);
+ if (defaulted) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
} else {
@@ -349,11 +350,11 @@
}
//Setting defaults.
- if (clone.getFieldValue("name")==null) {
+ if (defaulted && clone.getFieldValue("name")==null) {
clone.setField("name", this.getName());
MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to " + this.getName());
}
- if (clone.getFieldValue("descriptorType")==null) {
+ if (defaulted && clone.getFieldValue("descriptorType")==null) {
clone.setField("descriptorType", "notification");
MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \"notification\"");
}
@@ -372,12 +373,12 @@
"The isValid() method of the Descriptor object itself returned false,"+
"one or more required fields are invalid. Descriptor:" + clone.toString());
}
- if (! ((String)clone.getFieldValue("name")).equalsIgnoreCase(this.getName())) {
+ if (!getName().equalsIgnoreCase((String) clone.getFieldValue("name"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"name\" field does not match the object described. " +
" Expected: "+ this.getName() + " , was: " + clone.getFieldValue("name"));
}
- if (! ((String)clone.getFieldValue("descriptorType")).equalsIgnoreCase("notification")) {
+ if (!"notification".equalsIgnoreCase((String) clone.getFieldValue("descriptorType"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"descriptorType\" field does not match the object described. " +
" Expected: \"notification\" ," + " was: " + clone.getFieldValue("descriptorType"));
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java Wed Oct 21 16:50:44 2009 +0100
@@ -208,16 +208,16 @@
* appropriate metadata for this instance of the
* ModelMBeanOperationInfo. If it is null a default
* descriptor will be created. If the descriptor does not
- * contain all the fields "name", "descriptorType",
- * "displayName", and "role", the missing ones are added with
+ * contain the fields
+ * "displayName" or "role", the missing ones are added with
* their default values.
*
* @exception RuntimeOperationsException Wraps an
* IllegalArgumentException. The descriptor is invalid; or
- * descriptor field "name" is present but not equal to
+ * descriptor field "name" is not equal to
* operation name; or descriptor field "DescriptorType" is
- * present but not equal to "operation"; or descriptor
- * optional field "role" is not equal to "operation",
+ * not equal to "operation"; or descriptor
+ * optional field "role" is present but not equal to "operation",
* "getter", or "setter".
*
*/
@@ -281,16 +281,16 @@
* @param descriptor An instance of Descriptor containing the
* appropriate metadata for this instance of the
* MBeanOperationInfo. If it is null then a default descriptor
- * will be created. If the descriptor does not contain all the
- * fields "name", "descriptorType", "displayName", and "role",
+ * will be created. If the descriptor does not contain
+ * fields "displayName" or "role",
* the missing ones are added with their default values.
*
* @exception RuntimeOperationsException Wraps an
* IllegalArgumentException. The descriptor is invalid; or
- * descriptor field "name" is present but not equal to
+ * descriptor field "name" is not equal to
* operation name; or descriptor field "DescriptorType" is
- * present but not equal to "operation"; or descriptor optional
- * field "role" is not equal to "operation", "getter", or
+ * not equal to "operation"; or descriptor optional
+ * field "role" is present but not equal to "operation", "getter", or
* "setter".
*/
@@ -446,7 +446,8 @@
private Descriptor validDescriptor(final Descriptor in)
throws RuntimeOperationsException {
Descriptor clone;
- if (in == null) {
+ boolean defaulted = (in == null);
+ if (defaulted) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
} else {
@@ -454,11 +455,11 @@
}
//Setting defaults.
- if (clone.getFieldValue("name")==null) {
+ if (defaulted && clone.getFieldValue("name")==null) {
clone.setField("name", this.getName());
MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to " + this.getName());
}
- if (clone.getFieldValue("descriptorType")==null) {
+ if (defaulted && clone.getFieldValue("descriptorType")==null) {
clone.setField("descriptorType", "operation");
MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \"operation\"");
}
@@ -477,15 +478,15 @@
"The isValid() method of the Descriptor object itself returned false,"+
"one or more required fields are invalid. Descriptor:" + clone.toString());
}
- if (! ((String)clone.getFieldValue("name")).equalsIgnoreCase(this.getName())) {
+ if (!getName().equalsIgnoreCase((String) clone.getFieldValue("name"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"name\" field does not match the object described. " +
" Expected: "+ this.getName() + " , was: " + clone.getFieldValue("name"));
}
- if (! ((String)clone.getFieldValue("descriptorType")).equalsIgnoreCase("operation")) {
+ if (!"operation".equalsIgnoreCase((String) clone.getFieldValue("descriptorType"))) {
throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
"The Descriptor \"descriptorType\" field does not match the object described. " +
- " Expected: \"attribute\" ," + " was: " + clone.getFieldValue("descriptorType"));
+ " Expected: \"operation\" ," + " was: " + clone.getFieldValue("descriptorType"));
}
final String role = (String)clone.getFieldValue("role");
if (!(role.equalsIgnoreCase("operation") ||
--- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Wed Oct 21 16:50:44 2009 +0100
@@ -23,7 +23,7 @@
* have any questions.
*/
/*
- * @(#)author IBM Corp.
+ * @author IBM Corp.
*
* Copyright IBM Corp. 1999-2000. All rights reserved.
*/
@@ -55,7 +55,6 @@
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.Descriptor;
-import javax.management.DynamicWrapperMBean;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
@@ -116,7 +115,7 @@
*/
public class RequiredModelMBean
- implements ModelMBean, MBeanRegistration, NotificationEmitter, DynamicWrapperMBean {
+ implements ModelMBean, MBeanRegistration, NotificationEmitter {
/*************************************/
/* attributes */
@@ -134,8 +133,6 @@
* and operations will be executed */
private Object managedResource = null;
- /* true if getWrappedObject returns the wrapped resource */
- private boolean visible;
/* records the registering in MBeanServer */
private boolean registered = false;
@@ -322,13 +319,9 @@
*
* @param mr Object that is the managed resource
* @param mr_type The type of reference for the managed resource.
- * <br>Can be: "ObjectReference", "VisibleObjectReference",
- * "Handle", "IOR", "EJBHandle", or "RMIReference".
- * <br>In this implementation only "ObjectReference" and
- * "VisibleObjectReference" are supported. The two
- * types are equivalent except for the behavior of the
- * {@link #getWrappedObject()} and {@link #getWrappedClassLoader()}
- * methods.
+ * <br>Can be: "ObjectReference", "Handle", "IOR", "EJBHandle",
+ * or "RMIReference".
+ * <br>In this implementation only "ObjectReference" is supported.
*
* @exception MBeanException The initializer of the object has
* thrown an exception.
@@ -348,11 +341,10 @@
"setManagedResource(Object,String)","Entry");
}
- visible = "visibleObjectReference".equalsIgnoreCase(mr_type);
-
// check that the mr_type is supported by this JMXAgent
// only "objectReference" is supported
- if (!"objectReference".equalsIgnoreCase(mr_type) && !visible) {
+ if ((mr_type == null) ||
+ (! mr_type.equalsIgnoreCase("objectReference"))) {
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),
@@ -378,51 +370,6 @@
}
/**
- * <p>Get the managed resource for this Model MBean. For compatibility
- * reasons, the managed resource is only returned if the resource type
- * specified to {@link #setManagedResource setManagedResource} was {@code
- * "visibleObjectReference"}. Otherwise, {@code this} is returned.</p>
- *
- * @return The value that was specified to {@link #setManagedResource
- * setManagedResource}, if the resource type is {@code
- * "visibleObjectReference"}. Otherwise, {@code this}.
- */
- public Object getWrappedObject() {
- if (visible)
- return managedResource;
- else
- return this;
- }
-
- /**
- * <p>Get the ClassLoader of the managed resource for this Model MBean. For
- * compatibility reasons, the ClassLoader of the managed resource is only
- * returned if the resource type specified to {@link #setManagedResource
- * setManagedResource} was {@code "visibleObjectReference"}. Otherwise,
- * {@code this.getClass().getClassLoader()} is returned.</p>
- *
- * @return The ClassLoader of the value that was specified to
- * {@link #setManagedResource setManagedResource}, if the resource
- * type is {@code "visibleObjectReference"}. Otherwise, {@code
- * this.getClass().getClassLoader()}.
- */
- public ClassLoader getWrappedClassLoader() {
- return getWrappedObject().getClass().getClassLoader();
- }
-
- private static boolean isTrue(Descriptor d, String field) {
- if (d == null)
- return false;
- Object x = d.getFieldValue(field);
- if (x instanceof Boolean)
- return (Boolean) x;
- if (!(x instanceof String))
- return false;
- String s = (String) x;
- return ("true".equalsIgnoreCase(s) || "T".equalsIgnoreCase(s));
- }
-
- /**
* <p>Instantiates this MBean instance with the data found for
* the MBean in the persistent store. The data loaded could include
* attribute and operation values.</p>
--- a/jdk/src/share/classes/javax/management/monitor/MonitorNotification.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/monitor/MonitorNotification.java Wed Oct 21 16:50:44 2009 +0100
@@ -201,7 +201,7 @@
* @param derGauge The derived gauge.
* @param trigger The threshold/string (depending on the monitor type) that triggered the notification.
*/
- public MonitorNotification(String type, Object source, long sequenceNumber, long timeStamp, String msg,
+ MonitorNotification(String type, Object source, long sequenceNumber, long timeStamp, String msg,
ObjectName obsObj, String obsAtt, Object derGauge, Object trigger) {
super(type, source, sequenceNumber, timeStamp, msg);
--- a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,378 +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 javax.management.namespace;
-
-import java.io.IOException;
-import javax.management.ListenerNotFoundException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
-
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerDelegate;
-import javax.management.ObjectName;
-
-/**
- * A special {@link JMXNamespace} that can handle part of
- * the MBeanServer local name space.
- * <p>
- * A {@code JMXDomain} makes a domain <i>X</i> of a
- * {@linkplain #getSourceServer() source MBean server} appear in the same domain
- * <i>X</i> of a containing {@code MBeanServer} in which the
- * {@code JMXDomain} MBean {@linkplain #getMBeanServer() is registered}.
- * </p>
- * <p>
- * The JMX infrastructure of the containing {@code MBeanServer} takes care of
- * routing all calls to MBeans whose names have domain <i>X</i> to the
- * {@linkplain #getSourceServer() source MBean server} exported by the
- * {@code JMXDomain} MBean in charge of domain <i>X</i>.
- * </p>
- * <p>
- * The {@linkplain #getSourceServer() source MBean server} of a {@code JMXDomain}
- * can, but need not be a regular {@code MBeanServer} created through
- * the {@link javax.management.MBeanServerFactory}. It could also be,
- * for instance, an instance of a subclass of {@link MBeanServerSupport},
- * or a custom object implementing the {@link MBeanServer} interface.
- * </p>
- *
- * <h4>Differences between {@code JMXNamespace} and {@code JMXDomain}</h4>
- *
- * <p>
- * A {@code JMXDomain} is a special kind of {@code JMXNamespace}.
- * A {@code JMXNamespace} such as {@code foo//} is triggered by an
- * {@code ObjectName} that begins with the string {@code foo//}, for example
- * {@code foo//bar:type=Baz}. A {@code JMXDomain} such as {@code foo} is
- * triggered by an {@code ObjectName} with that exact domain, for example
- * {@code foo:type=Baz}. A client can immediately see that an MBean is
- * handled by a {@code JMXNamespace} because of the {@code //} in the name.
- * A client cannot see whether a name such as {@code foo:type=Baz} is an
- * ordinary MBean or is handled by a {@code JMXDomain}.
- * </p>
- *
- * <p>
- * A {@linkplain MBeanServer#queryNames query} on the containing {@code
- * MBeanserver} will return all MBeans from the {@code JMXDomain} that match
- * the query. In particular, {@code queryNames(null, null)} will return all
- * MBeans including those from {@code JMXDomain} domains. On the other hand,
- * a query will not include MBeans from a {@code JMXNamespace} unless the
- * {@code ObjectName} pattern in the query starts with the name of that
- * namespace.
- * </p>
- *
- * <h4 id="security">Permission checks</h4>
- *
- * <p>
- * When a JMXDomain MBean is registered in a containing
- * MBean server created through the default {@link
- * javax.management.MBeanServerBuilder}, and if a {@link
- * SecurityManager SecurityManager} is
- * {@linkplain System#getSecurityManager() present}, the containing MBeanServer will
- * check an {@link javax.management.MBeanPermission} before invoking
- * any method on the {@linkplain #getSourceServer() source MBeanServer} of the
- * JMXDomain.
- * </p>
- *
- * <p>First, if there is no security manager ({@link
- * System#getSecurityManager()} is null), that containing
- * {@code MBeanServer} is free not to make any checks.
- * </p>
- *
- * <p>
- * Assuming that there is a security manager, or that the
- * implementation chooses to make checks anyway, the containing
- * {@code MBeanServer} will perform
- * {@link javax.management.MBeanPermission MBeanPermission} checks
- * for access to the MBeans in domain <i>X</i> handled by a {@code JMXDomain}
- * in the same way that it would do for MBeans registered in its own local
- * repository, and as <a href="../MBeanServer.html#security">described in
- * the MBeanServer interface</a>, with the following exceptions:
- * </p>
- *
- * <p>
- * For those permissions that require a {@code className}, the
- * <code>className</code> is the
- * string returned by {@link #getSourceServer() getSourceServer()}.
- * {@link MBeanServer#getObjectInstance(ObjectName)
- * getObjectInstance(mbeanName)}.
- * {@link javax.management.ObjectInstance#getClassName() getClassName()},
- * except for {@code createMBean} and {@code registerMBean} operations,
- * for which the permission checks are performed as follows:
- * </p>
- * <ul>
- * <li><p>For {@code createMBean} operations, the {@code className} of the
- * permission you need is the {@code className} passed as first parameter
- * to {@code createMBean}.</p>
- *
- * <li><p>For {@code registerMBean} operations, the {@code className} of the
- * permission you need is the name of the class of the mbean object, as
- * returned by {@code mbean.getClass().getClassName()}, where
- * {@code mbean} is the mbean reference passed as first parameter
- * to {@code registerMBean}.</p>
- *
- * <li><p>In addition, for {@code createMBean} and {@code registerMBean}, the
- * permission you need is checked with the {@linkplain ObjectName object name} of
- * the mbean that is passed as second parameter to the {@code createMBean} or
- * {@code registerMBean} operation.
- * </p>
- *
- * <li><p>Contrarily to what is done for regular MBeans registered in the
- * MBeanServer local repository, the containing MBeanServer will not
- * check the {@link javax.management.MBeanTrustPermission#MBeanTrustPermission(String)
- * MBeanTrustPermission("register")} against the protection domain
- * of the MBean's class. This check can be performed by the
- * {@linkplain #getSourceServer source MBean server} implementation,
- * if necessary.
- * </p>
- * </ul>
- *
- * <p>If a security check fails, the method throws {@link
- * SecurityException}.</p>
- *
- * <p>For methods that can throw {@link InstanceNotFoundException},
- * this exception is thrown for a non-existent MBean, regardless of
- * permissions. This is because a non-existent MBean has no
- * <code>className</code>.</p>
- *
- * All these checks are performed by the containing {@code MBeanServer},
- * before accessing the JMXDomain {@linkplain #getSourceServer source MBean server}.
- * The implementation of the JMXDomain {@linkplain #getSourceServer source MBean
- * server} is free to make any additional checks. In fact, if the JMXDomain
- * {@linkplain #getSourceServer source MBean server} is an {@code MBeanServer}
- * obtained through the {@link javax.management.MBeanServerFactory}, it will
- * again make permission checks as described in the
- * <a href="../MBeanServer.html#security">MBeanServer</a> interface.
- *
- * <p>See the <a href="../MBeanServer.html#security">MBeanServer</a> interface
- * for more details on permission checks.</p>
- *
- * @since 1.7
- */
-public class JMXDomain extends JMXNamespace {
-
-
- /**
- * This constant contains the value of the {@code type}
- * key used in defining a standard JMXDomain MBean object name.
- * By definition, a standard JMXDomain MBean object name must be of
- * the form:
- * <pre>
- * {@code "<domain>:"}+{@value javax.management.namespace.JMXDomain#TYPE_ASSIGNMENT}
- * </pre>
- */
- public static final String TYPE = "JMXDomain";
-
- /**
- * This constant contains the value of the standard
- * {@linkplain javax.management.ObjectName#getKeyPropertyListString() key
- * property list string} for JMXDomain MBean object names.
- * By definition, a standard JMXDomain MBean object name must be of
- * the form:
- * <pre>
- * {@code <domain>}+":"+{@value javax.management.namespace.JMXDomain#TYPE_ASSIGNMENT}
- * </pre>
- */
- public static final String TYPE_ASSIGNMENT = "type="+TYPE;
-
-
-
- /**
- * Creates a new instance of JMXDomain. The MBeans contained in this
- * domain are handled by the {@code virtualServer} object given to
- * this constructor. Frequently, this will be an instance of
- * {@link MBeanServerSupport}.
- * @param virtualServer The virtual server that acts as a container for
- * the MBeans handled by this JMXDomain object. Frequently, this will
- * be an instance of {@link MBeanServerSupport}
- * @see JMXNamespace#JMXNamespace(MBeanServer)
- */
- public JMXDomain(MBeanServer virtualServer) {
- super(virtualServer);
- }
-
- /**
- * Return the name of domain handled by this JMXDomain.
- * @return the domain handled by this JMXDomain.
- * @throws IOException - if the domain cannot be determined,
- * for instance, if the MBean is not registered yet.
- */
- @Override
- public final String getDefaultDomain() {
- final ObjectName name = getObjectName();
- if (name == null)
- throw new IllegalStateException("DefaultDomain is not yet known");
- final String dom = name.getDomain();
- return dom;
- }
-
- /**
- * Returns a singleton array, containing the only domain handled by
- * this JMXDomain object. This is
- * {@code new String[] {getDefaultDomain()}}.
- * @return the only domain handled by this JMXDomain.
- * @throws IOException if the domain cannot be determined,
- * for instance, if the MBean is not registered yet.
- * @see #getDefaultDomain()
- */
- @Override
- public final String[] getDomains() {
- return new String[] {getDefaultDomain()};
- }
-
- /**
- * This method returns the number of MBeans in the domain handled
- * by this JMXDomain object. The default implementation is:
- * <pre>
- * getSourceServer().queryNames(
- * new ObjectName(getObjectName().getDomain()+":*"), null).size();
- * </pre>
- * If this JMXDomain is not yet registered, this method returns 0.
- * Subclasses can override the above behavior and provide a better
- * implementation.
- * <p>
- * The getMBeanCount() method is called when computing the number
- * of MBeans in the {@linkplain #getMBeanServer() containing MBeanServer}.
- * @return the number of MBeans in this domain, or 0.
- */
- @Override
- public Integer getMBeanCount() {
- final ObjectName name = getObjectName();
- if (name == null) return 0;
- try {
- return getSourceServer().
- queryNames(ObjectName.WILDCARD.withDomain(name.getDomain()),
- null).size();
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException("Unexpected exception: "+x,x);
- }
- }
-
-
-
- /**
- * Return a canonical handler name for the provided local
- * <var>domain</var> name, or null if the provided domain name is
- * {@code null}.
- * If not null, the handler name returned will be
- * {@code domain+":type="+}{@link #TYPE TYPE}, for example
- * {@code foo:type=JMXDomain}.
- * @param domain A domain name
- * @return a canonical ObjectName for a domain handler.
- * @throws IllegalArgumentException if the provided
- * <var>domain</var> is not valid - e.g it contains "//".
- */
- public static ObjectName getDomainObjectName(String domain) {
- if (domain == null) return null;
- if (domain.contains(NAMESPACE_SEPARATOR))
- throw new IllegalArgumentException("domain contains " +
- NAMESPACE_SEPARATOR+": "+domain);
- return ObjectName.valueOf(domain, "type", TYPE);
- }
-
-
- /**
- * Validate the ObjectName supplied to preRegister.
- * This method is introduced to allow standard subclasses to use
- * an alternate naming scheme. For instance - if we want to
- * reuse JMXNamespace in order to implement sessions...
- * It is however only available for subclasses in this package.
- **/
- @Override
- ObjectName validateHandlerName(ObjectName suppliedName) {
- if (suppliedName == null)
- throw new IllegalArgumentException("Must supply a valid name");
- final String dirName = JMXNamespaces.
- normalizeNamespaceName(suppliedName.getDomain());
- final ObjectName handlerName = getDomainObjectName(dirName);
- if (!suppliedName.equals(handlerName))
- throw new IllegalArgumentException("invalid name space name: "+
- suppliedName);
-
- return suppliedName;
- }
-
- /**
- * This method is called by the JMX framework to register a
- * NotificationListener that will forward {@linkplain
- * javax.management.MBeanServerNotification mbean server notifications}
- * through the delegate of the {@linkplain #getMBeanServer()
- * containing MBeanServer}.
- * The default implementation of this method is to call
- * <pre>
- * getSourceServer().addNotificationListener(
- * MBeanServerDelegate.DELEGATE_NAME, listener, filter, null);
- * </pre>
- * Subclasses can redefine this behavior if needed. In particular,
- * subclasses can send their own instances of {@link
- * javax.management.MBeanServerNotification} by calling
- * {@code listener.handleNotification()}.
- *
- * @param listener The MBeanServerNotification listener for this domain.
- * @param filter A notification filter.
- */
- public void addMBeanServerNotificationListener(
- NotificationListener listener, NotificationFilter filter) {
- try {
- getSourceServer().addNotificationListener(
- MBeanServerDelegate.DELEGATE_NAME, listener, filter, null);
- } catch(InstanceNotFoundException x) {
- throw new UnsupportedOperationException(
- "Unexpected exception: " +
- "Emission of MBeanServerNotification disabled.", x);
- }
- }
-
- /**
- * This method is called by the JMX framework to remove the
- * NotificationListener that was added with {@link
- * #addMBeanServerNotificationListener addMBeanServerNotificationListener}.
- * The default implementation of this method is to call
- * <pre>
- * getSourceServer().removeNotificationListener(
- * MBeanServerDelegate.DELEGATE_NAME, listener);
- * </pre>
- * Subclasses can redefine this behavior if needed.
- *
- * @param listener The MBeanServerNotification listener for this domain.
- * @throws ListenerNotFoundException if the listener is not found.
- */
- public void removeMBeanServerNotificationListener(
- NotificationListener listener)
- throws ListenerNotFoundException {
- try {
- getSourceServer().removeNotificationListener(
- MBeanServerDelegate.DELEGATE_NAME, listener);
- } catch(InstanceNotFoundException x) {
- throw new UnsupportedOperationException(
- "Unexpected exception: " +
- "Emission of MBeanServerNotification disabled.", x);
- }
- }
-
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,666 +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 javax.management.namespace;
-
-
-import java.io.IOException;
-
-import java.util.UUID;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-/**
- * MBean Servers can be federated into a single hierarchical name space:
- * A JMXNamespace is an MBean that handles a sub name space in that
- * hierarchical name space.
- * <p>
- * A name space is created simply by registering a {@code JMXNamespace}
- * MBean in the MBean Server. The name of the created name space is defined
- * by the {@linkplain JMXNamespaces#getNamespaceObjectName name of the JMXNamespace}
- * that handles it. A name space is equivalent to
- * an MBean Server within an MBean Server. When creating a {@code JMXNamespace},
- * the MBean Server within is passed to the constructor.
- * </p>
- * <p>
- * The {@code JMXNamespace} class is the base class for implementing
- * all name space handlers. All name space handlers must be instances of
- * {@code JMXNamespace} or a subclass of it.
- * </p>
- * <p>
- * A concrete example of a {@code JMXNamespace} MBean subclass
- * is the {@link JMXRemoteNamespace JMXRemoteNamespace} MBean which
- * is able to mirror all MBeans contained in a remote MBean server known by its
- * {@link javax.management.remote.JMXServiceURL}.
- * </p>
- * <p>
- * You can create a local namespace by supplying a newly created MBean Server
- * to an instance of {@code JMXNamespace}. For instance:
- * <pre>
- * final String namespace = "foo";
- * final ObjectName namespaceName = {@link JMXNamespaces#getNamespaceObjectName
- * JMXNamespaces.getNamespaceObjectName(namespace)};
- * server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()),
- * namespaceName);
- * </pre>
- * </p>
- * <p>
- * <u>Note:</u> A JMXNamespace MBean cannot be registered
- * simultaneously in two different
- * MBean servers, or indeed in the same MBean Server with two
- * different names. It is however possible to give the same MBeanServer
- * instance to two different JMXNamespace MBeans, and thus create a graph
- * rather than a tree.
- * </p>
- *
- * <p>To view the content of a namespace, you will usually use an
- * instance of {@link JMXNamespaceView}. For instance, given the
- * namespace {@code "foo"} created above, you would do:
- * </p>
- * <pre>
- * final JMXNamespaceView view = new JMXNamespaceView(server);
- * System.out.println("List of namespaces: "+Arrays.toString({@link JMXNamespaceView#list() view.list()}));
- *
- * final JMXNamespaceView foo = {@link JMXNamespaceView#down view.down("foo")};
- * System.out.println({@link JMXNamespaceView#where() foo.where()}+" contains: " +
- * {@link JMXNamespaceView#getMBeanServerConnection foo.getMBeanServerConnection()}.queryNames(null,null));
- * </pre>
- *
- * <h2 id="PermissionChecks">JMX Namespace Permission Checks</h2>
- *
- * <p>A special {@link JMXNamespacePermission} is defined to check access
- * to MBean within namespaces.</p>
- * <p>When a JMXNamespace MBean is registered in an
- * MBean server created through the default {@link
- * javax.management.MBeanServerBuilder}, and if a {@link
- * SecurityManager SecurityManager} is
- * {@linkplain System#getSecurityManager() present}, the MBeanServer will
- * check a {@link JMXNamespacePermission} before invoking
- * any method on the {@linkplain #getSourceServer source MBeanServer} of the
- * JMXNamespace.
- * {@linkplain JMXNamespacePermission JMX Namespace Permissions} are similar to
- * {@linkplain javax.management.MBeanPermission MBean Permissions}, except
- * that you usually cannot specify an MBean class name. You can however
- * specify object name patterns - which will allow you for example to only grant
- * permissions for MBeans having a specific {@code type=<MBeanType>} key
- * in their object name.
- * <p>
- * Another difference is that {@link JMXNamespacePermission
- * JMXNamespacePermission} also specifies from which namespace and which
- * MBean server the permission is granted.
- * </p>
- * <p>In the rest of this document, the following terms are used:</p>
- * <ul>
- * <li id="MBeanServerName"><p>{@code server name} is the
- * <a href="../MBeanServerFactory.html#MBeanServerName">name of the
- * MBeanServer</a> in which the permission is granted.
- * The name of an {@code MBeanServer} can be obtained by calling {@link
- * javax.management.MBeanServerFactory#getMBeanServerName
- * MBeanServerFactory.getMBeanServerName(mbeanServer)}
- * </p>
- * <li id="NamespaceName"><p>{@code namespace} is the name of the namespace
- * in the <a href="#MBeanServerName">named MBean server</a> for which the
- * permission is granted. It doesn't contain any
- * {@link JMXNamespaces#NAMESPACE_SEPARATOR namespace separator}.
- * </p>
- * <li id="MBeanName"><p>{@code mbean} is the name
- * of the MBean in that {@code namespace}. This is the name of the MBean
- * in the namespace's {@link JMXNamespace#getSourceServer() source mbean server}.
- * It might contain no, one, or several {@link
- * JMXNamespaces#NAMESPACE_SEPARATOR namespace separators}.
- * </p>
- * </ul>
- *
- * <p>For instance let's assume that some piece of code calls:</p>
- * <pre>
- * final MBeanServer mbeanServer = ...;
- * final ObjectName name = new ObjectName("a//b//c//D:k=v");
- * mbeanServer.getAttribute(name,"Foo");
- * </pre>
- * <p>
- * Assuming that there is a security manager, or that the
- * implementation chooses to make checks anyway, the checks that will
- * be made in that case are:
- * </p>
- * <ol>
- * <li id="check1">
- * <code>JMXNamespacePermission(mbeanServerName, "Foo", "<b>a//</b>b//c//D:k=v",
- * "getAttribute")</code>
- * (where {@code mbeanServerName=MBeanServerFactory.getMBeanServerName(mbeanServer)},
- * <code>namespace="<b>a</b>"</code>, and {@code mbean="b//c//D:k=v"})
- * </li>
- * <li id="check2">and in addition if namespace {@code "a"} is local,
- * <code>JMXNamespacePermission(aSourceServerName,"Foo","<b>b//</b>c//D:k=v",
- * "getAttribute")}</code>
- * (where
- * {@code aSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(a))},
- * <code>namespace="<b>b</b>"</code>, and {@code mbean="c//D:k=v"}),
- * </li>
- * <li id="check3">and in addition if namespace {@code "b"} is also local,
- * <code>JMXNamespacePermission(bSourceServerName,"Foo","<b>c//</b>D:k=v",
- * "getAttribute")}</code>
- * (where
- * {@code bSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(b))},
- * <code>namespace="<b>c</b>"</code>, and {@code mbean="D:k=v"}),
- * </li>
- * <li id="check4">and in addition if the source mbean server of namespace
- * {@code "c"} is a also a local MBeanServer in this JVM,
- * {@code MBeanPermission(cSourceServerName,<className(D:k=v)>,"Foo","D:k=v","getAttrinute")},
- * (where
- * {@code cSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(c))}).
- * </li>
- * </ol>
- * <p>For any of these MBean servers, if no name was supplied when
- * creating that MBeanServer the {@link JMXNamespacePermission} is
- * created with an {@code mbeanServerName} equal to
- * {@value javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}.
- * </p>
- * <p>If the namespace {@code a} is in fact a remote {@code MBeanServer},
- * for instance because namespace {@code a} is implemented by a {@link
- * JMXRemoteNamespace} pointing to a distant MBeanServer located in
- * another JMX agent, then checks <a href="#check2">2</a>,
- * <a href="#check3">3</a>, and <a href="#check4">4</a> will not
- * be performed in the local JVM. They might or might not be performed in
- * the remote agent, depending on how access control and permission
- * checking are configured in the remote agent, and how authentication
- * is configured in the connector used by the {@link
- * JMXRemoteNamespace}.
- * </p>
- * <p>In all cases, {@linkplain JMXNamespacePermission JMX Namespace Permissions}
- * are checked as follows:</p>
- * <p>First, if there is no security manager ({@link
- * System#getSecurityManager()} is null), then an implementation of
- * of MBeanServer that supports JMX namespaces is free not to make any
- * checks.</p>
- *
- * <p>Assuming that there is a security manager, or that the
- * implementation chooses to make checks anyway, the checks are made
- * as detailed below.</p>
- *
- * <p>If a security check fails, the method throws {@link
- * SecurityException}.</p>
- *
- * <ul>
- *
- * <li><p>For the {@link MBeanServer#invoke invoke} method, the caller's
- * permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <operation name>, <namespace>//<mbean>, "invoke")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#getAttribute getAttribute} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <attribute>, <namespace>//<mbean>, "getAttribute")}.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#getAttributes getAttributes} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <null>, <namespace>//<mbean>, "getAttribute")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * Additionally, for each attribute <em>att</em> in the {@link
- * javax.management.AttributeList}, if the caller's permissions do not
- * imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <em>att</em>,
- * <namespace>//<mbean>, "getAttribute")}, the
- * MBean server will behave as if that attribute had not been in the
- * supplied list.</p>
- *
- * <li><p>For the {@link MBeanServer#setAttribute setAttribute} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <attrName>, <namespace>//<mbean>, "setAttribute")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace, and
- * <code>attrName</code> is {@link javax.management.Attribute#getName()
- * attribute.getName()}.</p>
- *
- * <li><p>For the {@link MBeanServer#setAttributes setAttributes} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, "setAttribute")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * Additionally, for each attribute <em>att</em> in the {@link
- * javax.management.AttributeList}, if the caller's permissions do not
- * imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <em>att</em>, <namespace>//<mbean>, "setAttribute")},
- * the MBean server will behave as if that attribute had not been in the
- * supplied list.</p>
- *
- * <li><p>For the <code>addNotificationListener</code> methods,
- * the caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "addNotificationListener")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the <code>removeNotificationListener</code> methods,
- * the caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "removeNotificationListener")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#getMBeanInfo getMBeanInfo} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "getMBeanInfo")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#getObjectInstance getObjectInstance} method,
- * the caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "getObjectInstance")},
- * where <a href="#MBeanServerName">mbean server name/a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#isInstanceOf isInstanceOf} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "isInstanceOf")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#queryMBeans queryMBeans} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, null,
- * "queryMBeans")}.
- * Additionally, for each MBean {@code mbean} that matches {@code pattern},
- * if the caller's permissions do not imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "queryMBeans")}, the
- * MBean server will behave as if that MBean did not exist.</p>
- *
- * <p>Certain query elements perform operations on the MBean server.
- * However these operations are usually performed by the MBeanServer at the
- * bottom of the namespace path, and therefore, do not involve any
- * {@link JMXNamespacePermission} permission check. They might involve
- * {@link javax.management.MBeanPermission} checks depending on how security
- * in the JVM in which the bottom MBeanServer resides is implemented.
- * See {@link javax.management.MBeanServer} for more details.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#queryNames queryNames} method, the checks
- * are the same as for <code>queryMBeans</code> except that
- * <code>"queryNames"</code> is used instead of
- * <code>"queryMBeans"</code> in the <code>JMXNamespacePermission</code>
- * objects. Note that a <code>"queryMBeans"</code> permission implies
- * the corresponding <code>"queryNames"</code> permission.</p>
- *
- * <li><p>For the {@link MBeanServer#getClassLoader getClassLoader} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<loaderName>,
- * "getClassLoader")},
- * where <a href="#MBeanServerName">mbean server name/a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">loaderName</a> is the name of the ClassLoader MBean
- * which is accessed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#getClassLoaderFor getClassLoaderFor} method,
- * the caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "getClassLoaderFor")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action
- * is performed, in that namespace.
- * </p>
- *
- * <li><p>For the {@link MBeanServer#registerMBean registerMBean} method, the
- * caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>,
- * "registerMBean")}. Here
- * <code>class name</code> is the string returned by {@code
- * obj.getClass().getName()} where {@code obj} is the mbean reference,
- * <a href="#MBeanServerName"mbean server name/a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean which is being
- * registered, relative to that namespace.
- *
- * <li><p>For the <code>createMBean</code> methods, the caller's
- * permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>,
- * "instantiate")} and
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>,
- * "registerMBean")}, where
- * <code>class name</code> is the string passed as first argument to the {@code
- * createMBean} method,
- * <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean which is being
- * created, relative to that namespace.
- *
- * <li><p>For the {@link MBeanServer#unregisterMBean unregisterMBean} method,
- * the caller's permissions must imply {@link
- * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String)
- * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>,
- * "unregisterMBean")},
- * where <a href="#MBeanServerName">mbean server name</a> is the name of the
- * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of
- * <a href="#NamespaceName">namespace</a> is registered, and
- * <a href="#MBeanName">mbean</a> is the name of the MBean on which is
- * being unregistered, relative to that namespace.
- * </p>
- * </ul>
- * </p>
- * <p>It must be noted that if all namespaces are local, and all
- * local namespaces are implemented by regular MBean servers, that is, there
- * are no {@linkplain MBeanServerSupport Virtual Namespaces}, then
- * simple {@linkplain javax.management.MBeanPermission MBean Permission}
- * checks might be enough to secure an application.
- * In that case, it is possible to specify the following {@link
- * JMXNamespacePermission} permission in the policy file, which implies all
- * other JMX namespace permissions:
- * </p>
- * <pre>
- * permission javax.management.namespace.JMXNamespacePermission "*::*[]", "*";
- * </pre>
- *
- * @since 1.7
- */
-public class JMXNamespace
- implements JMXNamespaceMBean, MBeanRegistration {
-
- /**
- * The standard value of the {@code type}
- * property key that must be used to construct valid {@link
- * JMXNamespaceMBean} ObjectNames.<br>
- * This is {@value #TYPE}.
- **/
- public static final String TYPE = "JMXNamespace";
-
- /**
- * The {@link ObjectName#getKeyPropertyListString keyPropertyListString}
- * that must be used to construct valid {@link JMXNamespaceMBean}
- * ObjectNames.<br>
- * This is
- * <code>{@value #TYPE_ASSIGNMENT}</code>.
- **/
- public static final String TYPE_ASSIGNMENT = "type="+TYPE;
-
- private volatile MBeanServer mbeanServer; // the mbean server in which
- // this MBean is registered.
- private volatile ObjectName objectName; // the ObjectName of this MBean.
- private final MBeanServer sourceServer; // the MBeanServer within = the
- // name space (or the MBean server
- // that contains it).
- private final String uuid;
-
- /**
- * Creates a new JMXNamespace implemented by means of an MBean Server.
- * A namespace is equivalent to an MBeanServer within an MBean Server.
- * The {@code sourceServer} provided to this constructor is the MBean Server
- * within.
- * @param sourceServer the MBean server that implemented by this namespace.
- * @see #getSourceServer
- */
- public JMXNamespace(MBeanServer sourceServer) {
- this.sourceServer = sourceServer;
- this.uuid = UUID.randomUUID().toString();
- }
-
- /**
- * This method is part of the {@link MBeanRegistration} interface.
- * The {@link JMXNamespace} class uses the {@link MBeanRegistration}
- * interface in order to get a reference to the MBean server in which it is
- * registered. It also checks the validity of its own ObjectName.
- * <p>
- * This method is called by the MBean server.
- * Application classes should never call this method directly.
- * <p>
- * If this method is overridden, the overriding method should call
- * {@code super.preRegister(server,name)}.
- * @see MBeanRegistration#preRegister MBeanRegistration
- * @see JMXNamespaces#getNamespaceObjectName getNamespaceObjectName
- * @param name The object name of the MBean. <var>name</var> must be a
- * syntactically valid JMXNamespace name, as returned by
- * {@link JMXNamespaces#getNamespaceObjectName(java.lang.String)
- * getNamespaceObjectName(namespace)}.
- * @return The name under which the MBean is to be registered.
- * @throws IllegalArgumentException if the name supplied is not valid.
- * @throws Exception can be thrown by subclasses.
- */
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- // need to synchronize to protect against multiple registration.
- synchronized(this) {
- if (objectName != null && ! objectName.equals(name))
- throw new IllegalStateException(
- "Already registered under another name: " + objectName);
- objectName = validateHandlerName(name);
- mbeanServer = server;
- }
- return name;
- }
-
- /**
- * Validate the ObjectName supplied to preRegister.
- * This method is introduced to allow standard subclasses to use
- * an alternate naming scheme. For instance - if we want to
- * reuse JMXNamespace in order to implement sessions...
- * It is however only available for subclasses in this package.
- **/
- ObjectName validateHandlerName(ObjectName suppliedName) {
- if (suppliedName == null)
- throw new IllegalArgumentException("Must supply a valid name");
- final String dirName = JMXNamespaces.
- normalizeNamespaceName(suppliedName.getDomain());
- final ObjectName handlerName =
- JMXNamespaces.getNamespaceObjectName(dirName);
- if (!suppliedName.equals(handlerName))
- throw new IllegalArgumentException("invalid name space name: "+
- suppliedName);
- return suppliedName;
- }
-
- /**
- * This method is part of the {@link MBeanRegistration} interface.
- * The {@link JMXNamespace} class uses the {@link MBeanRegistration}
- * interface in order to get a reference to the MBean server in which it is
- * registered.
- * <p>
- * This method is called by the MBean server. Application classes should
- * not call this method directly. Subclasses are free to override this
- * method with their own specific behavior - but the overriding method
- * shoud still call {@code super.postRegister(registrationDone)}.
- * @see MBeanRegistration#postRegister MBeanRegistration
- */
- public void postRegister(Boolean registrationDone) {
- // nothing to do
- }
-
- /**
- * This method is part of the {@link MBeanRegistration} interface.
- * The {@link JMXNamespace} class uses the {@link MBeanRegistration}
- * interface in order to get a reference to the MBean server in which it is
- * registered.
- * <p>
- * This method is called by the MBean server. Application classes should
- * not call this method directly. Subclasses are free to override this
- * method with their own specific behavior - but the overriding method
- * shoud still call {@code super.preDeregister()}.
- * @see MBeanRegistration#preDeregister MBeanRegistration
- */
- public void preDeregister() throws Exception {
- // nothing to do
- }
-
- /**
- * This method is part of the {@link MBeanRegistration} interface.
- * It allows the {@code JMXNamespace} MBean to perform any operations
- * needed after having been unregistered in the MBean server.
- * <p>
- * This method is called by the MBean server. Application classes should
- * not call this method directly. If a subclass overrides this
- * method, the overriding method shoud call {@code super.postDeregister()}.
- * @see MBeanRegistration#postDeregister MBeanRegistration
- */
- public void postDeregister() {
- // need to synchronize to protect against multiple registration.
- synchronized(this) {
- mbeanServer = null;
- objectName = null;
- }
- }
-
-
- /**
- * Returns the MBeanServer in which this MBean is registered,
- * or null. Chiefly of interest for subclasses.
- * @return the MBeanServer supplied to {@link #preRegister}.
- **/
- public final MBeanServer getMBeanServer() {
- return mbeanServer;
- }
-
- /**
- * Returns the MBeanServer that contains or emulates the source
- * namespace. When a JMXNamespace MBean is registered in an
- * MBean server created through the default {@link
- * javax.management.MBeanServerBuilder}, the MBeanServer will
- * check {@link JMXNamespacePermission} before invoking
- * any method on the source MBeanServer of the JMXNamespace.
- * See <a href="#PermissionChecks">JMX Namespace Permission Checks</a>
- * above.
- * @return an MBeanServer view of the source namespace
- **/
- public MBeanServer getSourceServer() {
- return sourceServer;
- }
-
- /**
- * Returns the ObjectName with which this MBean was registered,
- * or null. Chiefly of interest for subclasses.
- * @return the ObjectName supplied to {@link #preRegister}.
- **/
- public final ObjectName getObjectName() {
- return objectName;
- }
-
- /**
- * HandlerName used in traces.
- **/
- String getHandlerName() {
- final ObjectName name = getObjectName();
- if (name != null) return name.toString();
- return this.toString();
- }
-
- /**
- * In this class, this method returns {@link #getSourceServer
- * getSourceServer()}.{@link javax.management.MBeanServer#getMBeanCount
- * getMBeanCount()}.
- * <br>This default behaviour may be redefined in subclasses.
- * @throws java.io.IOException can be thrown by subclasses.
- */
- public Integer getMBeanCount() throws IOException {
- return getSourceServer().getMBeanCount();
- }
-
- /**
- * In this class, this method returns {@link #getSourceServer
- * getSourceServer()}.{@link javax.management.MBeanServer#getDomains
- * getDomains()}.
- * <br>This default behaviour may be redefined in subclasses.
- * @throws java.io.IOException can be thrown by subclasses.
- */
- public String[] getDomains() throws IOException {
- return getSourceServer().getDomains();
- }
-
- /**
- * In this class, this method returns {@link #getSourceServer
- * getSourceServer()}.{@link javax.management.MBeanServer#getDefaultDomain
- * getDefaultDomain()}.
- * <br>This default behaviour may be redefined in subclasses.
- * @throws java.io.IOException can be thrown by subclasses.
- */
- public String getDefaultDomain() throws IOException {
- return getSourceServer().getDefaultDomain();
- }
-
- public final String getUUID() {
- return uuid;
- }
-
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespaceMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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 javax.management.namespace;
-
-import java.io.IOException;
-import java.util.UUID;
-
-/**
- * A {@link JMXNamespace} is an MBean that handles a name space in the
- * MBeanServer hierarchical name space.
- * @see JMXNamespace
- * @since 1.7
- */
-public interface JMXNamespaceMBean {
-
- // Note: since getDomains(), getDefaultDomain(), and getMBeanCount()
- // don't take any ObjectName parameters, the only efficient way
- // to get these data is to call the corresponding method on the
- // JMXNamespaceMBean that handles the name space.
- //
- // We need these methods to implement 'cd' (JMXNamespaces.narrowToNamespace)
- // correctly.
- //
-
- /**
- * Returns the list of domains currently implemented in the name space
- * handled by this {@link JMXNamespace}.
- * @throws IOException if the domain list cannot be obtained due to
- * I/O problems (communication failures etc...).
- * @return the list of domains currently implemented in the name space
- * handled by this {@link JMXNamespace}.
- * @see javax.management.MBeanServerConnection#getDomains
- * MBeanServerConnection.getDomains
- **/
- public String[] getDomains() throws IOException;
-
- /**
- * Returns the default domain for the name space handled by
- * this {@link JMXNamespace}.
- * @throws IOException if the default domain cannot be obtained due to
- * I/O problems (communication failures etc...).
- * @return the default domain for the name space handled by
- * this {@link JMXNamespace}.
- * @see javax.management.MBeanServerConnection#getDefaultDomain
- * MBeanServerConnection.getDefaultDomain
- **/
- public String getDefaultDomain() throws IOException;
-
- /**
- * Returns the number of MBeans registered in the name space handled by
- * this {@link JMXNamespace}.
- *
- * @return the number of MBeans registered in the name space handled by
- * this {@link JMXNamespace}.
- *
- * @throws IOException if the MBean count cannot be obtained due to
- * I/O problems (communication failures etc...).
- * @see javax.management.MBeanServerConnection#getMBeanCount
- * MBeanServerConnection.getMBeanCount
- */
- public Integer getMBeanCount() throws IOException;
-
- /**
- * Returns a {@link java.util.UUID UUID string} which uniquely identifies
- * this {@linkplain JMXNamespace} MBean.
- * This information can be used to detect loops in the JMX name space graph.
- * @return A unique ID identifying this MBean.
- * @throws IOException if the MBean UUID cannot be obtained due to
- * I/O problems (communication failures etc...).
- */
- public String getUUID() throws IOException;
-
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1446 +0,0 @@
-/*
- * Copyright 2002-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 javax.management.namespace;
-
-import javax.management.*;
-import com.sun.jmx.mbeanserver.Util;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.security.Permission;
-
-/**
- * <p>A permission controlling access to MBeans located in namespaces.
- * If a security manager has been set using {@link
- * System#setSecurityManager}, most operations on an MBean mounted in a
- * namespace require that the caller's permissions imply a
- * JMXNamespacePermission appropriate for the operation.
- * This is described in detail in the
- * documentation for the
- * <a href="JMXNamespace.html#PermissionChecks">JMXNamespace</a>
- * class.</p>
- *
- * <p>As with other {@link Permission} objects,
- * a JMXNamespacePermission can represent either a permission that
- * you <em>have</em> or a permission that you <em>need</em>.
- * When a sensitive operation is being checked for permission,
- * a JMXNamespacePermission is constructed
- * representing the permission you need. The operation is only
- * allowed if the permissions you have {@linkplain #implies imply} the
- * permission you need.</p>
- *
- * <p>A JMXNamespacePermission contains four items of information:</p>
- *
- * <ul>
- *
- * <li id="Action"><p>The <em>action</em>.</p>
- * <p>For a permission you need,
- * this is one of the actions in the list <a
- * href="#action-list">below</a>. For a permission you have, this is
- * a comma-separated list of those actions, or <code>*</code>,
- * representing all actions.</p>
- *
- * <p>The action is returned by {@link #getActions()}.</p>
- *
- * <li id="MBeanServerName"><p>The <em>MBean Server name</em>.</p>
- *
- * <p>For a permission you need, this is the {@linkplain
- * javax.management.MBeanServerFactory#getMBeanServerName
- * name of the MBeanServer}
- * from which the <a href="#MBeanName">MBean</a> is accessed.</p>
- *
- * <p>For a permission you have, this is either the {@linkplain
- * javax.management.MBeanServerFactory#getMBeanServerName
- * name of the MBeanServer} from which the <a href="#MBeanName">MBean</a>
- * for which you have this permission is accessed,
- * or a pattern against which that MBean Server name will be matched.<br>
- * An {@code mbeanServername} pattern can also be empty, or the single
- * character {@code "*"}, both of which match any {@code MBeanServer} name.
- * The string {@code "-"} doesn't match any MBeanServer name.
- * </p>
- *
- * <p>Example:</p>
- * <pre>
- * // grant permission to invoke the operation "stop" on any MBean
- * // whose name matches "a//**//*:type=JMXConnectorServer" when
- * // accessed from any MBeanServer whose name matches myapp.*"
- * permission javax.management.namespace.JMXNamespacePermission "myapp.*::stop[a//**//*:type=JMXConnectorServer]", "invoke";
- * </pre>
- *
- * <li id="Member"><p>The <em>member</em>.</p>
- *
- * <p>For a permission you need, this is the name of the attribute or
- * operation you are accessing. For operations that do not reference
- * an attribute or operation, the member is null.</p>
- *
- * <p>For a permission you have, this is either the name of an attribute
- * or operation you can access, or it is empty or the single character
- * "<code>*</code>", both of which grant access to any member.</p>
- *
- * <p>There is a special case for actions {@code registerMBean} and
- * {@code instantiate}, where for a permission you need, {@code member}
- * indicates the name of the class for which you are trying
- * to create, instantiate, or register an MBean instance. For a
- * permission you have, it is a pattern that will be matched against
- * the full class name of the MBean being created, instantiated, or
- * registered.
- * </p>
- *
- *
- * <li id="MBeanName"><p>The <em>object name</em>.</p>
- *
- * <p>For a permission you need, this is the {@link ObjectName} of the
- * MBean you are accessing. It is of the form {@code <namespace>//<mbean name>}
- * where {@code <namespace>} is the name of the name space for which the
- * permission is checked, and {@code <mbean name>} is the name of the MBean
- * within that namespace.
- * <br>
- * For operations that do not reference a
- * single MBean, the <em>object name</em> is null. It is never an object
- * name pattern.
- * </p>
- *
- * <p>For a permission you have, this is the {@link ObjectName} of the
- * MBean or MBeans you can access. It is of the form
- * {@code <namespace>//<mbean name>}
- * where {@code <namespace>} is the name of the name space for which the
- * permission is checked, and
- * {@code <mbean name>} is the name of the MBean
- * within that namespace. Both {@code <namespace>} and {@code <mbean name>}
- * can be patterns. The <em>object name</em>
- * may also be empty, which grants access to all MBeans whatever their
- * name and namespace.
- * When included in a namespace path the special path element
- * <code>**</code> matches any number of sub namespaces
- * recursively, but only if used as a complete namespace path element,
- * as in <code>**//b//c//D:k=v</code> or <code>a//**//c//D:k=v</code>
- * - see ObjectName <a href="../ObjectName.html#metawildcard">documentation</a>
- * for more details.
- * </p>
- *
- *
- * </ul>
- *
- * <p>If you have a JMXNamespacePermission, it allows operations only
- * if all four of the items match.</p>
- *
- * <p>The <a href="#MBeanServerName">MBeanServer name</a>,
- * <a href="#Member">member</a>, and <a href="#MBeanName">object name</a>
- * can be written together
- * as a single string, which is the <em>name</em> of this permission.
- * The name of the permission is the string returned by {@link
- * java.security.Permission#getName() getName()}.
- * The format of the string is:</p>
- *
- * <blockquote>
- * {@code <mbean server name>::<member>[<namespace>//<mbean name>]}
- * </blockquote>
- *
- * <p>
- * The {@code <mbean server name>} is optional. If omitted, {@code "*"} is
- * assumed, and these three permission names
- * are thus equivalent:
- * </p>
- * <blockquote>
- * {@code *::<member>[<namespace>//<mbean name>]}<br>
- * {@code ::<member>[<namespace>//<mbean name>]}<br>
- * {@code <member>[<namespace>//<mbean name>]}<br>
- * </blockquote>
- * <p>
- * The {@code <namespace>//<mbean name>} string can be in the form
- * of a traditional ObjectName
- * pattern - meaning that <code>?</code> will match any single
- * character, and <code>*</code> will match any sequence of characters,
- * except {@value
- * javax.management.namespace.JMXNamespaces#NAMESPACE_SEPARATOR}
- * In addition, when included in a namespace path the special
- * path element <code>**</code> matches any number of sub namespaces
- * recursively.
- * A {@code <namespace>//<mbean name>} string of the form
- * <code>**//*:*</code> thus means that the permission is
- * granted for all MBeans in all namespaces, recursively (see
- * <a href="#metawildcard">below</a> for more details.
- * </p>
- * <p>Namespace permission checking may be tricky to configure, depending
- * on whether the namespaces crossed to reach the MBean are local or
- * remote.<br>
- * For instance, let <code>a//b//D:k=v</code> be an MBean exposing an
- * attribute <code>Foo</code>.
- * If namespace <code>a</code> is a plain JMXNamespace pointing to
- * a local MBeanServer in the same JVM, then the permissions you need
- * to get the attribute <code>Foo</code> will be:
- * </p>
- * <pre>
- * // granting permission to access attribute 'Foo' of MBean a//b//D:k=v
- * // from MBeanServer named 'srv1'
- * // This permission will be checked by the MBeanServer that contains 'a'.
- * srv1::Foo[a//b//D:k=v]
- *
- * // Since a is local, you also need the following additional permission,
- * // which will be checked by the MBeanServer 'srv2' that contains 'b':
- * //
- * // granting permission to access attribute 'Foo' of MBean b//D:k=v from
- * // 'srv2'
- * srv2::Foo[b//D:k=v]
- * </pre>
- * <p>On the other hand, if namespace <code>a</code> is a JMXRemoteNamespace
- * pointing to an MBeanServer in a remote JVM, then the only permission you
- * need to get the attribute <code>Foo</code> will be:
- * </p>
- * <pre>
- * // granting permission to access attribute 'Foo' of MBean a//b//D:k=v
- * // from 'srv1'
- * srv1::Foo[a//b//D:k=v]
- * </pre>
- * <p>The namespace <code>b</code> resides in the remote JVM, and
- * therefore the permissions concerning access to MBeans from
- * namespace 'b' will only be checked in the remote JVM, if that JVM is
- * configured to do so.
- * </p>
- *
- * <p>The {@code <mbean name>} is written using the usual syntax for {@link
- * ObjectName}. It may contain any legal characters, including
- * <code>]</code>. It is terminated by a <code>]</code> character
- * that is the last character in the string.
- * </p>
- * <p>Below are some examples of permission names:</p>
- * <pre>
- * // allows access to Foo in 'a//b//*:*' from any MBeanServer in the JVM.
- * Foo[a//b//*:*]
- *
- * // allows access to Foo in all subnamespaces of 'a//b', but only for
- * // MBeanServers whose name matches 'myapp.*'
- * myapp.*::Foo[a//b//**//*:*]
- *
- * // allows access to Foo from all namespaces in the MBeanServer named
- * // 'myapp.srv1' - but not recursively.
- * myapp.srv1::Foo[*//*:*]
- * </pre>
- * <p>For instance, the first two permissions listed above
- * will let through {@code getAttribute("a//b//D:k=v","Foo");} in
- * all MBeanServers, but will block access to
- * {@code getAttribute("a//b//c//D:k=v","Foo");} in MBeanServers whose
- * name do not start with {@code "myapp."}.
- * </p>
- * <p><a name="metawildcard">Depending on how your namespace hierarchy
- * is defined some of these wildcard permission names can be useful</a>:</p>
- * <pre>
- * // allows access to Foo in all namespaces, recursively.
- * //
- * *::Foo[**//*:*]
- *
- * // This permission name is the equivalent to the permission names above:
- * // Foo[**//*:*] and Foo[] are equivalent.
- * //
- * Foo[]
- *
- * // This permission name is the equivalent to the two permission names
- * // above:
- * // Foo[**//*:*], Foo[], Foo are equivalent.
- * //
- * Foo
- *
- * // allows access to Foo from all namespaces - but not recursively.
- * // This wildcard permission complements the previous one: it allows
- * // access to 'Foo' from an MBean directly registered in any local namespace.
- * //
- * Foo[*//*:*]
- *
- * </pre>
- * <p><b>Note on wildcards:</b> In an object name pattern, a path element
- * of exactly <code>**</code> corresponds to a meta
- * wildcard that will match any number of sub namespaces.
- * See ObjectName <a href="../ObjectName.html#metawildcard">documentation</a>
- * for more details.</p>
- *
- * <p>If {@code <mbean server name>::} is omitted, then one of
- * <code>member</code> or <code>object name</code> may be omitted.
- * If the <code>object name</code> is omitted,
- * the <code>[]</code> may be too (but does not have to be). It is
- * not legal to omit all items, that is to have a <em>name</em>
- * which is the empty string.</p>
- * <p>If {@code <mbean server name>} is present, it <b>must be followed</b> by
- * the {@code "::"} separator - otherwise it will be interpreted as
- * a {@code member name}.
- * </p>
- *
- * <p>
- * One or more of the <a href="#MBeanServerName">MBean Server name</a>,
- * <a href="#Member">member</a>
- * or <a href="#MBeanName">object name</a> may be the character "<code>-</code>",
- * which is equivalent to a null value. A null value is implied by
- * any value (including another null value) but does not imply any
- * other value.
- * </p>
- *
- * <p><a name="action-list">The possible actions are these:</a></p>
- *
- * <ul>
- * <li>addNotificationListener</li>
- * <li>getAttribute</li>
- * <li>getClassLoader</li>
- * <li>getClassLoaderFor</li>
- * <li>getClassLoaderRepository</li>
- * <li>getMBeanInfo</li>
- * <li>getObjectInstance</li>
- * <li>instantiate</li>
- * <li>invoke</li>
- * <li>isInstanceOf</li>
- * <li>queryMBeans</li>
- * <li>queryNames</li>
- * <li>registerMBean</li>
- * <li>removeNotificationListener</li>
- * <li>setAttribute</li>
- * <li>unregisterMBean</li>
- * </ul>
- *
- * <p>In a comma-separated list of actions, spaces are allowed before
- * and after each action.</p>
- *
- * @since 1.7
- */
-public class JMXNamespacePermission extends Permission {
-
- private static final long serialVersionUID = -2416928705275160661L;
-
- private static final String WILDPATH = "**" +
- JMXNamespaces.NAMESPACE_SEPARATOR + "*";
-
- /**
- * Actions list.
- */
- private static final int AddNotificationListener = 0x00001;
- private static final int GetAttribute = 0x00002;
- private static final int GetClassLoader = 0x00004;
- private static final int GetClassLoaderFor = 0x00008;
- private static final int GetClassLoaderRepository = 0x00010;
- // No GetDomains because it is not possible to route a call to
- // getDomains() on a NamespaceInterceptor - getDomains() doesn't
- // have any ObjectName.
- // private static final int GetDomains = 0x00020;
- private static final int GetMBeanInfo = 0x00040;
- private static final int GetObjectInstance = 0x00080;
- private static final int Instantiate = 0x00100;
- private static final int Invoke = 0x00200;
- private static final int IsInstanceOf = 0x00400;
- private static final int QueryMBeans = 0x00800;
- private static final int QueryNames = 0x01000;
- private static final int RegisterMBean = 0x02000;
- private static final int RemoveNotificationListener = 0x04000;
- private static final int SetAttribute = 0x08000;
- private static final int UnregisterMBean = 0x10000;
-
- /**
- * No actions.
- */
- private static final int NONE = 0x00000;
-
- /**
- * All actions.
- */
- // No GetDomains because it is not possible to route a call to
- // getDomains() on a NamespaceInterceptor - getDomains() doesn't
- // have any ObjectName.
- //
- private static final int ALL =
- AddNotificationListener |
- GetAttribute |
- GetClassLoader |
- GetClassLoaderFor |
- GetClassLoaderRepository |
- GetMBeanInfo |
- GetObjectInstance |
- Instantiate |
- Invoke |
- IsInstanceOf |
- QueryMBeans |
- QueryNames |
- RegisterMBean |
- RemoveNotificationListener |
- SetAttribute |
- UnregisterMBean;
-
- /**
- * The actions string.
- */
- private String actions;
-
- /**
- * The actions mask.
- */
- private transient int mask;
-
- /**
- * The name of the MBeanServer in which this permission is checked, or
- * granted. If null, is implied by any MBean server name
- * but does not imply any non-null MBean server name.
- */
- private transient String mbeanServerName;
-
- /**
- * The member that must match. If null, is implied by any member
- * but does not imply any non-null member.
- */
- private transient String member;
-
- /**
- * The objectName that must match. If null, is implied by any
- * objectName but does not imply any non-null objectName.
- */
- private transient ObjectName objectName;
-
- /**
- * If objectName is missing from name, then allnames will be
- * set to true.
- */
- private transient boolean allnames = false;
-
- /**
- * Parse <code>actions</code> parameter.
- */
- private void parseActions() {
-
- int amask;
-
- if (actions == null)
- throw new IllegalArgumentException("JMXNamespaceAccessPermission: " +
- "actions can't be null");
- if (actions.equals(""))
- throw new IllegalArgumentException("JMXNamespaceAccessPermission: " +
- "actions can't be empty");
-
- amask = getMask(actions);
-
- if ((amask & ALL) != amask)
- throw new IllegalArgumentException("Invalid actions mask");
- if (amask == NONE)
- throw new IllegalArgumentException("Invalid actions mask");
- this.mask = amask;
- }
-
- /**
- * Parse <code>name</code> parameter.
- */
- private void parseName() {
- String name = getName();
-
- if (name == null)
- throw new IllegalArgumentException("JMXNamespaceAccessPermission name " +
- "cannot be null");
-
- if (name.equals(""))
- throw new IllegalArgumentException("JMXNamespaceAccessPermission name " +
- "cannot be empty");
- final int sepIndex = name.indexOf("::");
- if (sepIndex < 0) {
- setMBeanServerName("*");
- } else {
- setMBeanServerName(name.substring(0,sepIndex));
- }
-
- /* The name looks like "mbeanServerName::member[objectname]".
- We subtract elements from the right as we parse, so after
- parsing the objectname we have "class#member" and after parsing the
- member we have "class". Each element is optional. */
-
- // Parse ObjectName
-
- final int start = (sepIndex<0)?0:sepIndex+2;
- int openingBracket = name.indexOf("[",start);
- if (openingBracket == -1) {
- // If "[on]" missing then ObjectName("*:*")
- //
- objectName = null;
- allnames = true;
- openingBracket=name.length();
- } else {
- if (!name.endsWith("]")) {
- throw new IllegalArgumentException("JMXNamespaceAccessPermission: " +
- "The ObjectName in the " +
- "target name must be " +
- "included in square " +
- "brackets");
- } else {
- // Create ObjectName
- //
- String on = name.substring(openingBracket + 1,
- name.length() - 1);
- try {
- // If "[]" then allnames are implied
- //
- final ObjectName target;
- final boolean all;
- if (on.equals("")) {
- target = null;
- all = true;
- } else if (on.equals("-")) {
- target = null;
- all = false;
- } else {
- target = new ObjectName(on);
- all = false;
- }
- setObjectName(target,all);
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException(
- "JMXNamespaceAccessPermission: " +
- "The target name does " +
- "not specify a valid " +
- "ObjectName", e);
- }
- }
- }
-
- final String memberName = name.substring(start,openingBracket);
- setMember(memberName);
- }
-
- private void setObjectName(ObjectName target, boolean all) {
- if (target != null &&
- !Util.wildpathmatch(target.getDomain(), WILDPATH)) {
- throw new IllegalArgumentException(
- "The target name does not contain " +
- "any namespace: "+String.valueOf(target));
- } else if (target != null) {
- final String domain = target.getDomain();
- final int seplen = JMXNamespaces.NAMESPACE_SEPARATOR.length();
- final int sepc = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR);
- if (sepc < 0 || (sepc+seplen)==domain.length()) {
- throw new IllegalArgumentException(String.valueOf(target)+
- ": no namespace in domain");
- }
- }
- objectName = target;
- allnames = all;
- }
-
- /**
- * Assign fields based on className, member, and objectName
- * parameters.
- */
-// private void initName(String namespaceName, String member,
-// ObjectName objectName, boolean allnames) {
-// setNamespace(namespaceName);
- private void initName(String mbeanServerName, String member,
- ObjectName mbeanName, boolean all) {
- setMBeanServerName(mbeanServerName);
- setMember(member);
- setObjectName(mbeanName, all);
- }
-
- private void setMBeanServerName(String mbeanServerName) {
- if (mbeanServerName == null || mbeanServerName.equals("-")) {
- this.mbeanServerName = null;
- } else if (mbeanServerName.equals("")) {
- this.mbeanServerName = "*";
- } else {
- this.mbeanServerName = mbeanServerName;
- }
- }
-
- private void setMember(String member) {
- if (member == null || member.equals("-"))
- this.member = null;
- else if (member.equals(""))
- this.member = "*";
- else
- this.member = member;
- }
-
- /**
- * <p>Create a new JMXNamespacePermission object with the
- * specified target name and actions.</p>
- *
- * <p>The target name is of the form
- * "<code>mbeanServerName::member[objectName]</code>" where each part is
- * optional. This target name must not be empty or null.
- * If <code>objectName</code> is present, it is of
- * the form <code>namespace//MBeanName</code>.
- * </p>
- * <p>
- * For a permission you need, {@code mbeanServerName} is the
- * <a href="#MBeanServerName">name of the MBeanServer</a> from
- * which {@code objectName} is being accessed.
- * </p>
- * <p>
- * For a permission you have, {@code mbeanServerName} is the
- * <a href="#MBeanServerName">name of the MBeanServer</a> from
- * which access to {@code objectName} is granted.
- * It can also be a pattern, and if omitted, {@code "*"} is assumed,
- * meaning that access to {@code objectName} is granted in all
- * MBean servers in the JVM.
- * </p>
- *
- * <p>The actions parameter contains a comma-separated list of the
- * desired actions granted on the target name. It must not be
- * empty or null.</p>
- *
- * @param name the triplet "mbeanServerName::member[objectName]".
- * If <code>objectName</code> is present, it is of
- * the form <code>namespace//MBeanName</code>.
- * @param actions the action string.
- *
- * @exception IllegalArgumentException if the <code>name</code> or
- * <code>actions</code> is invalid.
- */
- public JMXNamespacePermission(String name, String actions) {
- super(name);
-
- parseName();
-
- this.actions = actions;
- parseActions();
- }
-
- /**
- * <p>Create a new JMXNamespacePermission object with the specified
- * target name (namespace name, member, object name) and actions.</p>
- *
- * <p>The {@code MBeanServer} name, member and object name
- * parameters define a target name of the form
- * "<code>mbeanServerName::member[objectName]</code>" where each
- * part is optional. This will be the result of {@link #getName()} on the
- * resultant JMXNamespacePermission.
- * If the <code>mbeanServerName</code> is empty or exactly {@code "*"}, then
- * "{@code mbeanServerName::}" is omitted in that result.
- * </p>
- *
- * <p>The actions parameter contains a comma-separated list of the
- * desired actions granted on the target name. It must not be
- * empty or null.</p>
- *
- * @param mbeanServerName the name of the {@code MBeanServer} to which this
- * permission applies.
- * May be null or <code>"-"</code>, which represents an MBeanServer name
- * that is implied by any MBeanServer name but does not imply any other
- * MBeanServer name.
- * @param member the member to which this permission applies. May
- * be null or <code>"-"</code>, which represents a member that is
- * implied by any member but does not imply any other member.
- * @param objectName the object name to which this permission
- * applies.
- * May be null, which represents an object name that is
- * implied by any object name but does not imply any other object
- * name. If not null, the {@code objectName} must be of the
- * form {@code <namespace>//<mbean name>} - where {@code <namespace>}
- * can be a domain pattern, and {@code <mbean name>} can be an ObjectName
- * pattern.
- * For a permission you need, {@code <namespace>} is the name of the
- * name space for which the permission is checked, and {@code <mbean name>}
- * is the name of the MBean in that namespace.
- * The composed name {@code <namespace>//<mbean name>} thus represents the
- * name of the MBean as seen by the {@code mbeanServerName} containing
- * {@code <namespace>}.
- *
- * @param actions the action string.
- */
- public JMXNamespacePermission(
- String mbeanServerName,
- String member,
- ObjectName objectName,
- String actions) {
- this(mbeanServerName, member, objectName, false, actions);
-// this(member, objectName, false, actions);
- }
-
- /**
- * <p>Create a new JMXNamespacePermission object with the specified
- * MBean Server name, member, and actions.</p>
- *
- * <p>The {@code MBeanServer} name and member
- * parameters define a target name of the form
- * "<code>mbeanServerName::member[]</code>" where each
- * part is optional. This will be the result of {@link #getName()} on the
- * resultant JMXNamespacePermission.
- * If the <code>mbeanServerName</code> is empty or exactly {@code "*"}, then
- * "{@code mbeanServerName::}" is omitted in that result.
- * </p>
- *
- * <p>The actions parameter contains a comma-separated list of the
- * desired actions granted on the target name. It must not be
- * empty or null.</p>
- *
- * @param mbeanServerName the name of the {@code MBeanServer} to which this
- * permission applies.
- * May be null or <code>"-"</code>, which represents an MBeanServer name
- * that is implied by any MBeanServer name but does not imply any other
- * MBeanServer name.
- * @param member the member to which this permission applies. May
- * be null or <code>"-"</code>, which represents a member that is
- * implied by any member but does not imply any other member.
- * @param actions the action string.
- */
- public JMXNamespacePermission(String mbeanServerName,
- String member,
- String actions) {
- this(mbeanServerName,member,null,true,actions);
- // this(member,null,allnames,actions);
- }
-
- /**
- * <p>Create a new JMXNamespacePermission object with the specified
- * target name (namespace name, member, object name) and actions.</p>
- *
- * <p>The MBean Server name, member and object name parameters define a
- * target name of the form
- * "<code>mbeanServerName::member[objectName]</code>" where each part is
- * optional. This will be the result of {@link
- * java.security.Permission#getName() getName()} on the
- * resultant JMXNamespacePermission.</p>
- *
- * <p>The actions parameter contains a comma-separated list of the
- * desired actions granted on the target name. It must not be
- * empty or null.</p>
- *
- * @param mbeanServerName the name of the {@code MBeanServer} to which this
- * permission applies.
- * May be null or <code>"-"</code>, which represents an MBeanServer name
- * that is implied by any MBeanServer name but does not imply any other
- * MBeanServer name.
- * @param member the member to which this permission applies. May
- * be null or <code>"-"</code>, which represents a member that is
- * implied by any member but does not imply any other member.
- * @param objectName the object name to which this permission
- * applies. If null, and allnames is false, represents an object
- * name that is implied by any object name but does not imply any
- * other object name. Otherwise, if allnames is true, it represents
- * a meta wildcard that matches all object names. It is equivalent to
- * a missing objectName ("[]") in the {@link
- * java.security.Permission#getName() name} property.
- * @param allnames represent a meta wildcard indicating that the
- * objectName was not specified. This implies all objectnames
- * that match "*:*" and all object names that match
- * "**//*:*"
- * @param actions the action string.
- */
- private JMXNamespacePermission(String mbeanServerName,
- String member,
- ObjectName objectName,
- boolean allnames,
- String actions) {
-
- super(makeName(mbeanServerName,
- member, objectName, allnames));
- initName(mbeanServerName,
- member, objectName, allnames);
-
- this.actions = actions;
- parseActions();
- }
-
- private static String makeName(String mbeanServerName,
- String memberName, ObjectName objName, boolean allMBeans) {
- final StringBuilder name = new StringBuilder();
- if (mbeanServerName == null)
- mbeanServerName = "-";
- if (!mbeanServerName.equals("") && !mbeanServerName.equals("*"))
- name.append(mbeanServerName).append("::");
- if (memberName == null)
- memberName = "-";
- name.append(memberName);
- if (objName == null) {
- if (allMBeans)
- name.append("[]");
- else
- name.append("[-]");
- } else {
- final String domain = objName.getDomain();
- final int seplen = JMXNamespaces.NAMESPACE_SEPARATOR.length();
- final int sepc = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR);
- if (sepc < 0 || (sepc+seplen)==domain.length()) {
- throw new IllegalArgumentException(String.valueOf(objName)+
- ": no namespace in domain");
- }
- final String can = objName.getCanonicalName();
- name.append("[").append(can).append("]");
- }
- return name.toString();
- }
-
- /**
- * Returns the "canonical string representation" of the actions. That is,
- * this method always returns actions in alphabetical order.
- *
- * @return the canonical string representation of the actions.
- */
- public String getActions() {
-
- if (actions == null)
- actions = getActions(this.mask);
-
- return actions;
- }
-
- /**
- * Returns the "canonical string representation"
- * of the actions from the mask.
- */
- private static String getActions(int mask) {
- final StringBuilder sb = new StringBuilder();
- boolean comma = false;
-
- if ((mask & AddNotificationListener) == AddNotificationListener) {
- comma = true;
- sb.append("addNotificationListener");
- }
-
- if ((mask & GetAttribute) == GetAttribute) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("getAttribute");
- }
-
- if ((mask & GetClassLoader) == GetClassLoader) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("getClassLoader");
- }
-
- if ((mask & GetClassLoaderFor) == GetClassLoaderFor) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("getClassLoaderFor");
- }
-
- if ((mask & GetClassLoaderRepository) == GetClassLoaderRepository) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("getClassLoaderRepository");
- }
-
- if ((mask & GetMBeanInfo) == GetMBeanInfo) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("getMBeanInfo");
- }
-
- if ((mask & GetObjectInstance) == GetObjectInstance) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("getObjectInstance");
- }
-
- if ((mask & Instantiate) == Instantiate) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("instantiate");
- }
-
- if ((mask & Invoke) == Invoke) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("invoke");
- }
-
- if ((mask & IsInstanceOf) == IsInstanceOf) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("isInstanceOf");
- }
-
- if ((mask & QueryMBeans) == QueryMBeans) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("queryMBeans");
- }
-
- if ((mask & QueryNames) == QueryNames) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("queryNames");
- }
-
- if ((mask & RegisterMBean) == RegisterMBean) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("registerMBean");
- }
-
- if ((mask & RemoveNotificationListener) == RemoveNotificationListener) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("removeNotificationListener");
- }
-
- if ((mask & SetAttribute) == SetAttribute) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("setAttribute");
- }
-
- if ((mask & UnregisterMBean) == UnregisterMBean) {
- if (comma) sb.append(',');
- else comma = true;
- sb.append("unregisterMBean");
- }
-
- // No GetDomains because it is not possible to route a call to
- // getDomains() on a NamespaceInterceptor - getDomains() doesn't
- // have any ObjectName.
-
- return sb.toString();
- }
-
- @Override
- public int hashCode() {
- return this.getName().hashCode() + this.getActions().hashCode();
- }
-
- /**
- * Converts an action String to an integer action mask.
- *
- * @param action the action string.
- * @return the action mask.
- */
- private static int getMask(String action) {
-
- /*
- * BE CAREFUL HERE! PARSING ORDER IS IMPORTANT IN THIS ALGORITHM.
- *
- * The 'string length' test must be performed for the lengthiest
- * strings first.
- *
- * In this permission if the "unregisterMBean" string length test is
- * performed after the "registerMBean" string length test the algorithm
- * considers the 'unregisterMBean' action as being the 'registerMBean'
- * action and a parsing error is returned.
- */
-
- int mask = NONE;
-
- if (action == null) {
- return mask;
- }
-
- if (action.equals("*")) {
- return ALL;
- }
-
- char[] a = action.toCharArray();
-
- int i = a.length - 1;
- if (i < 0)
- return mask;
-
- while (i != -1) {
- char c;
-
- // skip whitespace
- while ((i!=-1) && ((c = a[i]) == ' ' ||
- c == '\r' ||
- c == '\n' ||
- c == '\f' ||
- c == '\t'))
- i--;
-
- // check for the known strings
- int matchlen;
-
- // No GetDomains because it is not possible to route a call to
- // getDomains() on a NamespaceInterceptor - getDomains() doesn't
- // have any ObjectName.
-
- if (i >= 25 && /* removeNotificationListener */
- (a[i-25] == 'r') &&
- (a[i-24] == 'e') &&
- (a[i-23] == 'm') &&
- (a[i-22] == 'o') &&
- (a[i-21] == 'v') &&
- (a[i-20] == 'e') &&
- (a[i-19] == 'N') &&
- (a[i-18] == 'o') &&
- (a[i-17] == 't') &&
- (a[i-16] == 'i') &&
- (a[i-15] == 'f') &&
- (a[i-14] == 'i') &&
- (a[i-13] == 'c') &&
- (a[i-12] == 'a') &&
- (a[i-11] == 't') &&
- (a[i-10] == 'i') &&
- (a[i-9] == 'o') &&
- (a[i-8] == 'n') &&
- (a[i-7] == 'L') &&
- (a[i-6] == 'i') &&
- (a[i-5] == 's') &&
- (a[i-4] == 't') &&
- (a[i-3] == 'e') &&
- (a[i-2] == 'n') &&
- (a[i-1] == 'e') &&
- (a[i] == 'r')) {
- matchlen = 26;
- mask |= RemoveNotificationListener;
- } else if (i >= 23 && /* getClassLoaderRepository */
- (a[i-23] == 'g') &&
- (a[i-22] == 'e') &&
- (a[i-21] == 't') &&
- (a[i-20] == 'C') &&
- (a[i-19] == 'l') &&
- (a[i-18] == 'a') &&
- (a[i-17] == 's') &&
- (a[i-16] == 's') &&
- (a[i-15] == 'L') &&
- (a[i-14] == 'o') &&
- (a[i-13] == 'a') &&
- (a[i-12] == 'd') &&
- (a[i-11] == 'e') &&
- (a[i-10] == 'r') &&
- (a[i-9] == 'R') &&
- (a[i-8] == 'e') &&
- (a[i-7] == 'p') &&
- (a[i-6] == 'o') &&
- (a[i-5] == 's') &&
- (a[i-4] == 'i') &&
- (a[i-3] == 't') &&
- (a[i-2] == 'o') &&
- (a[i-1] == 'r') &&
- (a[i] == 'y')) {
- matchlen = 24;
- mask |= GetClassLoaderRepository;
- } else if (i >= 22 && /* addNotificationListener */
- (a[i-22] == 'a') &&
- (a[i-21] == 'd') &&
- (a[i-20] == 'd') &&
- (a[i-19] == 'N') &&
- (a[i-18] == 'o') &&
- (a[i-17] == 't') &&
- (a[i-16] == 'i') &&
- (a[i-15] == 'f') &&
- (a[i-14] == 'i') &&
- (a[i-13] == 'c') &&
- (a[i-12] == 'a') &&
- (a[i-11] == 't') &&
- (a[i-10] == 'i') &&
- (a[i-9] == 'o') &&
- (a[i-8] == 'n') &&
- (a[i-7] == 'L') &&
- (a[i-6] == 'i') &&
- (a[i-5] == 's') &&
- (a[i-4] == 't') &&
- (a[i-3] == 'e') &&
- (a[i-2] == 'n') &&
- (a[i-1] == 'e') &&
- (a[i] == 'r')) {
- matchlen = 23;
- mask |= AddNotificationListener;
- } else if (i >= 16 && /* getClassLoaderFor */
- (a[i-16] == 'g') &&
- (a[i-15] == 'e') &&
- (a[i-14] == 't') &&
- (a[i-13] == 'C') &&
- (a[i-12] == 'l') &&
- (a[i-11] == 'a') &&
- (a[i-10] == 's') &&
- (a[i-9] == 's') &&
- (a[i-8] == 'L') &&
- (a[i-7] == 'o') &&
- (a[i-6] == 'a') &&
- (a[i-5] == 'd') &&
- (a[i-4] == 'e') &&
- (a[i-3] == 'r') &&
- (a[i-2] == 'F') &&
- (a[i-1] == 'o') &&
- (a[i] == 'r')) {
- matchlen = 17;
- mask |= GetClassLoaderFor;
- } else if (i >= 16 && /* getObjectInstance */
- (a[i-16] == 'g') &&
- (a[i-15] == 'e') &&
- (a[i-14] == 't') &&
- (a[i-13] == 'O') &&
- (a[i-12] == 'b') &&
- (a[i-11] == 'j') &&
- (a[i-10] == 'e') &&
- (a[i-9] == 'c') &&
- (a[i-8] == 't') &&
- (a[i-7] == 'I') &&
- (a[i-6] == 'n') &&
- (a[i-5] == 's') &&
- (a[i-4] == 't') &&
- (a[i-3] == 'a') &&
- (a[i-2] == 'n') &&
- (a[i-1] == 'c') &&
- (a[i] == 'e')) {
- matchlen = 17;
- mask |= GetObjectInstance;
- } else if (i >= 14 && /* unregisterMBean */
- (a[i-14] == 'u') &&
- (a[i-13] == 'n') &&
- (a[i-12] == 'r') &&
- (a[i-11] == 'e') &&
- (a[i-10] == 'g') &&
- (a[i-9] == 'i') &&
- (a[i-8] == 's') &&
- (a[i-7] == 't') &&
- (a[i-6] == 'e') &&
- (a[i-5] == 'r') &&
- (a[i-4] == 'M') &&
- (a[i-3] == 'B') &&
- (a[i-2] == 'e') &&
- (a[i-1] == 'a') &&
- (a[i] == 'n')) {
- matchlen = 15;
- mask |= UnregisterMBean;
- } else if (i >= 13 && /* getClassLoader */
- (a[i-13] == 'g') &&
- (a[i-12] == 'e') &&
- (a[i-11] == 't') &&
- (a[i-10] == 'C') &&
- (a[i-9] == 'l') &&
- (a[i-8] == 'a') &&
- (a[i-7] == 's') &&
- (a[i-6] == 's') &&
- (a[i-5] == 'L') &&
- (a[i-4] == 'o') &&
- (a[i-3] == 'a') &&
- (a[i-2] == 'd') &&
- (a[i-1] == 'e') &&
- (a[i] == 'r')) {
- matchlen = 14;
- mask |= GetClassLoader;
- } else if (i >= 12 && /* registerMBean */
- (a[i-12] == 'r') &&
- (a[i-11] == 'e') &&
- (a[i-10] == 'g') &&
- (a[i-9] == 'i') &&
- (a[i-8] == 's') &&
- (a[i-7] == 't') &&
- (a[i-6] == 'e') &&
- (a[i-5] == 'r') &&
- (a[i-4] == 'M') &&
- (a[i-3] == 'B') &&
- (a[i-2] == 'e') &&
- (a[i-1] == 'a') &&
- (a[i] == 'n')) {
- matchlen = 13;
- mask |= RegisterMBean;
- } else if (i >= 11 && /* getAttribute */
- (a[i-11] == 'g') &&
- (a[i-10] == 'e') &&
- (a[i-9] == 't') &&
- (a[i-8] == 'A') &&
- (a[i-7] == 't') &&
- (a[i-6] == 't') &&
- (a[i-5] == 'r') &&
- (a[i-4] == 'i') &&
- (a[i-3] == 'b') &&
- (a[i-2] == 'u') &&
- (a[i-1] == 't') &&
- (a[i] == 'e')) {
- matchlen = 12;
- mask |= GetAttribute;
- } else if (i >= 11 && /* getMBeanInfo */
- (a[i-11] == 'g') &&
- (a[i-10] == 'e') &&
- (a[i-9] == 't') &&
- (a[i-8] == 'M') &&
- (a[i-7] == 'B') &&
- (a[i-6] == 'e') &&
- (a[i-5] == 'a') &&
- (a[i-4] == 'n') &&
- (a[i-3] == 'I') &&
- (a[i-2] == 'n') &&
- (a[i-1] == 'f') &&
- (a[i] == 'o')) {
- matchlen = 12;
- mask |= GetMBeanInfo;
- } else if (i >= 11 && /* isInstanceOf */
- (a[i-11] == 'i') &&
- (a[i-10] == 's') &&
- (a[i-9] == 'I') &&
- (a[i-8] == 'n') &&
- (a[i-7] == 's') &&
- (a[i-6] == 't') &&
- (a[i-5] == 'a') &&
- (a[i-4] == 'n') &&
- (a[i-3] == 'c') &&
- (a[i-2] == 'e') &&
- (a[i-1] == 'O') &&
- (a[i] == 'f')) {
- matchlen = 12;
- mask |= IsInstanceOf;
- } else if (i >= 11 && /* setAttribute */
- (a[i-11] == 's') &&
- (a[i-10] == 'e') &&
- (a[i-9] == 't') &&
- (a[i-8] == 'A') &&
- (a[i-7] == 't') &&
- (a[i-6] == 't') &&
- (a[i-5] == 'r') &&
- (a[i-4] == 'i') &&
- (a[i-3] == 'b') &&
- (a[i-2] == 'u') &&
- (a[i-1] == 't') &&
- (a[i] == 'e')) {
- matchlen = 12;
- mask |= SetAttribute;
- } else if (i >= 10 && /* instantiate */
- (a[i-10] == 'i') &&
- (a[i-9] == 'n') &&
- (a[i-8] == 's') &&
- (a[i-7] == 't') &&
- (a[i-6] == 'a') &&
- (a[i-5] == 'n') &&
- (a[i-4] == 't') &&
- (a[i-3] == 'i') &&
- (a[i-2] == 'a') &&
- (a[i-1] == 't') &&
- (a[i] == 'e')) {
- matchlen = 11;
- mask |= Instantiate;
- } else if (i >= 10 && /* queryMBeans */
- (a[i-10] == 'q') &&
- (a[i-9] == 'u') &&
- (a[i-8] == 'e') &&
- (a[i-7] == 'r') &&
- (a[i-6] == 'y') &&
- (a[i-5] == 'M') &&
- (a[i-4] == 'B') &&
- (a[i-3] == 'e') &&
- (a[i-2] == 'a') &&
- (a[i-1] == 'n') &&
- (a[i] == 's')) {
- matchlen = 11;
- mask |= QueryMBeans;
- } else if (i >= 9 && /* queryNames */
- (a[i-9] == 'q') &&
- (a[i-8] == 'u') &&
- (a[i-7] == 'e') &&
- (a[i-6] == 'r') &&
- (a[i-5] == 'y') &&
- (a[i-4] == 'N') &&
- (a[i-3] == 'a') &&
- (a[i-2] == 'm') &&
- (a[i-1] == 'e') &&
- (a[i] == 's')) {
- matchlen = 10;
- mask |= QueryNames;
- } else if (i >= 5 && /* invoke */
- (a[i-5] == 'i') &&
- (a[i-4] == 'n') &&
- (a[i-3] == 'v') &&
- (a[i-2] == 'o') &&
- (a[i-1] == 'k') &&
- (a[i] == 'e')) {
- matchlen = 6;
- mask |= Invoke;
- } else {
- // parse error
- throw new IllegalArgumentException("Invalid permission: " +
- action);
- }
-
- // make sure we didn't just match the tail of a word
- // like "ackbarfaccept". Also, skip to the comma.
- boolean seencomma = false;
- while (i >= matchlen && !seencomma) {
- switch(a[i-matchlen]) {
- case ',':
- seencomma = true;
- break;
- case ' ': case '\r': case '\n':
- case '\f': case '\t':
- break;
- default:
- throw new IllegalArgumentException("Invalid permission: " +
- action);
- }
- i--;
- }
-
- // point i at the location of the comma minus one (or -1).
- i -= matchlen;
- }
-
- return mask;
- }
-
- /**
- * <p>Checks if this JMXNamespacePermission object "implies" the
- * specified permission.</p>
- *
- * <p>More specifically, this method returns true if:</p>
- *
- * <ul>
- *
- * <li> <i>p</i> is an instance of JMXNamespacePermission; and</li>
- *
- * <li> <i>p</i> has a null mbeanServerName or <i>p</i>'s mbeanServerName
- * matches this object's mbeanServerName; and</li>
- *
- * <li> <i>p</i> has a null member or <i>p</i>'s member matches this
- * object's member; and</li>
- *
- * <li> <i>p</i> has a null object name or <i>p</i>'s
- * object name matches this object's object name; and</li>
- *
- * <li> <i>p</i>'s actions are a subset of this object's actions</li>
- *
- * </ul>
- *
- * <p>If this object's mbeanServerName is a pattern, then <i>p</i>'s
- * mbeanServerName is matched against that pattern. An empty
- * mbeanServerName is equivalent to "{@code *}". A null
- * mbeanServerName is equivalent to "{@code -}".</p>
- * <p>If this object's mbeanServerName is "<code>*</code>" or is
- * empty, <i>p</i>'s mbeanServerName always matches it.</p>
- *
- * <p>If this object's member is "<code>*</code>", <i>p</i>'s
- * member always matches it.</p>
- *
- * <p>If this object's objectName <i>n1</i> is an object name pattern,
- * <i>p</i>'s objectName <i>n2</i> matches it if
- * {@link ObjectName#equals <i>n1</i>.equals(<i>n2</i>)} or if
- * {@link ObjectName#apply <i>n1</i>.apply(<i>n2</i>)}.</p>
- *
- * <p>A permission that includes the <code>queryMBeans</code> action
- * is considered to include <code>queryNames</code> as well.</p>
- *
- * @param p the permission to check against.
- * @return true if the specified permission is implied by this object,
- * false if not.
- */
- public boolean implies(Permission p) {
- if (!(p instanceof JMXNamespacePermission))
- return false;
-
- JMXNamespacePermission that = (JMXNamespacePermission) p;
-
- // Actions
- //
- // The actions in 'this' permission must be a
- // superset of the actions in 'that' permission
- //
-
- /* "queryMBeans" implies "queryNames" */
- if ((this.mask & QueryMBeans) == QueryMBeans) {
- if (((this.mask | QueryNames) & that.mask) != that.mask) {
- //System.out.println("action [with QueryNames] does not imply");
- return false;
- }
- } else {
- if ((this.mask & that.mask) != that.mask) {
- //System.out.println("action does not imply");
- return false;
- }
- }
-
- // Target name
- //
- // The 'mbeanServerName' check is true iff:
- // 1) the mbeanServerName in 'this' permission is omitted or "*", or
- // 2) the mbeanServerName in 'that' permission is omitted or "*", or
- // 3) the mbeanServerName in 'this' permission does pattern
- // matching with the mbeanServerName in 'that' permission.
- //
- // The 'member' check is true iff:
- // 1) the member in 'this' member is omitted or "*", or
- // 2) the member in 'that' member is omitted or "*", or
- // 3) the member in 'this' permission equals the member in
- // 'that' permission.
- //
- // The 'object name' check is true iff:
- // 1) the object name in 'this' permission is omitted, or
- // 2) the object name in 'that' permission is omitted, or
- // 3) the object name in 'this' permission does pattern
- // matching with the object name in 'that' permission.
- //
-
- if (that.mbeanServerName == null) {
- // bottom is implied
- } else if (this.mbeanServerName == null) {
- // bottom implies nothing but itself
- return false;
- } else if (that.mbeanServerName.equals(this.mbeanServerName)) {
- // exact match
- } else if (!Util.wildmatch(that.mbeanServerName,this.mbeanServerName)) {
- return false; // no match
- }
-
- /* Check if this.member implies that.member */
-
- if (that.member == null) {
- // bottom is implied
- } else if (this.member == null) {
- // bottom implies nothing but itself
- return false;
- } else if (this.member.equals("*")) {
- // wildcard implies everything (including itself)
- } else if (this.member.equals(that.member)) {
- // exact match
- } else if (!Util.wildmatch(that.member,this.member)) {
- return false; // no match
- }
-
- /* Check if this.objectName implies that.objectName */
-
- if (that.objectName == null) {
- // bottom is implied
- } else if (this.objectName == null) {
- // bottom implies nothing but itself
- if (allnames == false) return false;
- } else if (!this.objectName.apply(that.objectName)) {
- /* ObjectName.apply returns false if that.objectName is a
- wildcard so we also allow equals for that case. This
- never happens during real permission checks, but means
- the implies relation is reflexive. */
- if (!this.objectName.equals(that.objectName))
- return false;
- }
-
- return true;
- }
-
- /**
- * Checks two JMXNamespacePermission objects for equality. Checks
- * that <i>obj</i> is an JMXNamespacePermission, and has the same
- * name and actions as this object.
- * <P>
- * @param obj the object we are testing for equality with this object.
- * @return true if obj is an JMXNamespacePermission, and has the
- * same name and actions as this JMXNamespacePermission object.
- */
- public boolean equals(Object obj) {
- if (obj == this)
- return true;
-
- if (! (obj instanceof JMXNamespacePermission))
- return false;
-
- JMXNamespacePermission that = (JMXNamespacePermission) obj;
-
- return (this.mask == that.mask) &&
- (this.getName().equals(that.getName()));
- }
-
- /**
- * Deserialize this object based on its name and actions.
- */
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- parseName();
- parseActions();
- }
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespaceView.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +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 javax.management.namespace;
-
-import java.io.IOException;
-import java.util.Set;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-/**
- * This class makes it possible to navigate easily within a hierarchical
- * namespace view.
- *
- * <pre>
- * MBeanServerConnnection rootConnection = ...;
- *
- * // create a view at the local root of the namespace hierarchy.
- * //
- * JMXNamespaceView view = new JMXNamespaceView(rootConnection);
- *
- * // list all top level namespaces
- * String[] list = view.list();
- *
- * // select one namespace from the list
- * String whereToGo = ... ;
- *
- * // go down to the selected namespace:
- * view = view.down(whereToGo);
- * System.out.println("I am now in: " + view.where());
- * System.out.println("I can see these MBeans:" +
- * view.getMBeanServerConnection().queryNames(null,null));
- *
- * // list sub namespaces in current view ('whereToGo')
- * list = view.list();
- * System.out.println("Here are the sub namespaces of "+view.where()+": "+
- * Arrays.toString(list));
- *
- * // go up one level
- * view = view.up();
- * System.out.println("I am now back to: " +
- * (view.isRoot() ? "root namespace" : view.where()));
- * </pre>
- * @since 1.7
- */
-public class JMXNamespaceView {
-
- private static final ObjectName ALL_NAMESPACES;
- static {
- try {
- ALL_NAMESPACES = ObjectName.getInstance("*" +
- JMXNamespaces.NAMESPACE_SEPARATOR + ":"+
- JMXNamespace.TYPE_ASSIGNMENT);
- } catch (MalformedObjectNameException x) {
- throw new ExceptionInInitializerError(x);
- }
- }
- private static final int NAMESPACE_SEPARATOR_LENGTH =
- JMXNamespaces.NAMESPACE_SEPARATOR.length();
-
- private final JMXNamespaceView parent;
- private final MBeanServerConnection here;
- private final String where;
-
- private static MBeanServerConnection checkRoot(MBeanServerConnection root) {
- if (root == null)
- throw new IllegalArgumentException(
- "namespaceRoot: null is not a valid value");
- return root;
- }
-
- /**
- * Creates a view at the top of a JMX namespace hierarchy.
- * @param namespaceRoot The {@code MBeanServerConnection} at the
- * top of the hierarchy.
- */
- public JMXNamespaceView(MBeanServerConnection namespaceRoot) {
- this(null,checkRoot(namespaceRoot),"");
- }
-
- // This constructor should remain private. A user can only create
- // JMXNamespaceView at the top of the hierarchy.
- // JMXNamespaceView sub nodes are created by their parent nodes.
- private JMXNamespaceView(JMXNamespaceView parent,
- MBeanServerConnection here, String where) {
- this.parent = parent;
- this.here = here;
- this.where = where;
- }
-
- /**
- * Returns the path leading to the namespace in this view, from
- * the top of the hierarchy.
- * @return The path to the namespace in this view.
- */
- public String where() {
- return where;
- }
-
- /**
- * Lists all direct sub namespaces in this view. The returned strings
- * do not contain the {@code //} separator.
- *
- * @return A list of direct sub name spaces accessible from this
- * namespace.
- * @throws IOException if the attempt to list the namespaces fails because
- * of a communication problem.
- */
- public String[] list() throws IOException {
- final Set<ObjectName> names =
- here.queryNames(ALL_NAMESPACES,null);
- final String[] res = new String[names.size()];
- int i = 0;
- for (ObjectName dirName : names) {
- final String dir = dirName.getDomain();
- res[i++]=dir.substring(0,dir.length()-NAMESPACE_SEPARATOR_LENGTH);
- }
- return res;
- }
-
- /**
- * Go down into a sub namespace.
- * @param namespace the namespace to go down to. It can contain one or
- * more {@code //} separators, to traverse intermediate namespaces, but
- * it must not begin or end with {@code //} or contain an empty
- * intermediate namespace. If it is the empty string, then {@code this} is
- * returned.
- * @return A view of the named sub namespace.
- * @throws IllegalArgumentException if the {@code namespace} begins or
- * ends with {@code //}.
- */
- public JMXNamespaceView down(String namespace) {
- if (namespace.equals("")) return this;
- if (namespace.startsWith(JMXNamespaces.NAMESPACE_SEPARATOR))
- throw new IllegalArgumentException(namespace+": can't start with "+
- JMXNamespaces.NAMESPACE_SEPARATOR);
-
- // This is a convenience to handle paths like xxx//yyy
- final String[] elts =
- namespace.split(JMXNamespaces.NAMESPACE_SEPARATOR);
-
- // Go down the path, creating all sub namespaces along the way.
- // Usually there will be a single element in the given namespace
- // name, but we don't want to forbid things like
- // down("xxx//yyy/www");
- //
- JMXNamespaceView previous = this;
- String cursor = where;
- for (String elt : elts) {
- // empty path elements are not allowed. It means we
- // had something like "xxx////yyy"
- if (elt.equals(""))
- throw new IllegalArgumentException(namespace+
- ": invalid path element");
-
- // compute the "where" for the child.
- cursor = JMXNamespaces.concat(cursor, elt);
-
- // create the child...
- final JMXNamespaceView next =
- makeJMXNamespaceView(root(), previous, cursor);
-
- // the current child will be the parent of the next child...
- previous = next;
- }
-
- // We return the last child that was created.
- return previous;
- }
-
- /**
- * Go back up one level. If this view is at the root of the
- * hierarchy, returns {@code null}.
- * @return A view of the parent namespace, or {@code null} if we're at
- * the root of the hierarchy.
- */
- public JMXNamespaceView up() {
- return parent;
- }
-
- /**
- * Tells whether this view is at the root of the hierarchy.
- * @return {@code true} if this view is at the root of the hierachy.
- */
- public boolean isRoot() {
- return parent == null;
- }
-
- /**
- * Returns the view at the root of the hierarchy.
- * If we are already at the root, this is {@code this}.
- * @return the view at the root of the hierarchy.
- */
- public JMXNamespaceView root() {
- if (parent == null) return this;
- return parent.root();
- }
-
- /**
- * A MBeanServerConnection to the namespace shown by this view.
- * This is what would have been obtained by doing:
- * <pre>
- * JMX.narrowToNamespace(this.root().getMBeanServerConnection(),
- * this.where());
- * </pre>
- * @return A MBeanServerConnection to the namespace shown by this view.
- */
- public MBeanServerConnection getMBeanServerConnection() {
- return here;
- }
-
- /**
- * <p>Get the name of the JMXNamespaceMBean handling the namespace shown by
- * this view, relative to the root of the hierarchy. If we are at the root
- * of the hierarchy, this method returns {@code null}.</p>
- *
- * <p>You can use this method to make a proxy for the JMXNamespaceMBean
- * as follows:</p>
- *
- * <pre>
- * JMXNamespaceView view = ...;
- * ObjectName namespaceMBeanName = view.getJMXNamespaceMBeanName();
- * JMXNamespaceMBean namespaceMBean = JMX.newMBeanProxy(
- * view.root().getMBeanServerConnection(), namespaceMBeanName,
- * JMXNamespaceMBean.class);
- * </pre>
- *
- * @return The name of the {@code JMXNamespaceMBean} handling the namespace
- * shown by this view, or {@code null}.
- */
- public ObjectName getJMXNamespaceMBeanName() {
- if (parent == null)
- return null;
- else
- return JMXNamespaces.getNamespaceObjectName(where);
- }
-
- @Override
- public int hashCode() {
- return where.hashCode();
- }
-
- /**
- * Returns true if this object is equal to the given object. The
- * two objects are equal if the other object is also a {@code
- * JMXNamespaceView} and both objects have the same {@linkplain #root root}
- * MBeanServerConnection and the same {@linkplain #where path}.
- * @param o the other object to compare to.
- * @return true if both objects are equal.
- */
- @Override
- public boolean equals(Object o) {
- if (o==this) return true;
- if (! (o instanceof JMXNamespaceView)) return false;
- if (!where.equals(((JMXNamespaceView)o).where)) return false;
- return root().getMBeanServerConnection().equals(
- ((JMXNamespaceView)o).root().getMBeanServerConnection());
- }
-
- private JMXNamespaceView makeJMXNamespaceView(final JMXNamespaceView root,
- final JMXNamespaceView directParent, final String pathFromRoot) {
- if (pathFromRoot.equals("")) return root;
-
- return new JMXNamespaceView(directParent,
- narrowToNamespace(root.getMBeanServerConnection(),
- pathFromRoot),pathFromRoot);
- }
-
- private MBeanServerConnection narrowToNamespace(MBeanServerConnection root,
- String path) {
- if (root instanceof MBeanServer)
- return JMXNamespaces.narrowToNamespace((MBeanServer)root, path);
- return JMXNamespaces.narrowToNamespace(root, path);
- }
-
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +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 javax.management.namespace;
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.namespace.ObjectNameRouter;
-import com.sun.jmx.namespace.serial.RewritingProcessor;
-import com.sun.jmx.namespace.RoutingConnectionProxy;
-import com.sun.jmx.namespace.RoutingServerProxy;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-/**
- * Static constants and utility methods to help work with
- * JMX name spaces. There are no instances of this class.
- * @since 1.7
- */
-public class JMXNamespaces {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
- /** Creates a new instance of JMXNamespaces */
- private JMXNamespaces() {
- }
-
- /**
- * The name space separator. This is an alias for {@link
- * ObjectName#NAMESPACE_SEPARATOR}.
- **/
- public static final String NAMESPACE_SEPARATOR =
- ObjectName.NAMESPACE_SEPARATOR;
- private static final int NAMESPACE_SEPARATOR_LENGTH =
- NAMESPACE_SEPARATOR.length();
-
-
- /**
- * Creates a new {@code MBeanServerConnection} proxy on a
- * {@linkplain javax.management.namespace sub name space}
- * of the given parent.
- *
- * @param parent The parent {@code MBeanServerConnection} that contains
- * the name space.
- * @param namespace The {@linkplain javax.management.namespace
- * name space} in which to narrow.
- * @return A new {@code MBeanServerConnection} proxy that shows the content
- * of that name space.
- * @throws IllegalArgumentException if either argument is null,
- * or the name space does not exist, or if a proxy for that name space
- * cannot be created. The {@linkplain Throwable#getCause() cause} of
- * this exception will be an {@link InstanceNotFoundException} if and only
- * if the name space is found not to exist.
- */
- public static MBeanServerConnection narrowToNamespace(
- MBeanServerConnection parent,
- String namespace) {
- if (LOG.isLoggable(Level.FINER))
- LOG.finer("Making MBeanServerConnection for: " +namespace);
- return RoutingConnectionProxy.cd(parent, namespace, true);
- }
-
- /**
- * Creates a new {@code MBeanServer} proxy on a
- * {@linkplain javax.management.namespace sub name space}
- * of the given parent.
- *
- * @param parent The parent {@code MBeanServer} that contains
- * the name space.
- * @param namespace The {@linkplain javax.management.namespace
- * name space} in which to narrow.
- * @return A new {@code MBeanServer} proxy that shows the content
- * of that name space.
- * @throws IllegalArgumentException if either argument is null,
- * or the name space does not exist, or if a proxy for that name space
- * cannot be created. The {@linkplain Throwable#getCause() cause} of
- * this exception will be an {@link InstanceNotFoundException} if and only
- * if the name space is found not to exist.
- */
- public static MBeanServer narrowToNamespace(MBeanServer parent,
- String namespace) {
- if (LOG.isLoggable(Level.FINER))
- LOG.finer("Making MBeanServer for: " +namespace);
- return RoutingServerProxy.cd(parent, namespace, true);
- }
-
- /**
- * Returns an object that is the same as the given object except that
- * any {@link ObjectName} it might contain has its domain modified.
- * The returned object might be identical to the given object if it
- * does not contain any {@code ObjectName} values or if none of them
- * were modified.
- * This method will replace a prefix ({@code toRemove}) from the path of
- * the ObjectNames contained in {@code obj} by another prefix
- * ({@code toAdd}).
- * Therefore, all contained ObjectNames must have a path that start with
- * the given {@code toRemove} prefix. If one of them doesn't, an {@link
- * IllegalArgumentException} is thrown.
- * <p>
- * For instance, if {@code obj} contains the ObjectName
- * {@code x//y//z//d:k=x}, and {@code toAdd} is {@code v//w}, and
- * {@code toRemove}
- * is {@code x//y} this method will return a copy of {@code obj} that
- * contains {@code v//w//z//d:k=x}.<br>
- * On the other hand, if {@code obj} contains the ObjectName
- * {@code x//y//z//d:k=x}, and {@code toAdd} is {@code v//w}, and
- * {@code toRemove} is {@code v} this method
- * will raise an exception, because {@code x//y//z//d:k=x} doesn't start
- * with {@code v}
- * </p>
- * <p>Note: the default implementation of this method can use the
- * Java serialization framework to clone and replace ObjectNames in the
- * provided {@code obj}. It will usually fail if {@code obj} is not
- * Java serializable, or contains objects which are not Java
- * serializable.
- * </p>
- * @param obj The object to deep-rewrite
- * @param toRemove a prefix already present in contained ObjectNames.
- * If {@code toRemove} is the empty string {@code ""}, nothing
- * will be removed from the contained ObjectNames.
- * @param toAdd the prefix that will replace (@code toRemove} in contained
- * ObjectNames.
- * If {@code toAdd} is the empty string {@code ""}, nothing
- * will be added to the contained ObjectNames.
- * @return the rewritten object, or possibly {@code obj} if nothing needed
- * to be changed.
- * @throws IllegalArgumentException if {@code obj} couldn't be rewritten or
- * if {@code toRemove} or {@code toAdd} is null.
- **/
- public static <T> T deepReplaceHeadNamespace(T obj, String toRemove, String toAdd) {
- final RewritingProcessor processor =
- RewritingProcessor.newRewritingProcessor(toAdd,toRemove);
- return processor.rewriteOutput(obj);
- }
-
- /**
- * Appends {@code namespace} to {@code path}.
- * This methods appends {@code namespace} to {@code path} to obtain a
- * a <i>full path</i>, and normalizes the result thus obtained:
- * <ul>
- * <li>If {@code path} is empty, the full path is
- * {@code namespace}.</li>
- * <li>Otherwise, if {@code namespace} is empty,
- * the full path is {@code path}</li>
- * <li>Otherwise, and this is the regular case, the full path is the
- * result of the concatenation of
- * {@code path}+{@value #NAMESPACE_SEPARATOR}+{@code namespace}</li>
- * <li>finally, the full path is normalized: multiple consecutive
- * occurrences of {@value #NAMESPACE_SEPARATOR} are replaced by a
- * single {@value #NAMESPACE_SEPARATOR} in the result, and trailing
- * occurences of {@value #NAMESPACE_SEPARATOR} are removed.
- * </li>
- * </ul>
- * @param path a name space path prefix
- * @param namespace a name space name to append to the path
- * @return a syntactically valid name space path, or "" if both parameters
- * are null or empty.
- * @throws IllegalArgumentException if either argument is null or ends with
- * an odd number of {@code /} characters.
- **/
- public static String concat(String path, String namespace) {
- if (path == null || namespace == null)
- throw new IllegalArgumentException("Null argument");
- checkTrailingSlashes(path);
- checkTrailingSlashes(namespace);
- final String result;
- if (path.equals("")) result=namespace;
- else if (namespace.equals("")) result=path;
- else result=path+NAMESPACE_SEPARATOR+namespace;
- return ObjectNameRouter.normalizeNamespacePath(result,false,true,false);
- }
-
- /**
- * Returns a syntactically valid name space path.
- * If the provided {@code namespace} ends with {@code "//"},
- * recursively strips trailing {@code "//"}. Each sequence of an
- * even number of {@code "/"} characters is also replaced by {@code "//"},
- * for example {@code "foo//bar////baz/////buh"} will become
- * {@code "foo//bar//baz///buh"}.
- *
- * @param namespace A name space path
- * @return {@code ""} - if the provided {@code namespace} resolves to
- * the empty string; otherwise a syntactically valid name space string
- * stripped of trailing and redundant {@code "//"}.
- * @throws IllegalArgumentException if {@code namespace} is null or
- * is not syntactically valid (e.g. it contains
- * invalid characters like ':', or it ends with an odd
- * number of '/').
- */
- public static String normalizeNamespaceName(String namespace) {
- if (namespace == null)
- throw new IllegalArgumentException("Null namespace");
- final String sourcePath =
- ObjectNameRouter.normalizeNamespacePath(namespace,false,true,false);
- if (sourcePath.equals("")) return sourcePath;
-
- // Will throw an IllegalArgumentException if the namespace name
- // is not syntactically valid...
- //
- getNamespaceObjectName(sourcePath);
- return sourcePath;
- }
-
-
- /**
- * Return a canonical handler name for the provided {@code namespace},
- * The handler name returned will be
- * {@link #normalizeNamespaceName normalizeNamespaceName}{@code (namespace) +
- * "//:type=JMXNamespace"}.
- *
- * @param namespace A name space path
- * @return a canonical ObjectName for a name space handler.
- * @see #normalizeNamespaceName
- * @throws IllegalArgumentException if the provided
- * {@code namespace} is null or not valid.
- */
- public static ObjectName getNamespaceObjectName(String namespace) {
- if (namespace == null || namespace.equals(""))
- throw new IllegalArgumentException("Null or empty namespace");
- final String sourcePath =
- ObjectNameRouter.normalizeNamespacePath(namespace,false,
- true,false);
- try {
- // We could use ObjectName.valueOf here - but throwing an
- // IllegalArgumentException that contains just the supplied
- // namespace instead of the whole ObjectName seems preferable.
- return ObjectName.getInstance(sourcePath+
- NAMESPACE_SEPARATOR+":"+
- JMXNamespace.TYPE_ASSIGNMENT);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException("Invalid namespace: " +
- namespace,x);
- }
- }
-
- /**
- * Returns an ObjectName pattern that can be used to query for all MBeans
- * contained in the given name space.
- * For instance, if {@code namespace="foo//bar"}, this method will
- * return {@code "foo//bar//*:*"}
- * @return an ObjectName pattern that selects all MBeans in the given
- * name space.
- **/
- public static ObjectName getWildcardFor(String namespace) {
- return insertPath(namespace,ObjectName.WILDCARD);
- }
-
-
- /**
- * Returns an ObjectName that can be used to access an MBean
- * contained in the given name space.
- * For instance, if {@code path="foo//bar"}, and
- * {@code to="domain:type=Thing"} this method will
- * return {@code "foo//bar//domain:type=Thing"}
- * @return an ObjectName that can be used to invoke an MBean located in a
- * sub name space.
- * @throws IllegalArgumentException if {@code path} ends with an
- * odd number of {@code /} characters.
- **/
- public static ObjectName insertPath(String path, ObjectName to) {
- if (path == null || to == null)
- throw new IllegalArgumentException("Null argument");
- checkTrailingSlashes(path);
- String prefix = path;
- if (!prefix.equals(""))
- prefix = ObjectNameRouter.normalizeNamespacePath(
- prefix + NAMESPACE_SEPARATOR,false,false,false);
- return to.withDomain(
- ObjectNameRouter.normalizeDomain(
- prefix+to.getDomain(),false));
- }
-
- /**
- * Returns the normalized name space path of the name space expected to
- * contain {@code ObjectName}.
- * For instance, for {@code "foo//domain:type=Thing"} this will be
- * {@code "foo"}. For {@code "//foo//bar//domain:type=Thing"} this will be
- * {@code "foo//bar"}. For {@code //foo//bar//baz//domain:type=Thing}
- * this will be {@code "foo//bar//baz"}. For
- * {@code //foo//bar//baz//:type=JMXNamespace}
- * this will be {@code "foo//bar"}.
- *
- * @param name an {@code ObjectName}
- * @return the name space path of the name space that could contain such
- * a name. If {@code name} has no name space, returns {@code ""}.
- * @throws IllegalArgumentException if {@code name} is null.
- **/
- public static String getContainingNamespace(ObjectName name) {
- return getNormalizedPath(name,true);
- }
-
-
- static String getNormalizedPath(ObjectName name,
- boolean removeLeadingSep) {
- if (name == null)
- throw new IllegalArgumentException("Null name");
- String domain =
- ObjectNameRouter.normalizeDomain(name.getDomain(),removeLeadingSep);
- int end = domain.length();
-
- // special case of domain part being a single '/'
- //
- if (domain.endsWith(NAMESPACE_SEPARATOR+"/"))
- return domain.substring(0,end-NAMESPACE_SEPARATOR_LENGTH-1);
-
- // special case of namespace handler
- //
- if (domain.endsWith(NAMESPACE_SEPARATOR))
- domain = domain.substring(0,end-NAMESPACE_SEPARATOR_LENGTH);
-
- int last = domain.lastIndexOf(NAMESPACE_SEPARATOR);
- if (last < 0) return "";
- if (last == 0) return domain;
-
- // special case of domain part starting with '/'
- // last=0 is not possible - we took care of this above.
- if (domain.charAt(last-1) == '/') last--;
-
- return domain.substring(0,last);
- }
-
- private static void checkTrailingSlashes(String path) {
- int i;
- for (i = path.length() - 1; i >= 0 && path.charAt(i) == '/'; i--)
- continue;
- if (path.length() - i % 2 == 0)
- throw new IllegalArgumentException("Path ends with odd number of /");
- }
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,809 +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 javax.management.namespace;
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.mbeanserver.Util;
-import com.sun.jmx.remote.util.EnvHelp;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.AttributeChangeNotification;
-
-import javax.management.ClientContext;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServerConnection;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * A {@link JMXNamespace} that will connect to a remote MBeanServer
- * by creating a {@link javax.management.remote.JMXConnector} from a
- * {@link javax.management.remote.JMXServiceURL}.
- * <p>
- * You can call {@link #connect() connect()} and {@link #close close()}
- * several times. This MBean will emit an {@link AttributeChangeNotification}
- * when the value of its {@link #isConnected Connected} attribute changes.
- * </p>
- * <p>
- * The JMX Remote Namespace MBean is not connected until {@link
- * #connect() connect()} is explicitly called. The usual sequence of code to
- * create a JMX Remote Namespace is thus:
- * </p>
- * <pre>
- * final String namespace = "mynamespace";
- * final ObjectName name = {@link JMXNamespaces#getNamespaceObjectName
- * JMXNamespaces.getNamespaceObjectName(namespace)};
- * final JMXServiceURL remoteServerURL = .... ;
- * final Map<String,Object> optionsMap = .... ;
- * final MBeanServer masterMBeanServer = .... ;
- * final JMXRemoteNamespace namespaceMBean = {@link #newJMXRemoteNamespace
- * JMXRemoteNamespace.newJMXRemoteNamespace(remoteServerURL, optionsMap)};
- * masterMBeanServer.registerMBean(namespaceMBean, name);
- * namespaceMBean.connect();
- * // or: masterMBeanServer.invoke(name, {@link #connect() "connect"}, null, null);
- * </pre>
- * <p>
- * The JMX Remote Namespace MBean will register for {@linkplain
- * JMXConnectionNotification JMX Connection Notifications} with its underlying
- * {@link JMXConnector}. When a JMX Connection Notification indicates that
- * the underlying connection has failed, the JMX Remote Namespace MBean
- * closes its underlying connector and switches its {@link #isConnected
- * Connected} attribute to false, emitting an {@link
- * AttributeChangeNotification}.
- * </p>
- * <p>
- * At this point, a managing application (or an administrator connected
- * through a management console) can attempt to reconnect the
- * JMX Remote Namespace MBean by calling its {@link #connect() connect()} method
- * again.
- * </p>
- * <p>Note that when the connection with the remote namespace fails, or when
- * {@link #close} is called, then any notification subscription to
- * MBeans registered in that namespace will be lost - unless a custom
- * {@linkplain javax.management.event event service} supporting connection-less
- * mode was used.
- * </p>
- * @since 1.7
- */
-public class JMXRemoteNamespace
- extends JMXNamespace
- implements JMXRemoteNamespaceMBean, NotificationEmitter {
-
- /**
- * A logger for this class.
- */
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
-
-
- // This connection listener is used to listen for connection events from
- // the underlying JMXConnector. It is used in particular to maintain the
- // "connected" state in this MBean.
- //
- private class ConnectionListener implements NotificationListener {
- private ConnectionListener() {
- }
- public void handleNotification(Notification notification,
- Object handback) {
- if (!(notification instanceof JMXConnectionNotification))
- return;
- final JMXConnectionNotification cn =
- (JMXConnectionNotification)notification;
- final String type = cn.getType();
- if (JMXConnectionNotification.CLOSED.equals(type)
- || JMXConnectionNotification.FAILED.equals(type)) {
- checkState(this,cn,(JMXConnector)handback);
- }
- }
- }
-
- // When the JMXRemoteNamespace is originally created, it is not connected,
- // which means that the source MBeanServer should be one that throws
- // exceptions for most methods. When it is subsequently connected,
- // the methods should be forwarded to the MBeanServerConnection.
- // We handle this using MBeanServerConnectionWrapper. The
- // MBeanServerConnection that is supplied to the constructor of
- // MBeanServerConnectionWrapper is ignored (and in fact it is null)
- // because the one that is actually used is the one supplied by the
- // override of getMBeanServerConnection().
- private static class JMXRemoteNamespaceDelegate
- extends MBeanServerConnectionWrapper {
- private volatile JMXRemoteNamespace parent=null;
-
- JMXRemoteNamespaceDelegate() {
- super(null,null);
- }
- @Override
- public MBeanServerConnection getMBeanServerConnection() {
- return parent.getMBeanServerConnection();
- }
- @Override
- public ClassLoader getDefaultClassLoader() {
- return parent.getDefaultClassLoader();
- }
-
- // Because this class is instantiated in the super() call from the
- // constructor of JMXRemoteNamespace, it cannot be an inner class.
- // This method achieves the effect that an inner class would have
- // had, of giving the class a reference to the outer "this".
- synchronized void initParentOnce(JMXRemoteNamespace parent) {
- if (this.parent != null)
- throw new UnsupportedOperationException("parent already set");
- this.parent=parent;
-
- }
-
- }
-
- private static final MBeanNotificationInfo connectNotification =
- new MBeanNotificationInfo(new String[] {
- AttributeChangeNotification.ATTRIBUTE_CHANGE},
- "Connected",
- "Emitted when the Connected state of this object changes");
-
- private static AtomicLong seqNumber = new AtomicLong(0);
-
- private final NotificationBroadcasterSupport broadcaster;
- private final ConnectionListener listener;
- private final JMXServiceURL jmxURL;
- private final Map<String,?> optionsMap;
-
- private volatile MBeanServerConnection server = null;
- private volatile JMXConnector conn = null;
- private volatile ClassLoader defaultClassLoader = null;
-
- /**
- * Creates a new instance of {@code JMXRemoteNamespace}.
- * <p>
- * This constructor is provided for subclasses.
- * To create a new instance of {@code JMXRemoteNamespace} call
- * {@link #newJMXRemoteNamespace
- * JMXRemoteNamespace.newJMXRemoteNamespace(sourceURL, optionsMap)}.
- * </p>
- * @param sourceURL a JMX service URL that can be used to {@linkplain
- * #connect() connect} to the
- * source MBean Server. The source MBean Server is the remote
- * MBean Server which contains the MBeans that will be mirrored
- * in this namespace.
- * @param optionsMap the options map that will be passed to the
- * {@link JMXConnectorFactory} when {@linkplain
- * JMXConnectorFactory#newJMXConnector creating} the
- * {@link JMXConnector} used to {@linkplain #connect() connect}
- * to the remote source MBean Server. Can be null, which is
- * equivalent to an empty map.
- * @see #newJMXRemoteNamespace JMXRemoteNamespace.newJMXRemoteNamespace
- * @see #connect
- */
- protected JMXRemoteNamespace(JMXServiceURL sourceURL,
- Map<String,?> optionsMap) {
- super(new JMXRemoteNamespaceDelegate());
- ((JMXRemoteNamespaceDelegate)super.getSourceServer()).
- initParentOnce(this);
-
- // URL must not be null.
- if (sourceURL == null)
- throw new IllegalArgumentException("Null URL");
- this.jmxURL = sourceURL;
- this.broadcaster =
- new NotificationBroadcasterSupport(connectNotification);
-
- // handles options
- this.optionsMap = unmodifiableMap(optionsMap);
-
- // handles (dis)connection events
- this.listener = new ConnectionListener();
- }
-
- // returns un unmodifiable view of a map.
- private static <K,V> Map<K,V> unmodifiableMap(Map<K,V> aMap) {
- if (aMap == null || aMap.isEmpty())
- return Collections.emptyMap();
- return Collections.unmodifiableMap(aMap);
- }
-
- /**
- * Returns the {@code JMXServiceURL} that is (or will be) used to
- * connect to the remote name space. <p>
- * @see #connect
- * @return The {@code JMXServiceURL} used to connect to the remote
- * name space.
- */
- public JMXServiceURL getJMXServiceURL() {
- return jmxURL;
- }
-
- /**
- * In this class, this method never returns {@code null}, and the
- * address returned is the {@link #getJMXServiceURL JMXServiceURL}
- * that is used by this object to {@linkplain #connect} to the remote
- * name space. <p>
- * This behaviour might be overriden by subclasses, if needed.
- * For instance, a subclass might want to return {@code null} if it
- * doesn't want to expose that JMXServiceURL.
- */
- public JMXServiceURL getAddress() {
- return getJMXServiceURL();
- }
-
- private Map<String,?> getEnvMap() {
- return optionsMap;
- }
-
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback) {
- broadcaster.addNotificationListener(listener, filter, handback);
- }
-
- /**
- * A subclass that needs to send its own notifications must override
- * this method in order to return an {@link MBeanNotificationInfo
- * MBeanNotificationInfo[]} array containing both its own notification
- * infos and the notification infos of its super class. <p>
- * The implementation should probably look like:
- * <pre>
- * final MBeanNotificationInfo[] myOwnNotifs = { .... };
- * final MBeanNotificationInfo[] parentNotifs =
- * super.getNotificationInfo();
- * final Set<MBeanNotificationInfo> mergedResult =
- * new HashSet<MBeanNotificationInfo>();
- * mergedResult.addAll(Arrays.asList(myOwnNotifs));
- * mergedResult.addAll(Arrays.asList(parentNotifs));
- * return mergeResult.toArray(
- * new MBeanNotificationInfo[mergedResult.size()]);
- * </pre>
- */
- public MBeanNotificationInfo[] getNotificationInfo() {
- return broadcaster.getNotificationInfo();
- }
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(listener);
- }
-
- public void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback)
- throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(listener, filter, handback);
- }
-
- private static long getNextSeqNumber() {
- return seqNumber.getAndIncrement();
- }
-
-
- /**
- * Sends a notification to registered listeners. Before the notification
- * is sent, the following steps are performed:
- * <ul><li>
- * If {@code n.getSequenceNumber() <= 0} set it to the next available
- * sequence number.</li>
- * <li>If {@code n.getSource() == null}, set it to the value returned by {@link
- * #getObjectName getObjectName()}.
- * </li></ul>
- * <p>This method can be called by subclasses in order to send their own
- * notifications.
- * In that case, these subclasses might also need to override
- * {@link #getNotificationInfo} in order to declare their own
- * {@linkplain MBeanNotificationInfo notification types}.
- * </p>
- * @param n The notification to send to registered listeners.
- * @see javax.management.NotificationBroadcasterSupport
- * @see #getNotificationInfo
- **/
- protected void sendNotification(Notification n) {
- if (n.getSequenceNumber()<=0)
- n.setSequenceNumber(getNextSeqNumber());
- if (n.getSource()==null)
- n.setSource(getObjectName());
- broadcaster.sendNotification(n);
- }
-
- private void checkState(ConnectionListener listener,
- JMXConnectionNotification cn,
- JMXConnector emittingConnector) {
-
- // Due to the asynchronous handling of notifications, it is
- // possible that this method is called for a JMXConnector
- // (or connection) which is already closed and replaced by a newer
- // one.
- //
- // This method attempts to determine the real state of the
- // connection - which might be different from what the notification
- // says.
- //
- // This is quite complex logic - because we try not to hold any
- // lock while evaluating the true value of the connected state,
- // while anyone might also call close() or connect() from a
- // different thread.
- // The method switchConnection() (called from here too) also has the
- // same kind of complex logic:
- //
- // We use the JMXConnector has a handback to the notification listener
- // (emittingConnector) in order to be able to determine whether the
- // notification concerns the current connector in use, or an older
- // one. The 'emittingConnector' is the connector from which the
- // notification originated. This could be an 'old' connector - as
- // closed() and connect() could already have been called before the
- // notification arrived. So what we do is to compare the
- // 'emittingConnector' with the current connector, to see if the
- // notification actually comes from the curent connector.
- //
- boolean remove = false;
-
- // whether the emittingConnector is already 'removed'
- synchronized (this) {
- if (this.conn != emittingConnector ||
- JMXConnectionNotification.FAILED.equals(cn.getType()))
- remove = true;
- }
-
- // We need to unregister our listener from this 'removed' connector.
- // This is the only place where we remove the listener.
- //
- if (remove) {
- try {
- // This may fail if the connector is already closed.
- // But better unregister anyway...
- //
- emittingConnector.removeConnectionNotificationListener(
- listener,null,
- emittingConnector);
- } catch (Exception x) {
- LOG.log(Level.FINE,
- "Failed to unregister connection listener"+x);
- LOG.log(Level.FINEST,
- "Failed to unregister connection listener",x);
- }
- try {
- // This may fail if the connector is already closed.
- // But better call close twice and get an exception than
- // leaking...
- //
- emittingConnector.close();
- } catch (Exception x) {
- LOG.log(Level.FINEST,
- "Failed to close old connector " +
- "(failure was expected): "+x);
- }
- }
-
- // Now we checked whether our current connector is still alive.
- //
- boolean closed = false;
- final JMXConnector thisconn = this.conn;
- try {
- if (thisconn != null)
- thisconn.getConnectionId();
- } catch (IOException x) {
- LOG.finest("Connector already closed: "+x);
- closed = true;
- }
-
- // We got an IOException - the connector is not connected.
- // Need to forget it and switch our state to closed.
- //
- if (closed) {
- switchConnection(thisconn,null,null);
- try {
- // Usually this will fail... Better call close twice
- // and get an exception than leaking...
- //
- if (thisconn != emittingConnector || !remove)
- thisconn.close();
- } catch (IOException x) {
- LOG.log(Level.FINEST,
- "Failed to close connector (failure was expected): "
- +x);
- }
- }
- }
-
- private final void switchConnection(JMXConnector oldc,
- JMXConnector newc,
- MBeanServerConnection mbs) {
- boolean connect = false;
- boolean close = false;
- synchronized (this) {
- if (oldc != conn) {
- if (newc != null) {
- try {
- newc.close();
- } catch (IOException x) {
- LOG.log(Level.FINEST,
- "Failed to close connector",x);
- }
- }
- return;
- }
- if (conn == null && newc != null) connect=true;
- if (newc == null && conn != null) close = true;
- conn = newc;
- server = mbs;
- }
- if (connect || close) {
- boolean oldstate = close;
- boolean newstate = connect;
- final ObjectName myName = getObjectName();
-
- // In the uncommon case where the MBean is connected before
- // being registered, myName can be null...
- // If myName is null - we use 'this' as the source instead...
- //
- final Object source = (myName==null)?this:myName;
- final AttributeChangeNotification acn =
- new AttributeChangeNotification(source,
- getNextSeqNumber(),System.currentTimeMillis(),
- String.valueOf(source)+
- (newstate?" connected":" closed"),
- "Connected",
- "boolean",
- Boolean.valueOf(oldstate),
- Boolean.valueOf(newstate));
- sendNotification(acn);
- }
- }
-
- private void close(JMXConnector c) {
- try {
- if (c != null) c.close();
- } catch (Exception x) {
- // OK: we're gonna throw the original exception later.
- LOG.finest("Ignoring exception when closing connector: "+x);
- }
- }
-
- private JMXConnector connect(JMXServiceURL url, Map<String,?> env)
- throws IOException {
- final JMXConnector c = newJMXConnector(url, env);
- c.connect(env);
- return c;
- }
-
- /**
- * <p>Creates a new JMXConnector with the specified {@code url} and
- * {@code env} options map. The default implementation of this method
- * returns {@link JMXConnectorFactory#newJMXConnector
- * JMXConnectorFactory.newJMXConnector(jmxURL, env)}. Subclasses can
- * override this method to customize behavior.</p>
- *
- * @param url The JMXServiceURL of the remote server.
- * @param optionsMap An options map that will be passed to the
- * {@link JMXConnectorFactory} when {@linkplain
- * JMXConnectorFactory#newJMXConnector creating} the
- * {@link JMXConnector} that can connect to the remote source
- * MBean Server.
- * @return A JMXConnector to use to connect to the remote server
- * @throws IOException if the connector could not be created.
- * @see JMXConnectorFactory#newJMXConnector(javax.management.remote.JMXServiceURL, java.util.Map)
- * @see #JMXRemoteNamespace
- */
- protected JMXConnector newJMXConnector(JMXServiceURL url,
- Map<String,?> optionsMap) throws IOException {
- return JMXConnectorFactory.newJMXConnector(jmxURL, optionsMap);
- }
-
- /**
- * <p>Called when a new connection is established using {@link #connect}
- * so that subclasses can customize the connection. The default
- * implementation of this method effectively does the following:</p>
- *
- * <pre>
- * MBeanServerConnection mbsc = {@link JMXConnector#getMBeanServerConnection()
- * jmxc.getMBeanServerConnection()};
- * try {
- * return {@link ClientContext#withDynamicContext
- * ClientContext.withDynamicContext(mbsc)};
- * } catch (IllegalArgumentException e) {
- * return mbsc;
- * }
- * </pre>
- *
- * <p>In other words, it arranges for the client context to be forwarded
- * to the remote MBean Server if the remote MBean Server supports contexts;
- * otherwise it ignores the client context.</p>
- *
- * <h4>Example: connecting to a remote namespace</h4>
- *
- * <p>A subclass that wanted to narrow into a namespace of
- * the remote MBeanServer might look like this:</p>
- *
- * <pre>
- * class JMXRemoteSubNamespace extends JMXRemoteNamespace {
- * private final String subnamespace;
- *
- * JMXRemoteSubNamespace(
- * JMXServiceURL url, Map{@code <String, ?>} env, String subnamespace) {
- * super(url, env);
- * this.subnamespace = subnamespace;
- * }
- *
- * {@code @Override}
- * protected MBeanServerConnection getMBeanServerConnection(
- * JMXConnector jmxc) throws IOException {
- * MBeanServerConnection mbsc = super.getMBeanServerConnection(jmxc);
- * return {@link JMXNamespaces#narrowToNamespace(MBeanServerConnection,String)
- * JMXNamespaces.narrowToNamespace(mbsc, subnamespace)};
- * }
- * }
- * </pre>
- *
- * <h4>Example: using the Event Service for notifications</h4>
- *
- * <p>Some connectors may have been designed to work with an earlier
- * version of the JMX API, and may not have been upgraded to use
- * the {@linkplain javax.management.event Event Service} defined in
- * this version of the JMX API. In that case, and if the remote
- * server to which this JMXRemoteNamespace connects also contains
- * namespaces, it may be necessary to configure explicitly an {@linkplain
- * javax.management.event.EventClientDelegate#newForwarder Event Client
- * Forwarder} on the remote server side, and to force the use of an {@link
- * EventClient} on this client side.</p>
- *
- * <p>A subclass of {@link JMXRemoteNamespace} can provide an
- * implementation of {@code getMBeanServerConnection} that will force
- * notification subscriptions to flow through an {@link EventClient} over
- * a legacy protocol. It can do so by overriding this method in the
- * following way:</p>
- *
- * <pre>
- * class JMXRemoteEventClientNamespace extends JMXRemoteNamespace {
- * JMXRemoteEventClientNamespace(JMXServiceURL url, {@code Map<String,?>} env) {
- * super(url, env);
- * }
- *
- * {@code @Override}
- * protected MBeanServerConnection getMBeanServerConnection(JMXConnector jmxc)
- * throws IOException {
- * MBeanServerConnection mbsc = super.getMBeanServerConnection(jmxc);
- * return EventClient.getEventClientConnection(mbsc);
- * }
- * }
- * </pre>
- *
- * <p>
- * Note that the remote server also needs to provide an {@link
- * javax.management.event.EventClientDelegateMBean}: configuring only
- * the client side (this object) is not enough.</p>
- *
- * <p>In summary, this technique should be used if the remote server
- * supports JMX namespaces, but uses a JMX Connector Server whose
- * implementation does not transparently use the new Event Service
- * (as would be the case with the JMXMPConnectorServer implementation
- * from the reference implementation of the JMX Remote API 1.0
- * specification).</p>
- *
- * @param jmxc the newly-created {@code JMXConnector}.
- *
- * @return an {@code MBeanServerConnection} connected to the remote
- * MBeanServer.
- *
- * @throws IOException if the connection cannot be made. If this method
- * throws {@code IOException} then the calling {@link #connect()} method
- * will also fail with an {@code IOException}.
- *
- * @see #connect
- */
- protected MBeanServerConnection getMBeanServerConnection(JMXConnector jmxc)
- throws IOException {
- final MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
- try {
- return ClientContext.withDynamicContext(mbsc);
- } catch (IllegalArgumentException e) {
- LOG.log(Level.FINER, "ClientContext.withDynamicContext", e);
- return mbsc;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The sequence of events when this method is called includes,
- * effectively, the following code:</p>
- *
- * <pre>
- * JMXServiceURL url = {@link #getJMXServiceURL getJMXServiceURL}();
- * JMXConnector jmxc = {@link #newJMXConnector newJMXConnector}(url, env);
- * jmxc.connect();
- * MBeanServerConnection mbsc = {@link #getMBeanServerConnection(JMXConnector)
- * getMBeanServerConnection}(jmxc);
- * </pre>
- *
- * <p>Here, {@code env} is a {@code Map} containing the entries from the
- * {@code optionsMap} that was passed to the {@linkplain #JMXRemoteNamespace
- * constructor} or to the {@link #newJMXRemoteNamespace newJMXRemoteNamespace}
- * factory method.</p>
- *
- * <p>Subclasses can customize connection behavior by overriding the
- * {@code getJMXServiceURL}, {@code newJMXConnector}, or
- * {@code getMBeanServerConnection} methods.</p>
- */
- public void connect() throws IOException {
- LOG.fine("connecting...");
- final Map<String,Object> env =
- new HashMap<String,Object>(getEnvMap());
- try {
- // XXX: We should probably document this...
- // This allows to specify a loader name - which will be
- // retrieved from the parent MBeanServer.
- defaultClassLoader =
- EnvHelp.resolveServerClassLoader(env,getMBeanServer());
- } catch (InstanceNotFoundException x) {
- final IOException io =
- new IOException("ClassLoader not found");
- io.initCause(x);
- throw io;
- }
- env.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,defaultClassLoader);
- final JMXServiceURL url = getJMXServiceURL();
- final JMXConnector aconn = connect(url,env);
- final MBeanServerConnection msc;
- try {
- msc = getMBeanServerConnection(aconn);
- aconn.addConnectionNotificationListener(listener,null,aconn);
- } catch (IOException io) {
- close(aconn);
- throw io;
- } catch (RuntimeException x) {
- close(aconn);
- throw x;
- }
-
- switchConnection(conn,aconn,msc);
-
- LOG.fine("connected.");
- }
-
- public void close() throws IOException {
- if (conn == null) return;
- LOG.fine("closing...");
- // System.err.println(toString()+": closing...");
- conn.close();
- // System.err.println(toString()+": connector closed");
- switchConnection(conn,null,null);
- LOG.fine("closed.");
- // System.err.println(toString()+": closed");
- }
-
- MBeanServerConnection getMBeanServerConnection() {
- if (conn == null)
- throw newRuntimeIOException("getMBeanServerConnection: not connected");
- return server;
- }
-
- // Better than throwing UndeclaredThrowableException ...
- private RuntimeException newRuntimeIOException(String msg) {
- final IllegalStateException illegal = new IllegalStateException(msg);
- return Util.newRuntimeIOException(new IOException(msg,illegal));
- }
-
- /**
- * Returns the default class loader used by the underlying
- * {@link JMXConnector}.
- * @return the default class loader used when communicating with the
- * remote source MBean server.
- **/
- ClassLoader getDefaultClassLoader() {
- if (conn == null)
- throw newRuntimeIOException("getMBeanServerConnection: not connected");
- return defaultClassLoader;
- }
-
- public boolean isConnected() {
- // This is a pleonasm
- return (conn != null) && (server != null);
- }
-
-
- /**
- * This name space handler will automatically {@link #close} its
- * connection with the remote source in {@code preDeregister}.
- **/
- @Override
- public void preDeregister() throws Exception {
- try {
- close();
- } catch (IOException x) {
- LOG.fine("Failed to close properly - exception ignored: " + x);
- LOG.log(Level.FINEST,
- "Failed to close properly - exception ignored",x);
- }
- super.preDeregister();
- }
-
- /**
- * This method calls {@link
- * javax.management.MBeanServerConnection#getMBeanCount
- * getMBeanCount()} on the remote namespace.
- * @throws java.io.IOException if an {@link IOException} is raised when
- * communicating with the remote source namespace.
- */
- @Override
- public Integer getMBeanCount() throws IOException {
- return getMBeanServerConnection().getMBeanCount();
- }
-
- /**
- * This method returns the result of calling {@link
- * javax.management.MBeanServerConnection#getDomains
- * getDomains()} on the remote namespace.
- * @throws java.io.IOException if an {@link IOException} is raised when
- * communicating with the remote source namespace.
- */
- @Override
- public String[] getDomains() throws IOException {
- return getMBeanServerConnection().getDomains();
- }
-
- /**
- * This method returns the result of calling {@link
- * javax.management.MBeanServerConnection#getDefaultDomain
- * getDefaultDomain()} on the remote namespace.
- * @throws java.io.IOException if an {@link IOException} is raised when
- * communicating with the remote source namespace.
- */
- @Override
- public String getDefaultDomain() throws IOException {
- return getMBeanServerConnection().getDefaultDomain();
- }
-
- /**
- * Creates a new instance of {@code JMXRemoteNamespace}.
- * @param sourceURL a JMX service URL that can be used to connect to the
- * source MBean Server. The source MBean Server is the remote
- * MBean Server which contains the MBeans that will be mirrored
- * in this namespace.
- * @param optionsMap An options map that will be passed to the
- * {@link JMXConnectorFactory} when {@linkplain
- * JMXConnectorFactory#newJMXConnector creating} the
- * {@link JMXConnector} used to connect to the remote source
- * MBean Server. Can be null, which is equivalent to an empty map.
- * @see #JMXRemoteNamespace JMXRemoteNamespace(sourceURL,optionsMap)
- * @see JMXConnectorFactory#newJMXConnector(javax.management.remote.JMXServiceURL, java.util.Map)
- */
- public static JMXRemoteNamespace newJMXRemoteNamespace(
- JMXServiceURL sourceURL,
- Map<String,?> optionsMap) {
- return new JMXRemoteNamespace(sourceURL, optionsMap);
- }
-}
--- a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespaceMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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 javax.management.namespace;
-
-import java.io.IOException;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * A {@link JMXNamespaceMBean} that will connect to a remote MBeanServer
- * by creating a {@link javax.management.remote.JMXConnector} from a
- * {@link javax.management.remote.JMXServiceURL}.
- * You can call {@link #connect connect()} and {@link #close close()}
- * several times.
- * @since 1.7
- */
-public interface JMXRemoteNamespaceMBean
- extends JMXNamespaceMBean {
-
- /**
- * Connects to the underlying remote source name space, if not already
- * {@link #isConnected connected}.
- * If connected, do nothing. Otherwise, creates a new connector from the
- * {@link javax.management.remote.JMXServiceURL JMXServiceURL} provided at
- * creation time, and connects to the remote source name space.
- * <p>
- * The source MBeans will not appear in the target name space until the
- * JMXRemoteNamespaceMBean is connected.
- * </p><p>
- * It is possible to call {@code connect()}, {@link #close close()}, and
- * {@code connect()} again.
- * However, closing the connection with the remote name space may cause
- * notification listeners to be lost, unless the client explicitly uses
- * the new {@linkplain javax.management.event JMX event service}.
- * </p><p>
- * @throws IOException if connection to the remote source name space fails.
- * @see #isConnected isConnected
- **/
- public void connect()
- throws IOException;
-
- /**
- * Closes the connection with the remote source name space.
- * If the connection is already closed, do nothing.
- * Otherwise, closes the underlying {@link
- * javax.management.remote.JMXConnector}.
- * <p>Once closed, it is possible to reopen the connection by
- * calling {@link #connect connect}.
- * </p>
- * @throws IOException if the connection to the remote source name space
- * can't be closed properly.
- * @see #isConnected isConnected
- **/
- public void close()
- throws IOException;
-
- /**
- * Tells whether the connection to the remote source name space is opened.
- * @see #connect connect
- * @see #close close
- * @return {@code true} if connected.
- **/
- public boolean isConnected();
-
- /**
- * Returns the {@link JMXServiceURL} address that points to the remote name
- * space mirrored by this {@link JMXNamespaceMBean JMXNamespace MBean},
- * if available.
- * @return The {@link JMXServiceURL} address that points to the remote name
- * space mirrored by this {@link JMXNamespaceMBean JMXNamespace MBean},
- * or {@code null}.
- */
- public JMXServiceURL getAddress();
-}
--- a/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,702 +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 javax.management.namespace;
-
-import com.sun.jmx.mbeanserver.Util;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.util.Set;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.OperationsException;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.loading.ClassLoaderRepository;
-
-/**
- * <p>An object of this class implements the MBeanServer interface
- * and, for each of its methods forwards the request to a wrapped
- * {@link MBeanServerConnection} object.
- * Some methods of the {@link MBeanServer} interface do not have
- * any equivalent in {@link MBeanServerConnection}. In that case, an
- * {@link UnsupportedOperationException} will be thrown.
- *
- * <p>A typical use of this class is to apply a {@link QueryExp} object locally,
- * on an MBean that resides in a remote MBeanServer. Since an
- * MBeanServerConnection is not an MBeanServer, it cannot be passed
- * to the <code>setMBeanServer()</code> method of the {@link QueryExp}
- * object. However, this object can.</p>
- *
- * @since 1.7
- */
-public class MBeanServerConnectionWrapper
- implements MBeanServer {
-
- private final MBeanServerConnection wrapped;
- private final ClassLoader defaultCl;
-
- /**
- * Construct a new object that implements {@link MBeanServer} by
- * forwarding its methods to the given {@link MBeanServerConnection}.
- * This constructor is equivalent to {@link #MBeanServerConnectionWrapper(
- * MBeanServerConnection, ClassLoader) MBeanServerConnectionWrapper(wrapped,
- * null)}.
- *
- * @param wrapped the {@link MBeanServerConnection} to which methods
- * are to be forwarded. This parameter can be null, in which case the
- * {@code MBeanServerConnection} will typically be supplied by overriding
- * {@link #getMBeanServerConnection}.
- */
- public MBeanServerConnectionWrapper(MBeanServerConnection wrapped) {
- this(wrapped, null);
- }
-
- /**
- * Construct a new object that implements {@link MBeanServer} by
- * forwarding its methods to the given {@link MBeanServerConnection}.
- * The {@code defaultCl} parameter specifies the value to be returned
- * by {@link #getDefaultClassLoader}. A null value is equivalent to
- * {@link Thread#getContextClassLoader()}.
- *
- * @param wrapped the {@link MBeanServerConnection} to which methods
- * are to be forwarded. This parameter can be null, in which case the
- * {@code MBeanServerConnection} will typically be supplied by overriding
- * {@link #getMBeanServerConnection}.
- * @param defaultCl the value to be returned by {@link
- * #getDefaultClassLoader}. A null value is equivalent to the current
- * thread's {@linkplain Thread#getContextClassLoader()}.
- */
- public MBeanServerConnectionWrapper(MBeanServerConnection wrapped,
- ClassLoader defaultCl) {
- this.wrapped = wrapped;
- this.defaultCl = (defaultCl == null) ?
- Thread.currentThread().getContextClassLoader() : defaultCl;
- }
-
- /**
- * Returns an MBeanServerConnection. This method is called each time
- * an operation must be invoked on the underlying MBeanServerConnection.
- * The default implementation returns the MBeanServerConnection that
- * was supplied to the constructor of this MBeanServerConnectionWrapper.
- **/
- protected MBeanServerConnection getMBeanServerConnection() {
- return wrapped;
- }
-
- /**
- * Returns the default class loader passed to the constructor. If the
- * value passed was null, then the returned value will be the
- * {@linkplain Thread#getContextClassLoader() context class loader} at the
- * time this object was constructed.
- *
- * @return the ClassLoader that was passed to the constructor.
- **/
- public ClassLoader getDefaultClassLoader() {
- return defaultCl;
- }
-
- /**
- * <p>This method is called each time an IOException is raised when
- * trying to forward an operation to the underlying
- * MBeanServerConnection, as a result of calling
- * {@link #getMBeanServerConnection()} or as a result of invoking the
- * operation on the returned connection. Since the methods in
- * {@link MBeanServer} are not declared to throw {@code IOException},
- * this method must return a {@code RuntimeException} to be thrown
- * instead. Typically, the original {@code IOException} will be in the
- * {@linkplain Throwable#getCause() cause chain} of the {@code
- * RuntimeException}.</p>
- *
- * <p>Subclasses may redefine this method if they need to perform any
- * specific handling of IOException (logging etc...).</p>
- *
- * @param x The raised IOException.
- * @param method The name of the method in which the exception was
- * raised. This is one of the methods of the MBeanServer
- * interface.
- *
- * @return A RuntimeException that should be thrown by the caller.
- * In this default implementation, this is a
- * {@link RuntimeException} wrapping <var>x</var>.
- **/
- protected RuntimeException wrapIOException(IOException x, String method) {
- return Util.newRuntimeIOException(x);
- }
-
- // Take care of getMBeanServerConnection returning null.
- //
- private synchronized MBeanServerConnection connection()
- throws IOException {
- final MBeanServerConnection c = getMBeanServerConnection();
- if (c == null)
- throw new IOException("MBeanServerConnection unavailable");
- return c;
- }
-
- //--------------------------------------------
- //--------------------------------------------
- //
- // Implementation of the MBeanServer interface
- //
- //--------------------------------------------
- //--------------------------------------------
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- try {
- connection().addNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw wrapIOException(x,"addNotificationListener");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void addNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- try {
- connection().addNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw wrapIOException(x,"addNotificationListener");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public ObjectInstance createMBean(String className, ObjectName name)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException {
- try {
- return connection().createMBean(className, name);
- } catch (IOException x) {
- throw wrapIOException(x,"createMBean");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public ObjectInstance createMBean(String className, ObjectName name,
- Object params[], String signature[])
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException {
- try {
- return connection().createMBean(className, name,
- params, signature);
- } catch (IOException x) {
- throw wrapIOException(x,"createMBean");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException {
- try {
- return connection().createMBean(className, name, loaderName);
- } catch (IOException x) {
- throw wrapIOException(x,"createMBean");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- Object params[],
- String signature[])
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException {
- try {
- return connection().createMBean(className, name, loaderName,
- params, signature);
- } catch (IOException x) {
- throw wrapIOException(x,"createMBean");
- }
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- * @deprecated see {@link MBeanServer#deserialize(ObjectName,byte[])
- * MBeanServer}
- */
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException {
- throw new UnsupportedOperationException("deserialize");
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- * @deprecated see {@link MBeanServer#deserialize(String,byte[])
- * MBeanServer}
- */
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException {
- throw new UnsupportedOperationException("deserialize");
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- * @deprecated see {@link MBeanServer#deserialize(String,ObjectName,byte[])
- * MBeanServer}
- */
- @Deprecated
- public ObjectInputStream deserialize(String className,
- ObjectName loaderName,
- byte[] data)
- throws
- InstanceNotFoundException,
- OperationsException,
- ReflectionException {
- throw new UnsupportedOperationException("deserialize");
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public Object getAttribute(ObjectName name, String attribute)
- throws
- MBeanException,
- AttributeNotFoundException,
- InstanceNotFoundException,
- ReflectionException {
- try {
- return connection().getAttribute(name, attribute);
- } catch (IOException x) {
- throw wrapIOException(x,"getAttribute");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- try {
- return connection().getAttributes(name, attributes);
- } catch (IOException x) {
- throw wrapIOException(x,"getAttributes");
- }
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- */
- public ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- throw new UnsupportedOperationException("getClassLoader");
- }
-
- /**
- * Returns the {@linkplain #getDefaultClassLoader() default class loader}.
- * This behavior can be changed by subclasses.
- */
- public ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- return getDefaultClassLoader();
- }
-
- /**
- * <p>Returns a {@link ClassLoaderRepository} based on the class loader
- * returned by {@link #getDefaultClassLoader()}.</p>
- * @return a {@link ClassLoaderRepository} that contains a single
- * class loader, returned by {@link #getDefaultClassLoader()}.
- **/
- public ClassLoaderRepository getClassLoaderRepository() {
- // We return a new ClassLoaderRepository each time this method is
- // called. This is by design, because there's no guarantee that
- // getDefaultClassLoader() will always return the same class loader.
- return Util.getSingleClassLoaderRepository(getDefaultClassLoader());
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public String getDefaultDomain() {
- try {
- return connection().getDefaultDomain();
- } catch (IOException x) {
- throw wrapIOException(x,"getDefaultDomain");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public String[] getDomains() {
- try {
- return connection().getDomains();
- } catch (IOException x) {
- throw wrapIOException(x,"getDomains");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public Integer getMBeanCount() {
- try {
- return connection().getMBeanCount();
- } catch (IOException x) {
- throw wrapIOException(x,"getMBeanCount");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws
- InstanceNotFoundException,
- IntrospectionException,
- ReflectionException {
- try {
- return connection().getMBeanInfo(name);
- } catch (IOException x) {
- throw wrapIOException(x,"getMBeanInfo");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- try {
- return connection().getObjectInstance(name);
- } catch (IOException x) {
- throw wrapIOException(x,"getObjectInstance");
- }
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- */
- public Object instantiate(String className)
- throws ReflectionException, MBeanException {
- throw new UnsupportedOperationException("instantiate");
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- */
- public Object instantiate(String className,
- Object params[],
- String signature[])
- throws ReflectionException, MBeanException {
- throw new UnsupportedOperationException("instantiate");
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- */
- public Object instantiate(String className, ObjectName loaderName)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- throw new UnsupportedOperationException("instantiate");
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- */
- public Object instantiate(String className, ObjectName loaderName,
- Object params[], String signature[])
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- throw new UnsupportedOperationException("instantiate");
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public Object invoke(ObjectName name, String operationName,
- Object params[], String signature[])
- throws
- InstanceNotFoundException,
- MBeanException,
- ReflectionException {
- try {
- return connection().invoke(name,operationName,params,signature);
- } catch (IOException x) {
- throw wrapIOException(x,"invoke");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- try {
- return connection().isInstanceOf(name, className);
- } catch (IOException x) {
- throw wrapIOException(x,"isInstanceOf");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public boolean isRegistered(ObjectName name) {
- try {
- return connection().isRegistered(name);
- } catch (IOException x) {
- throw wrapIOException(x,"isRegistered");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- * If an IOException is raised, returns an empty Set.
- */
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- try {
- return connection().queryMBeans(name, query);
- } catch (IOException x) {
- throw wrapIOException(x,"queryMBeans");
- //return Collections.emptySet();
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- * If an IOException is raised, returns an empty Set.
- */
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- try {
- return connection().queryNames(name, query);
- } catch (IOException x) {
- throw wrapIOException(x,"queryNames");
- //return Collections.emptySet();
- }
- }
-
- /**
- * Throws an {@link UnsupportedOperationException}. This behavior can
- * be changed by subclasses.
- */
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- NotCompliantMBeanException {
- throw new UnsupportedOperationException("registerMBean");
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- connection().removeNotificationListener(name, listener);
- } catch (IOException x) {
- throw wrapIOException(x,"removeNotificationListener");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- connection().removeNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw wrapIOException(x,"removeNotificationListener");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void removeNotificationListener(ObjectName name,
- ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- connection().removeNotificationListener(name, listener);
- } catch (IOException x) {
- throw wrapIOException(x,"removeNotificationListener");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- try {
- connection().removeNotificationListener(name, listener,
- filter, handback);
- } catch (IOException x) {
- throw wrapIOException(x,"removeNotificationListener");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void setAttribute(ObjectName name, Attribute attribute)
- throws
- InstanceNotFoundException,
- AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException {
- try {
- connection().setAttribute(name, attribute);
- } catch (IOException x) {
- throw wrapIOException(x,"setAttribute");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public AttributeList setAttributes(ObjectName name,
- AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- try {
- return connection().setAttributes(name, attributes);
- } catch (IOException x) {
- throw wrapIOException(x,"setAttributes");
- }
- }
-
- /**
- * Forward this method to the
- * wrapped object.
- */
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException {
- try {
- connection().unregisterMBean(name);
- } catch (IOException x) {
- throw wrapIOException(x,"unregisterMBean");
- }
- }
-
- //----------------
- // PRIVATE METHODS
- //----------------
-
-}
--- a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1321 +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 javax.management.namespace;
-
-import com.sun.jmx.defaults.JmxProperties;
-import com.sun.jmx.mbeanserver.Util;
-import java.io.ObjectInputStream;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-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;
-import javax.management.InvalidAttributeValueException;
-import javax.management.JMRuntimeException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationBroadcaster;
-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.RuntimeOperationsException;
-import javax.management.loading.ClassLoaderRepository;
-
-/**
- * <p>Base class for custom implementations of the {@link MBeanServer}
- * interface. The commonest use of this class is as the {@linkplain
- * JMXNamespace#getSourceServer() source server} for a {@link
- * JMXNamespace}, although this class can be used anywhere an {@code
- * MBeanServer} instance is required. Note that the usual ways to
- * obtain an {@code MBeanServer} instance are either to use {@link
- * java.lang.management.ManagementFactory#getPlatformMBeanServer()
- * ManagementFactory.getPlatformMBeanServer()} or to use the {@code
- * newMBeanServer} or {@code createMBeanServer} methods from {@link
- * javax.management.MBeanServerFactory MBeanServerFactory}. {@code
- * MBeanServerSupport} is for certain cases where those are not
- * appropriate.</p>
- *
- * <p>There are two main use cases for this class: <a
- * href="#special-purpose">special-purpose MBeanServer implementations</a>,
- * and <a href="#virtual">namespaces containing Virtual MBeans</a>. The next
- * sections explain these use cases.</p>
- *
- * <p>In the simplest case, a subclass needs to implement only two methods:</p>
- *
- * <ul>
- * <li>
- * {@link #getNames getNames} which returns the name of
- * all MBeans handled by this {@code MBeanServer}.
- * </li>
- * <li>
- * {@link #getDynamicMBeanFor getDynamicMBeanFor} which returns a
- * {@link DynamicMBean} that can be used to invoke operations and
- * obtain meta data (MBeanInfo) on a given MBean.
- * </li>
- * </ul>
- *
- * <p>Subclasses can create such {@link DynamicMBean} MBeans on the fly - for
- * instance, using the class {@link javax.management.StandardMBean}, just for
- * the duration of an MBeanServer method call.</p>
- *
- * <h4 id="special-purpose">Special-purpose MBeanServer implementations</h4>
- *
- * <p>In some cases
- * the general-purpose {@code MBeanServer} that you get from
- * {@link javax.management.MBeanServerFactory MBeanServerFactory} is not
- * appropriate. You might need different security checks, or you might
- * want a mock {@code MBeanServer} suitable for use in tests, or you might
- * want a simplified and optimized {@code MBeanServer} for a special purpose.</p>
- *
- * <p>As an example of a special-purpose {@code MBeanServer}, the class {@link
- * javax.management.QueryNotificationFilter QueryNotificationFilter} constructs
- * an {@code MBeanServer} instance every time it filters a notification,
- * with just one MBean that represents the notification. Although it could
- * use {@code MBeanServerFactory.newMBeanServer}, a special-purpose {@code
- * MBeanServer} will be quicker to create, use less memory, and have simpler
- * methods that execute faster.</p>
- *
- * <p>Here is an example of a special-purpose {@code MBeanServer}
- * implementation that contains exactly one MBean, which is specified at the
- * time of creation.</p>
- *
- * <pre>
- * public class SingletonMBeanServer extends MBeanServerSupport {
- * private final ObjectName objectName;
- * private final DynamicMBean mbean;
- *
- * public SingletonMBeanServer(ObjectName objectName, DynamicMBean mbean) {
- * this.objectName = objectName;
- * this.mbean = mbean;
- * }
- *
- * @Override
- * protected {@code Set<ObjectName>} {@link #getNames getNames}() {
- * return Collections.singleton(objectName);
- * }
- *
- * @Override
- * public DynamicMBean {@link #getDynamicMBeanFor
- * getDynamicMBeanFor}(ObjectName name)
- * throws InstanceNotFoundException {
- * if (objectName.equals(name))
- * return mbean;
- * else
- * throw new InstanceNotFoundException(name);
- * }
- * }
- * </pre>
- *
- * <p>Using this class, you could make an {@code MBeanServer} that contains
- * a {@link javax.management.timer.Timer Timer} MBean like this:</p>
- *
- * <pre>
- * Timer timer = new Timer();
- * DynamicMBean mbean = new {@link javax.management.StandardMBean
- * StandardMBean}(timer, TimerMBean.class);
- * ObjectName name = new ObjectName("com.example:type=Timer");
- * MBeanServer timerMBS = new SingletonMBeanServer(name, mbean);
- * </pre>
- *
- * <p>When {@code getDynamicMBeanFor} always returns the same object for the
- * same name, as here, notifications work in the expected way: if the object
- * is a {@link NotificationEmitter} then listeners can be added using
- * {@link MBeanServer#addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object) MBeanServer.addNotificationListener}. If
- * {@code getDynamicMBeanFor} does not always return the same object for the
- * same name, more work is needed to make notifications work, as described
- * <a href="#notifs">below</a>.</p>
- *
- * <h4 id="virtual">Namespaces containing Virtual MBeans</h4>
- *
- * <p>Virtual MBeans are MBeans that do not exist as Java objects,
- * except transiently while they are being accessed. This is useful when
- * there might be very many of them, or when keeping track of their creation
- * and deletion might be expensive or hard. For example, you might have one
- * MBean per system process. With an ordinary {@code MBeanServer}, you would
- * have to list the system processes in order to create an MBean object for
- * each one, and you would have to track the arrival and departure of system
- * processes in order to create or delete the corresponding MBeans. With
- * Virtual MBeans, you only need the MBean for a given process at the exact
- * point where it is referenced with a call such as
- * {@link MBeanServer#getAttribute MBeanServer.getAttribute}.</p>
- *
- * <p>Here is an example of an {@code MBeanServer} implementation that has
- * one MBean for every system property. The system property {@code "java.home"}
- * is represented by the MBean called {@code
- * com.example:type=Property,name="java.home"}, with an attribute called
- * {@code Value} that is the value of the property.</p>
- *
- * <pre>
- * public interface PropertyMBean {
- * public String getValue();
- * }
- *
- * <a name="PropsMBS"></a>public class PropsMBS extends MBeanServerSupport {
- * public static class PropertyImpl implements PropertyMBean {
- * private final String name;
- *
- * public PropertyImpl(String name) {
- * this.name = name;
- * }
- *
- * public String getValue() {
- * return System.getProperty(name);
- * }
- * }
- *
- * @Override
- * public DynamicMBean {@link #getDynamicMBeanFor
- * getDynamicMBeanFor}(ObjectName name)
- * throws InstanceNotFoundException {
- *
- * // Check that the name is a legal one for a Property MBean
- * ObjectName namePattern = ObjectName.valueOf(
- * "com.example:type=Property,name=\"*\"");
- * if (!namePattern.apply(name))
- * throw new InstanceNotFoundException(name);
- *
- * // Extract the name of the property that the MBean corresponds to
- * String propName = ObjectName.unquote(name.getKeyProperty("name"));
- * if (System.getProperty(propName) == null)
- * throw new InstanceNotFoundException(name);
- *
- * // Construct and return a transient MBean object
- * PropertyMBean propMBean = new PropertyImpl(propName);
- * return new StandardMBean(propMBean, PropertyMBean.class, false);
- * }
- *
- * @Override
- * protected {@code Set<ObjectName>} {@link #getNames getNames}() {
- * {@code Set<ObjectName> names = new TreeSet<ObjectName>();}
- * Properties props = System.getProperties();
- * for (String propName : props.stringPropertyNames()) {
- * ObjectName objectName = ObjectName.valueOf(
- * "com.example:type=Property,name=" +
- * ObjectName.quote(propName));
- * names.add(objectName);
- * }
- * return names;
- * }
- * }
- * </pre>
- *
- * <p id="virtual-notif-example">Because the {@code getDynamicMBeanFor} method
- * returns a different object every time it is called, the default handling
- * of notifications will not work, as explained <a href="#notifs">below</a>.
- * In this case it does not matter, because the object returned by {@code
- * getDynamicMBeanFor} is not a {@code NotificationEmitter}, so {@link
- * MBeanServer#addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object) MBeanServer.addNotificationListener} will
- * always fail. But if we wanted to extend {@code PropsMBS} so that the MBean
- * for property {@code "foo"} emitted a notification every time that property
- * changed, we would need to do it as shown below. (Because there is no API to
- * be informed when a property changes, this code assumes that some other code
- * calls the {@code propertyChanged} method every time a property changes.)</p>
- *
- * <pre>
- * public class PropsMBS {
- * ...as <a href="#PropsMBS">above</a>...
- *
- * private final {@link VirtualEventManager} vem = new VirtualEventManager();
- *
- * @Override
- * public NotificationEmitter {@link #getNotificationEmitterFor
- * getNotificationEmitterFor}(
- * ObjectName name) throws InstanceNotFoundException {
- * getDynamicMBeanFor(name); // check that the name is valid
- * return vem.{@link VirtualEventManager#getNotificationEmitterFor
- * getNotificationEmitterFor}(name);
- * }
- *
- * public void propertyChanged(String name, String newValue) {
- * ObjectName objectName = ObjectName.valueOf(
- * "com.example:type=Property,name=" + ObjectName.quote(name));
- * Notification n = new Notification(
- * "com.example.property.changed", objectName, 0L,
- * "Property " + name + " changed");
- * n.setUserData(newValue);
- * vem.{@link VirtualEventManager#publish publish}(objectName, n);
- * }
- * }
- * </pre>
- *
- * <h4 id="creation">MBean creation and deletion</h4>
- *
- * <p>MBean creation through {@code MBeanServer.createMBean} is disabled
- * by default. Subclasses which need to support MBean creation
- * through {@code createMBean} need to implement a single method {@link
- * #createMBean(String, ObjectName, ObjectName, Object[], String[],
- * boolean)}.</p>
- *
- * <p>Similarly MBean registration and unregistration through {@code
- * registerMBean} and {@code unregisterMBean} are disabled by default.
- * Subclasses which need to support MBean registration and
- * unregistration will need to implement {@link #registerMBean registerMBean}
- * and {@link #unregisterMBean unregisterMBean}.</p>
- *
- * <h4 id="notifs">Notifications</h4>
- *
- * <p>By default {@link MBeanServer#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object) addNotificationListener}
- * is accepted for an MBean <em>{@code name}</em> if {@link #getDynamicMBeanFor
- * getDynamicMBeanFor}<code>(<em>name</em>)</code> returns an object that is a
- * {@link NotificationEmitter}. That is appropriate if
- * {@code getDynamicMBeanFor}<code>(<em>name</em>)</code> always returns the
- * same object for the same <em>{@code name}</em>. But with
- * Virtual MBeans, every call to {@code getDynamicMBeanFor} returns a new object,
- * which is discarded as soon as the MBean request has finished.
- * So a listener added to that object would be immediately forgotten.</p>
- *
- * <p>The simplest way for a subclass that defines Virtual MBeans
- * to support notifications is to create a private {@link VirtualEventManager}
- * and override the method {@link
- * #getNotificationEmitterFor getNotificationEmitterFor} as follows:</p>
- *
- * <pre>
- * private final VirtualEventManager vem = new VirtualEventManager();
- *
- * @Override
- * public NotificationEmitter getNotificationEmitterFor(
- * ObjectName name) throws InstanceNotFoundException {
- * // Check that the name is a valid Virtual MBean.
- * // This is the easiest way to do that, but not always the
- * // most efficient:
- * getDynamicMBeanFor(name);
- *
- * // Return an object that supports add/removeNotificationListener
- * // through the VirtualEventManager.
- * return vem.getNotificationEmitterFor(name);
- * }
- * </pre>
- *
- * <p>A notification <em>{@code n}</em> can then be sent from the Virtual MBean
- * called <em>{@code name}</em> by calling {@link VirtualEventManager#publish
- * vem.publish}<code>(<em>name</em>, <em>n</em>)</code>. See the example
- * <a href="#virtual-notif-example">above</a>.</p>
- *
- * @since 1.7
- */
-public abstract class MBeanServerSupport implements MBeanServer {
-
- /**
- * A logger for this class.
- */
- private static final Logger LOG =
- JmxProperties.NAMESPACE_LOGGER;
-
- /**
- * <p>Make a new {@code MBeanServerSupport} instance.</p>
- */
- protected MBeanServerSupport() {
- }
-
- /**
- * <p>Returns a dynamically created handle that makes it possible to
- * access the named MBean for the duration of a method call.</p>
- *
- * <p>An easy way to create such a {@link DynamicMBean} handle is, for
- * instance, to create a temporary MXBean instance and to wrap it in
- * an instance of
- * {@link javax.management.StandardMBean}.
- * This handle should remain valid for the duration of the call
- * but can then be discarded.</p>
- * @param name the name of the MBean for which a request was received.
- * @return a {@link DynamicMBean} handle that can be used to invoke
- * operations on the named MBean.
- * @throws InstanceNotFoundException if no such MBean is supposed
- * to exist.
- */
- public abstract DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException;
-
- /**
- * <p>Subclasses should implement this method to return
- * the names of all MBeans handled by this object instance.</p>
- *
- * <p>The object returned by getNames() should be safely {@linkplain
- * Set#iterator iterable} even in the presence of other threads that may
- * cause the set of names to change. Typically this means one of the
- * following:</p>
- *
- * <ul>
- * <li>the returned set of names is always the same; or
- * <li>the returned set of names is an object such as a {@link
- * java.util.concurrent.CopyOnWriteArraySet CopyOnWriteArraySet} that is
- * safely iterable even if the set is changed by other threads; or
- * <li>a new Set is constructed every time this method is called.
- * </ul>
- *
- * @return the names of all MBeans handled by this object.
- */
- protected abstract Set<ObjectName> getNames();
-
- /**
- * <p>List names matching the given pattern.
- * The default implementation of this method calls {@link #getNames()}
- * and returns the subset of those names matching {@code pattern}.</p>
- *
- * @param pattern an ObjectName pattern
- * @return the list of MBean names that match the given pattern.
- */
- protected Set<ObjectName> getMatchingNames(ObjectName pattern) {
- return Util.filterMatchingNames(pattern, getNames());
- }
-
- /**
- * <p>Returns a {@link NotificationEmitter} which can be used to
- * subscribe or unsubscribe for notifications with the named
- * mbean.</p>
- *
- * <p>The default implementation of this method calls {@link
- * #getDynamicMBeanFor getDynamicMBeanFor(name)} and returns that object
- * if it is a {@code NotificationEmitter}, otherwise null. See <a
- * href="#notifs">above</a> for further discussion of notification
- * handling.</p>
- *
- * @param name The name of the MBean whose notifications are being
- * subscribed, or unsuscribed.
- *
- * @return A {@link NotificationEmitter} that can be used to subscribe or
- * unsubscribe for notifications emitted by the named MBean, or {@code
- * null} if the MBean does not emit notifications and should not be
- * considered as a {@code NotificationEmitter}.
- *
- * @throws InstanceNotFoundException if {@code name} is not the name of
- * an MBean in this {@code MBeanServer}.
- */
- public NotificationEmitter getNotificationEmitterFor(ObjectName name)
- throws InstanceNotFoundException {
- DynamicMBean mbean = getDynamicMBeanFor(name);
- if (mbean instanceof NotificationEmitter)
- return (NotificationEmitter) mbean;
- else
- return null;
- }
-
- private NotificationEmitter getNonNullNotificationEmitterFor(
- ObjectName name)
- throws InstanceNotFoundException {
- NotificationEmitter emitter = getNotificationEmitterFor(name);
- if (emitter == null) {
- IllegalArgumentException iae = new IllegalArgumentException(
- "Not a NotificationEmitter: " + name);
- throw new RuntimeOperationsException(iae);
- }
- return emitter;
- }
-
- /**
- * <p>Creates a new MBean in the MBean name space.
- * This operation is not supported in this base class implementation.</p>
- * The default implementation of this method always throws an {@link
- * UnsupportedOperationException}
- * wrapped in a {@link RuntimeOperationsException}.</p>
- *
- * <p>Subclasses may redefine this method to provide an implementation.
- * All the various flavors of {@code MBeanServer.createMBean} methods
- * will eventually call this method. A subclass that wishes to
- * support MBean creation through {@code createMBean} thus only
- * needs to provide an implementation for this one method.</p>
- *
- * <p>A subclass implementation of this method should respect the contract
- * of the various {@code createMBean} methods in the {@link MBeanServer}
- * interface, in particular as regards exception wrapping.</p>
- *
- * @param className The class name of the MBean to be instantiated.
- * @param name The object name of the MBean. May be null.
- * @param params An array containing the parameters of the
- * constructor to be invoked.
- * @param signature An array containing the signature of the
- * constructor to be invoked.
- * @param loaderName The object name of the class loader to be used.
- * @param useCLR This parameter is {@code true} when this method
- * is called from one of the {@code MBeanServer.createMBean} methods
- * whose signature does not include the {@code ObjectName} of an
- * MBean class loader to use for loading the MBean class.
- *
- * @return An <CODE>ObjectInstance</CODE>, containing the
- * <CODE>ObjectName</CODE> and the Java class name of the newly
- * instantiated MBean. If the contained <code>ObjectName</code>
- * is <code>n</code>, the contained Java class name is
- * <code>{@link javax.management.MBeanServer#getMBeanInfo
- * getMBeanInfo(n)}.getClassName()</code>.
- *
- * @exception ReflectionException Wraps a
- * <CODE>java.lang.ClassNotFoundException</CODE> or a
- * <CODE>java.lang.Exception</CODE> that occurred when trying to
- * invoke the MBean's constructor.
- * @exception InstanceAlreadyExistsException The MBean is already
- * under the control of the MBean server.
- * @exception MBeanRegistrationException The
- * <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
- * interface) method of the MBean has thrown an exception. The
- * MBean will not be registered.
- * @exception RuntimeMBeanException If the MBean's constructor or its
- * {@code preRegister} or {@code postRegister} method threw
- * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
- * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
- * <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
- * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
- * and registration succeeded. In such a case, the MBean will be actually
- * registered even though the <CODE>createMBean</CODE> method
- * threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
- * also be thrown by <CODE>preRegister</CODE>, in which case the MBean
- * will not be registered.
- * @exception MBeanException The constructor of the MBean has
- * thrown an exception
- * @exception NotCompliantMBeanException This class is not a JMX
- * compliant MBean
- * @exception InstanceNotFoundException The specified class loader
- * is not registered in the MBean server.
- * @exception RuntimeOperationsException Wraps either:
- * <ul>
- * <li>a <CODE>java.lang.IllegalArgumentException</CODE>: The className
- * passed in parameter is null, the <CODE>ObjectName</CODE> passed in
- * parameter contains a pattern or no <CODE>ObjectName</CODE> is specified
- * for the MBean; or</li>
- * <li>an {@code UnsupportedOperationException} if creating MBeans is not
- * supported by this {@code MBeanServer} implementation.
- * </ul>
- */
- public ObjectInstance createMBean(String className,
- ObjectName name, ObjectName loaderName, Object[] params,
- String[] signature, boolean useCLR)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- throw newUnsupportedException("createMBean");
- }
-
-
- /**
- * <p>Attempts to determine whether the named MBean should be
- * considered as an instance of a given class. The default implementation
- * of this method calls {@link #getDynamicMBeanFor getDynamicMBeanFor(name)}
- * to get an MBean object. Then its behaviour is the same as the standard
- * {@link MBeanServer#isInstanceOf MBeanServer.isInstanceOf} method.</p>
- *
- * {@inheritDoc}
- */
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
-
- final DynamicMBean instance = nonNullMBeanFor(name);
-
- try {
- final String mbeanClassName = instance.getMBeanInfo().getClassName();
-
- if (mbeanClassName.equals(className))
- return true;
-
- final Object resource;
- final ClassLoader cl;
- if (instance instanceof DynamicWrapperMBean) {
- DynamicWrapperMBean d = (DynamicWrapperMBean) instance;
- resource = d.getWrappedObject();
- cl = d.getWrappedClassLoader();
- } else {
- resource = instance;
- cl = instance.getClass().getClassLoader();
- }
-
- final Class<?> classNameClass = Class.forName(className, false, cl);
-
- if (classNameClass.isInstance(resource))
- return true;
-
- if (classNameClass == NotificationBroadcaster.class ||
- classNameClass == NotificationEmitter.class) {
- try {
- getNotificationEmitterFor(name);
- return true;
- } catch (Exception x) {
- LOG.finest("MBean " + name +
- " is not a notification emitter. Ignoring: "+x);
- return false;
- }
- }
-
- final Class<?> resourceClass = Class.forName(mbeanClassName, false, cl);
- return classNameClass.isAssignableFrom(resourceClass);
- } catch (Exception x) {
- /* Could be SecurityException or ClassNotFoundException */
- LOG.logp(Level.FINEST,
- MBeanServerSupport.class.getName(),
- "isInstanceOf", "Exception calling isInstanceOf", x);
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method returns the string
- * "DefaultDomain".</p>
- */
- public String getDefaultDomain() {
- return "DefaultDomain";
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method returns
- * {@link #getNames()}.size().</p>
- */
- public Integer getMBeanCount() {
- return getNames().size();
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method first calls {@link #getNames
- * getNames()} to get a list of all MBean names,
- * and from this set of names, derives the set of domains which contain
- * MBeans.</p>
- */
- public String[] getDomains() {
- final Set<ObjectName> names = getNames();
- final Set<String> res = new TreeSet<String>();
- for (ObjectName n : names) {
- if (n == null) continue; // not allowed but you never know.
- res.add(n.getDomain());
- }
- return res.toArray(new String[res.size()]);
- }
-
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link
- * #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a handle
- * to the named MBean,
- * and then call {@link DynamicMBean#getAttribute getAttribute}
- * on that {@link DynamicMBean} handle.</p>
- *
- * @throws RuntimeOperationsException {@inheritDoc}
- */
- public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException,
- InstanceNotFoundException, ReflectionException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- return mbean.getAttribute(attribute);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)}
- * to obtain a handle to the named MBean,
- * and then call {@link DynamicMBean#setAttribute setAttribute}
- * on that {@link DynamicMBean} handle.</p>
- *
- * @throws RuntimeOperationsException {@inheritDoc}
- */
- public void setAttribute(ObjectName name, Attribute attribute)
- throws InstanceNotFoundException, AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- mbean.setAttribute(attribute);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a
- * handle to the named MBean,
- * and then call {@link DynamicMBean#getAttributes getAttributes}
- * on that {@link DynamicMBean} handle.</p>
- *
- * @throws RuntimeOperationsException {@inheritDoc}
- */
- public AttributeList getAttributes(ObjectName name,
- String[] attributes) throws InstanceNotFoundException,
- ReflectionException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- return mbean.getAttributes(attributes);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a
- * handle to the named MBean,
- * and then call {@link DynamicMBean#setAttributes setAttributes}
- * on that {@link DynamicMBean} handle.</p>
- *
- * @throws RuntimeOperationsException {@inheritDoc}
- */
- public AttributeList setAttributes(ObjectName name, AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- return mbean.setAttributes(attributes);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a
- * handle to the named MBean,
- * and then call {@link DynamicMBean#invoke invoke}
- * on that {@link DynamicMBean} handle.</p>
- */
- public Object invoke(ObjectName name, String operationName,
- Object[] params, String[] signature)
- throws InstanceNotFoundException, MBeanException,
- ReflectionException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- return mbean.invoke(operationName, params, signature);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a
- * handle to the named MBean,
- * and then call {@link DynamicMBean#getMBeanInfo getMBeanInfo}
- * on that {@link DynamicMBean} handle.</p>
- */
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, IntrospectionException,
- ReflectionException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- return mbean.getMBeanInfo();
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will call
- * {@link #getDynamicMBeanFor getDynamicMBeanFor(name)}.<!--
- * -->{@link DynamicMBean#getMBeanInfo getMBeanInfo()}.<!--
- * -->{@link MBeanInfo#getClassName getClassName()} to get the
- * class name to combine with {@code name} to produce a new
- * {@code ObjectInstance}.</p>
- */
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- final DynamicMBean mbean = nonNullMBeanFor(name);
- final String className = mbean.getMBeanInfo().getClassName();
- return new ObjectInstance(name, className);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first call {@link
- * #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a handle to the
- * named MBean. If {@code getDynamicMBeanFor} returns an object, {@code
- * isRegistered} will return true. If {@code getDynamicMBeanFor} returns
- * null or throws {@link InstanceNotFoundException}, {@code isRegistered}
- * will return false.</p>
- *
- * @throws RuntimeOperationsException {@inheritDoc}
- */
- public boolean isRegistered(ObjectName name) {
- try {
- final DynamicMBean mbean = getDynamicMBeanFor(name);
- return mbean!=null;
- } catch (InstanceNotFoundException x) {
- if (LOG.isLoggable(Level.FINEST))
- LOG.finest("MBean "+name+" is not registered: "+x);
- return false;
- }
- }
-
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method will first
- * call {@link #queryNames queryNames}
- * to get a list of all matching MBeans, and then, for each returned name,
- * call {@link #getObjectInstance getObjectInstance(name)}.</p>
- */
- public Set<ObjectInstance> queryMBeans(ObjectName pattern, QueryExp query) {
- final Set<ObjectName> names = queryNames(pattern, query);
- if (names.isEmpty()) return Collections.emptySet();
- final Set<ObjectInstance> mbeans = new HashSet<ObjectInstance>();
- for (ObjectName name : names) {
- try {
- mbeans.add(getObjectInstance(name));
- } catch (SecurityException x) { // DLS: OK
- continue;
- } catch (InstanceNotFoundException x) { // DLS: OK
- continue;
- }
- }
- return mbeans;
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method calls {@link #getMatchingNames
- * getMatchingNames(pattern)} to obtain a list of MBeans matching
- * the given name pattern. If the {@code query} parameter is null,
- * this will be the result. Otherwise, it will evaluate the
- * {@code query} parameter for each of the returned names, exactly
- * as an {@code MBeanServer} would. This might result in
- * {@link #getDynamicMBeanFor getDynamicMBeanFor} being called
- * several times for each returned name.</p>
- */
- public Set<ObjectName> queryNames(ObjectName pattern, QueryExp query) {
- try {
- final Set<ObjectName> res = getMatchingNames(pattern);
- return filterListOfObjectNames(res, query);
- } catch (Exception x) {
- LOG.fine("Unexpected exception raised in queryNames: "+x);
- LOG.log(Level.FINEST, "Unexpected exception raised in queryNames", x);
- }
- // We reach here only when an exception was raised.
- //
- return Collections.emptySet();
- }
-
- private final static boolean apply(final QueryExp query,
- final ObjectName on,
- final MBeanServer srv) {
- boolean res = false;
- MBeanServer oldServer = QueryEval.getMBeanServer();
- query.setMBeanServer(srv);
- try {
- res = query.apply(on);
- } catch (Exception e) {
- LOG.finest("QueryExp.apply threw exception, returning false." +
- " Cause: "+e);
- res = false;
- } finally {
- /*
- * query.setMBeanServer is probably
- * QueryEval.setMBeanServer so put back the old
- * value. Since that method uses a ThreadLocal
- * variable, this code is only needed for the
- * unusual case where the user creates a custom
- * QueryExp that calls a nested query on another
- * MBeanServer.
- */
- query.setMBeanServer(oldServer);
- }
- return res;
- }
-
- /**
- * Filters a {@code Set<ObjectName>} according to a pattern and a query.
- * This might be quite inefficient for virtual name spaces.
- */
- Set<ObjectName>
- filterListOfObjectNames(Set<ObjectName> list,
- QueryExp query) {
- if (list.isEmpty() || query == null)
- return list;
-
- // create a new result set
- final Set<ObjectName> result = new HashSet<ObjectName>();
-
- for (ObjectName on : list) {
- // if on doesn't match query exclude it.
- if (apply(query, on, this))
- result.add(on);
- }
- return result;
- }
-
-
- // Don't use {@inheritDoc}, because we don't want to say that the
- // MBeanServer replaces a reference to the MBean by its ObjectName.
- /**
- * <p>Adds a listener to a registered MBean. A notification emitted by
- * the MBean will be forwarded to the listener.</p>
- *
- * <p>This implementation calls
- * {@link #getNotificationEmitterFor getNotificationEmitterFor}
- * and invokes {@code addNotificationListener} on the
- * {@link NotificationEmitter} it returns.
- *
- * @see #getDynamicMBeanFor getDynamicMBeanFor
- * @see #getNotificationEmitterFor getNotificationEmitterFor
- */
- public void addNotificationListener(ObjectName name,
- NotificationListener listener, NotificationFilter filter,
- Object handback) throws InstanceNotFoundException {
- final NotificationEmitter emitter =
- getNonNullNotificationEmitterFor(name);
- emitter.addNotificationListener(listener, filter, handback);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This implementation calls
- * {@link #getNotificationEmitterFor getNotificationEmitterFor}
- * and invokes {@code removeNotificationListener} on the
- * {@link NotificationEmitter} it returns.
- * @see #getDynamicMBeanFor getDynamicMBeanFor
- * @see #getNotificationEmitterFor getNotificationEmitterFor
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- final NotificationEmitter emitter =
- getNonNullNotificationEmitterFor(name);
- emitter.removeNotificationListener(listener);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This implementation calls
- * {@link #getNotificationEmitterFor getNotificationEmitterFor}
- * and invokes {@code removeNotificationListener} on the
- * {@link NotificationEmitter} it returns.
- * @see #getDynamicMBeanFor getDynamicMBeanFor
- * @see #getNotificationEmitterFor getNotificationEmitterFor
- */
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener, NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- NotificationEmitter emitter =
- getNonNullNotificationEmitterFor(name);
- emitter.removeNotificationListener(listener);
- }
-
-
- /**
- * <p>Adds a listener to a registered MBean.</p>
- *
- * <p>The default implementation of this method first calls
- * {@link #getDynamicMBeanFor getDynamicMBeanFor(listenerName)}.
- * If that successfully returns an object, call it {@code
- * mbean}, then (a) if {@code mbean} is an instance of {@link
- * NotificationListener} then this method calls {@link
- * #addNotificationListener(ObjectName, NotificationListener,
- * NotificationFilter, Object) addNotificationListener(name, mbean, filter,
- * handback)}, otherwise (b) this method throws an exception as specified
- * for this case.</p>
- *
- * <p>This default implementation is not appropriate for Virtual MBeans,
- * although that only matters if the object returned by {@code
- * getDynamicMBeanFor} can be an instance of
- * {@code NotificationListener}.</p>
- *
- * @throws RuntimeOperationsException {@inheritDoc}
- */
- public void addNotificationListener(ObjectName name, ObjectName listenerName,
- NotificationFilter filter, Object handback)
- throws InstanceNotFoundException {
- NotificationListener listener = getListenerMBean(listenerName);
- addNotificationListener(name, listener, filter, handback);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public void removeNotificationListener(ObjectName name,
- ObjectName listenerName)
- throws InstanceNotFoundException, ListenerNotFoundException {
- NotificationListener listener = getListenerMBean(listenerName);
- removeNotificationListener(name, listener);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public void removeNotificationListener(ObjectName name,
- ObjectName listenerName, NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- NotificationListener listener = getListenerMBean(listenerName);
- removeNotificationListener(name, listener, filter, handback);
- }
-
- private NotificationListener getListenerMBean(ObjectName listenerName)
- throws InstanceNotFoundException {
- Object mbean = getDynamicMBeanFor(listenerName);
- if (mbean instanceof NotificationListener)
- return (NotificationListener) mbean;
- else {
- throw newIllegalArgumentException(
- "MBean is not a NotificationListener: " + listenerName);
- }
- }
-
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link InstanceNotFoundException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @return the default implementation of this method never returns.
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- final UnsupportedOperationException failed =
- new UnsupportedOperationException("getClassLoader");
- final InstanceNotFoundException x =
- new InstanceNotFoundException(String.valueOf(loaderName));
- x.initCause(failed);
- throw x;
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method calls
- * {@link #getDynamicMBeanFor getDynamicMBeanFor(mbeanName)} and applies
- * the logic just described to the result.</p>
- */
- public ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- final DynamicMBean mbean = nonNullMBeanFor(mbeanName);
- if (mbean instanceof DynamicWrapperMBean)
- return ((DynamicWrapperMBean) mbean).getWrappedClassLoader();
- else
- return mbean.getClass().getClassLoader();
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation of this method returns a
- * {@link ClassLoaderRepository} containing exactly one loader,
- * the {@linkplain Thread#getContextClassLoader() context class loader}
- * for the current thread.
- * Subclasses can override this method to return a different
- * {@code ClassLoaderRepository}.</p>
- */
- public ClassLoaderRepository getClassLoaderRepository() {
- // We return a new ClassLoaderRepository each time this
- // method is called. This is by design, because the
- // SingletonClassLoaderRepository is a very small object and
- // getClassLoaderRepository() will not be called very often
- // (the connector server calls it once) - in the context of
- // MBeanServerSupport there's a very good chance that this method will
- // *never* be called.
- ClassLoader ccl = Thread.currentThread().getContextClassLoader();
- return Util.getSingleClassLoaderRepository(ccl);
- }
-
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException, MBeanRegistrationException,
- NotCompliantMBeanException {
- throw newUnsupportedException("registerMBean");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException {
- throw newUnsupportedException("unregisterMBean");
- }
-
- /**
- * Calls {@link #createMBean(String, ObjectName,
- * ObjectName, Object[], String[], boolean)
- * createMBean(className, name, null, params, signature, true)};
- */
- public final ObjectInstance createMBean(String className, ObjectName name,
- Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- try {
- return createMBean(className, name, null, params, signature, true);
- } catch (InstanceNotFoundException ex) {
- // should not happen!
- throw new MBeanException(ex, "Unexpected exception: " + ex);
- }
- }
-
- /**
- * Calls {@link #createMBean(String, ObjectName,
- * ObjectName, Object[], String[], boolean)
- * createMBean(className,name, loaderName, params, signature, false)};
- */
- public final ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName, Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- return createMBean(className, name, loaderName, params, signature, false);
- }
-
- /**
- * Calls {@link #createMBean(String, ObjectName,
- * ObjectName, Object[], String[], boolean)
- * createMBean(className, name, null, null, null, true)};
- */
- public final ObjectInstance createMBean(String className, ObjectName name)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- try {
- return createMBean(className, name, null, null, null, true);
- } catch (InstanceNotFoundException ex) {
- // should not happen!
- throw new MBeanException(ex, "Unexpected exception: " + ex);
- }
- }
-
- /**
- * Calls {@link #createMBean(String, ObjectName,
- * ObjectName, Object[], String[], boolean)
- * createMBean(className, name, loaderName, null, null, false)};
- */
- public final ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- return createMBean(className, name, loaderName, null, null, false);
- }
-
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public Object instantiate(String className)
- throws ReflectionException, MBeanException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public Object instantiate(String className, ObjectName loaderName)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public Object instantiate(String className, Object[] params,
- String[] signature) throws ReflectionException, MBeanException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- public Object instantiate(String className, ObjectName loaderName,
- Object[] params, String[] signature)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>This operation is not supported in this base class implementation.
- * The default implementation of this method always throws
- * {@link RuntimeOperationsException} wrapping
- * {@link UnsupportedOperationException}.</p>
- *
- * @throws javax.management.RuntimeOperationsException wrapping
- * {@link UnsupportedOperationException}
- */
- @Deprecated
- public ObjectInputStream deserialize(String className,
- ObjectName loaderName, byte[] data)
- throws InstanceNotFoundException, OperationsException,
- ReflectionException {
- throw new UnsupportedOperationException("Not applicable.");
- }
-
-
- // Calls getDynamicMBeanFor, and throws an InstanceNotFoundException
- // if the returned mbean is null.
- // The DynamicMBean returned by this method is thus guaranteed to be
- // non null.
- //
- private DynamicMBean nonNullMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (name == null)
- throw newIllegalArgumentException("Null ObjectName");
- if (name.getDomain().equals("")) {
- String defaultDomain = getDefaultDomain();
- try {
- name = name.withDomain(getDefaultDomain());
- } catch (Exception e) {
- throw newIllegalArgumentException(
- "Illegal default domain: " + defaultDomain);
- }
- }
- final DynamicMBean mbean = getDynamicMBeanFor(name);
- if (mbean!=null) return mbean;
- throw new InstanceNotFoundException(String.valueOf(name));
- }
-
- static RuntimeException newUnsupportedException(String operation) {
- return new RuntimeOperationsException(
- new UnsupportedOperationException(
- operation+": Not supported in this namespace"));
- }
-
- static RuntimeException newIllegalArgumentException(String msg) {
- return new RuntimeOperationsException(
- new IllegalArgumentException(msg));
- }
-
-}
--- a/jdk/src/share/classes/javax/management/namespace/VirtualEventManager.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,378 +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 javax.management.namespace;
-
-import com.sun.jmx.remote.util.ClassLogger;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.management.InstanceNotFoundException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.Notification;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventConsumer;
-
-/**
- * <p>This class maintains a list of subscribers for ObjectName patterns and
- * allows a notification to be sent to all subscribers for a given ObjectName.
- * It is typically used in conjunction with {@link MBeanServerSupport}
- * to implement a namespace with Virtual MBeans that can emit notifications.
- * The {@code VirtualEventManager} keeps track of the listeners that have been
- * added to each Virtual MBean. When an event occurs that should trigger a
- * notification from a Virtual MBean, the {@link #publish publish} method can
- * be used to send it to the appropriate listeners.</p>
- * @since 1.7
- */
-public class VirtualEventManager implements EventConsumer {
- /**
- * <p>Create a new {@code VirtualEventManager}.</p>
- */
- public VirtualEventManager() {
- }
-
- public void subscribe(
- ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
-
- if (logger.traceOn())
- logger.trace("subscribe", "" + name);
-
- if (name == null)
- throw new IllegalArgumentException("Null MBean name");
-
- if (listener == null)
- throw new IllegalArgumentException("Null listener");
-
- Map<ObjectName, List<ListenerInfo>> map =
- name.isPattern() ? patternSubscriptionMap : exactSubscriptionMap;
-
- final ListenerInfo li = new ListenerInfo(listener, filter, handback);
- List<ListenerInfo> list;
-
- synchronized (map) {
- list = map.get(name);
- if (list == null) {
- list = new ArrayList<ListenerInfo>();
- map.put(name, list);
- }
- list.add(li);
- }
- }
-
- public void unsubscribe(
- ObjectName name, NotificationListener listener)
- throws ListenerNotFoundException {
-
- if (logger.traceOn())
- logger.trace("unsubscribe2", "" + name);
-
- if (name == null)
- throw new IllegalArgumentException("Null MBean name");
-
- if (listener == null)
- throw new ListenerNotFoundException();
-
- Map<ObjectName, List<ListenerInfo>> map =
- name.isPattern() ? patternSubscriptionMap : exactSubscriptionMap;
-
- final ListenerInfo li = new ListenerInfo(listener, null, null);
- List<ListenerInfo> list;
- synchronized (map) {
- list = map.get(name);
- if (list == null || !list.remove(li))
- throw new ListenerNotFoundException();
-
- if (list.isEmpty())
- map.remove(name);
- }
- }
-
- /**
- * <p>Unsubscribes a listener which is listening to an MBean or a set of
- * MBeans represented by an {@code ObjectName} pattern.</p>
- *
- * <p>The listener to be removed must have been added by the {@link
- * #subscribe subscribe} method with the given {@code name}, {@code filter},
- * and {@code handback}. If the {@code
- * name} is a pattern, then the {@code subscribe} must have used the same
- * pattern. If the same listener has been subscribed more than once to the
- * {@code name} with the same filter and handback, only one listener is
- * removed.</p>
- *
- * @param name The name of the MBean or an {@code ObjectName} pattern
- * representing a set of MBeans to which the listener was subscribed.
- * @param listener A listener that was previously subscribed to the
- * MBean(s).
- *
- * @throws ListenerNotFoundException The given {@code listener} was not
- * subscribed to the given {@code name}.
- *
- * @see #subscribe
- */
- public void unsubscribe(
- ObjectName name, NotificationListener listener,
- NotificationFilter filter, Object handback)
- throws ListenerNotFoundException {
-
- if (logger.traceOn())
- logger.trace("unsubscribe4", "" + name);
-
- if (name == null)
- throw new IllegalArgumentException("Null MBean name");
-
- if (listener == null)
- throw new ListenerNotFoundException();
-
- Map<ObjectName, List<ListenerInfo>> map =
- name.isPattern() ? patternSubscriptionMap : exactSubscriptionMap;
-
- List<ListenerInfo> list;
- synchronized (map) {
- list = map.get(name);
- boolean removed = false;
- for (Iterator<ListenerInfo> it = list.iterator(); it.hasNext(); ) {
- ListenerInfo li = it.next();
- if (li.equals(listener, filter, handback)) {
- it.remove();
- removed = true;
- break;
- }
- }
- if (!removed)
- throw new ListenerNotFoundException();
-
- if (list.isEmpty())
- map.remove(name);
- }
- }
-
- /**
- * <p>Sends a notification to the subscribers for a given MBean.</p>
- *
- * <p>For each listener subscribed with an {@code ObjectName} that either
- * is equal to {@code emitterName} or is a pattern that matches {@code
- * emitterName}, if the associated filter accepts the notification then it
- * is forwarded to the listener.</p>
- *
- * @param emitterName The name of the MBean emitting the notification.
- * @param n The notification being sent by the MBean called
- * {@code emitterName}.
- *
- * @throws IllegalArgumentException If the emitterName of the
- * notification is null or is an {@code ObjectName} pattern.
- */
- public void publish(ObjectName emitterName, Notification n) {
- if (logger.traceOn())
- logger.trace("publish", "" + emitterName);
-
- if (n == null)
- throw new IllegalArgumentException("Null notification");
-
- if (emitterName == null) {
- throw new IllegalArgumentException(
- "Null emitter name");
- } else if (emitterName.isPattern()) {
- throw new IllegalArgumentException(
- "The emitter must not be an ObjectName pattern");
- }
-
- final List<ListenerInfo> listeners = new ArrayList<ListenerInfo>();
-
- // If there are listeners for this exact name, add them.
- synchronized (exactSubscriptionMap) {
- List<ListenerInfo> exactListeners =
- exactSubscriptionMap.get(emitterName);
- if (exactListeners != null)
- listeners.addAll(exactListeners);
- }
-
- // Loop over subscription patterns, and add all listeners for each
- // one that matches the emitterName name.
- synchronized (patternSubscriptionMap) {
- for (ObjectName on : patternSubscriptionMap.keySet()) {
- if (on.apply(emitterName))
- listeners.addAll(patternSubscriptionMap.get(on));
- }
- }
-
- // Send the notification to all the listeners we found.
- sendNotif(listeners, n);
- }
-
- /**
- * <p>Returns a {@link NotificationEmitter} object which can be used to
- * subscribe or unsubscribe for notifications with the named
- * mbean. The returned object implements {@link
- * NotificationEmitter#addNotificationListener
- * addNotificationListener(listener, filter, handback)} as
- * {@link #subscribe this.subscribe(name, listener, filter, handback)}
- * and the two {@code removeNotificationListener} methods from {@link
- * NotificationEmitter} as the corresponding {@code unsubscribe} methods
- * from this class.</p>
- *
- * @param name The name of the MBean whose notifications are being
- * subscribed, or unsuscribed.
- *
- * @return A {@link NotificationEmitter}
- * that can be used to subscribe or unsubscribe for
- * notifications emitted by the named MBean, or {@code null} if
- * the MBean does not emit notifications and should not
- * be considered as a {@code NotificationBroadcaster}. This class
- * never returns null but a subclass is allowed to.
- *
- * @throws InstanceNotFoundException if {@code name} does not exist.
- * This implementation never throws {@code InstanceNotFoundException} but
- * a subclass is allowed to override this method to do so.
- */
- public NotificationEmitter
- getNotificationEmitterFor(final ObjectName name)
- throws InstanceNotFoundException {
- final NotificationEmitter emitter = new NotificationEmitter() {
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback)
- throws IllegalArgumentException {
- subscribe(name, listener, filter, handback);
- }
-
- public void removeNotificationListener(
- NotificationListener listener)
- throws ListenerNotFoundException {
- unsubscribe(name, listener);
- }
-
- public void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws ListenerNotFoundException {
- unsubscribe(name, listener, filter, handback);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- // Never called.
- return null;
- }
- };
- return emitter;
- }
-
- // ---------------------------------
- // private stuff
- // ---------------------------------
-
- private static class ListenerInfo {
- public final NotificationListener listener;
- public final NotificationFilter filter;
- public final Object handback;
-
- public ListenerInfo(NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
-
- if (listener == null) {
- throw new IllegalArgumentException("Null listener.");
- }
-
- this.listener = listener;
- this.filter = filter;
- this.handback = handback;
- }
-
- /* Two ListenerInfo instances are equal if they have the same
- * NotificationListener. This means that we can use List.remove
- * to implement the two-argument removeNotificationListener.
- */
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof ListenerInfo)) {
- return false;
- }
-
- return listener.equals(((ListenerInfo)o).listener);
- }
-
- /* Method that compares all four fields, appropriate for the
- * four-argument removeNotificationListener.
- */
- boolean equals(
- NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
- return (this.listener == listener && same(this.filter, filter)
- && same(this.handback, handback));
- }
-
- private static boolean same(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null)
- return false;
- return x.equals(y);
- }
-
- @Override
- public int hashCode() {
- return listener.hashCode();
- }
- }
-
- private static void sendNotif(List<ListenerInfo> listeners, Notification n) {
- for (ListenerInfo li : listeners) {
- if (li.filter == null ||
- li.filter.isNotificationEnabled(n)) {
- try {
- li.listener.handleNotification(n, li.handback);
- } catch (Exception e) {
- logger.trace("sendNotif", "handleNotification", e);
- }
- }
- }
- }
-
- // ---------------------------------
- // private variables
- // ---------------------------------
-
- private final Map<ObjectName, List<ListenerInfo>> exactSubscriptionMap =
- new HashMap<ObjectName, List<ListenerInfo>>();
- private final Map<ObjectName, List<ListenerInfo>> patternSubscriptionMap =
- new HashMap<ObjectName, List<ListenerInfo>>();
-
- // trace issue
- private static final ClassLogger logger =
- new ClassLogger("javax.management.event", "EventManager");
-}
--- a/jdk/src/share/classes/javax/management/namespace/package-info.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,629 +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.
- */
-
-/**
- * <p>The <code>javax.management.namespace</code> package makes it possible
- * to federate MBeanServers into a hierarchical name space.</p>
- *
- * <h3 id="WhatIs">What Is a Name Space?</h3>
- * <p>
- * A name space is like an {@link javax.management.MBeanServer} within
- * an {@code MBeanServer}. Just as a file system folder can contain
- * another file system folder, an {@code MBeanServer} can contain another
- * {@code MBeanServer}. Similarly, just as a remote folder on a remote
- * disk can be mounted on a parent folder on a local disk, a remote name
- * space in a remote {@code MBeanServer} can be mounted on a name
- * space in a local parent {@code MBeanServer}.
- * </p>
- * <p>
- * The <code>javax.management.namespace</code> API thus makes it possible to
- * create a hierarchy of MBean servers federated in a hierarchical name
- * space inside a single {@code MBeanServer}.
- * </p>
- * <h3 id="HowToCreate">How To Create a Name Space?</h3>
- * <p>
- * To create a name space, you only need to register a
- * {@link javax.management.namespace.JMXNamespace} MBean in
- * an MBean server. We have seen that a namespace is like
- * an {@code MBeanServer} within an {@code MBeanServer}, and
- * therefore, it is possible to create a namespace that shows the
- * content of another {@code MBeanServer}. The simplest case is
- * when that {@code MBeanServer} is another {@code MBeanServer}
- * created by the {@link javax.management.MBeanServerFactory} as
- * shown in the extract below:
- * </p>
- * <pre>
- * final MBeanServer server = ....;
- * final String namespace = "foo";
- * final ObjectName namespaceName = {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName
- * JMXNamespaces.getNamespaceObjectName(namespace)};
- * server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()),
- * namespaceName);
- * </pre>
- * <p id="NamespaceView">
- * To navigate in namespaces and view their content, the easiest way is
- * to use an instance of {@link javax.management.namespace.JMXNamespaceView}. For instance, given
- * the {@code server} above, in which we created a namespace {@code "foo"},
- * it is possible to create a {@code JMXNamespaceView} that will make it
- * possible to navigate easily in the namespaces and sub-namespaces of that
- * server:
- * </p>
- * <pre>
- * // create a namespace view for 'server'
- * final JMXNamespaceView view = new JMXNamespaceView(server);
- *
- * // list all top level namespaces in 'server'
- * System.out.println("List of namespaces: " + Arrays.toString({@link javax.management.namespace.JMXNamespaceView#list() view.list()}));
- *
- * // go down into namespace 'foo': provides a namespace view of 'foo' and its
- * // sub namespaces...
- * final JMXNamespaceView foo = {@link javax.management.namespace.JMXNamespaceView#down view.down("foo")};
- *
- * // list all MBeans contained in namespace 'foo'
- * System.out.println({@link javax.management.namespace.JMXNamespaceView#where() foo.where()} + " contains: " +
- * {@link javax.management.namespace.JMXNamespaceView#getMBeanServerConnection foo.getMBeanServerConnection()}.queryNames(null,null));
- * </pre>
- * <p>
- * It is also possible to create more complex namespaces, such as namespaces
- * that point to MBean servers located in remote JVMs.
- * </p>
- * <p>
- * For instance, to mount the MBeanServer accessible
- * at <code>service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi</code>
- * in a name space {@code "foo"} inside the {@linkplain
- * java.lang.management.ManagementFactory#getPlatformMBeanServer platform
- * MBeanServer} you would write the following piece of code:
- * </p>
- * <pre>
- * final JMXServiceURL sourceURL =
- * new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi");
- * final MBeanServer platform = ManagementFactory.getPlatformMBeanServer();
- * final Map<String,Object> options = Collections.emptyMap();
- * final JMXRemoteNamespace mbean = {@link
- * javax.management.namespace.JMXRemoteNamespace JMXRemoteNamespace}.
- * {@link javax.management.namespace.JMXRemoteNamespace#newJMXRemoteNamespace newJMXRemoteNamespace(sourceURL, options)};
- * final ObjectName name = {@link javax.management.namespace.JMXNamespaces JMXNamespaces}.{@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName(String) getNamespaceObjectName("foo")};
- * final ObjectInstance ref = platform.registerMBean(mbean,name);
- * platform.invoke(ref.getObjectName(),"connect",null,null);
- * </pre>
- *
- * <h3 id="WhatLike">What Does a Name Space Look Like?</h3>
- *
- * <p>
- * We have seen that {@link javax.management.namespace.JMXNamespaceView} class
- * provides an easy way to navigate within namespaces. It is however also
- * possible to interact with namespaces directly from the top level
- * {@code MBeanServer} in which they have been created.
- * From the outside, a name space only appears as a special MBean in
- * the MBean server. There's nothing much you can do with this MBean
- * directly.
- * </p>
- * <p>
- * For instance, let's assume you have registered a {@link
- * javax.management.namespace.JMXRemoteNamespaceMBean
- * JMXRemoteNamespaceMBean} to manage the name space {@code "foo"}.
- * <br>If you query for
- * <code>platform.queryNames("*//:*",null)</code>, then you will see
- * one MBean named {@code "foo//:type=JMXNamespace"}.
- * <br>This is the {@link javax.management.namespace.JMXNamespace}
- * MBean which is in charge of handling the namespace {@code "foo"}.
- * </p>
- * <p>
- * In fact, name space handler MBeans are instances of
- * the class {@link javax.management.namespace.JMXNamespace} - or
- * instances of a subclass of that class.
- * They have a special {@link javax.management.ObjectName} defined by
- * {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName
- * JMXNamespaces.getNamespaceObjectName}.<br>
- * {@link javax.management.namespace.JMXNamespace} instances are able
- * to return an {@link
- * javax.management.namespace.JMXNamespace#getSourceServer MBeanServer}
- * which corresponds to the MBeanServer within (= the name space itself).
- * </p>
- * <p>
- * So how does it work? How can you see the MBeans contained in the new
- * name space?
- * </p>
- * <p>In order to address scalability issues, MBeans registered in
- * namespaces (such as our namespace {@code "foo"} above) can not be
- * seen with {@code mbeanServer.queryNames("*:*",null)}. To see the MBeans
- * contained in a namespace, you can use one of these methods:
- * </p>
- * <ol>
- * <li>
- * You can use the {@link javax.management.namespace.JMXNamespaceView}
- * class <a href="#NamespaceView">shown above</a>,
- * </li>
- * <li>
- * or you can <a href="#NamespacePrefix">directly look</a> for MBeans
- * whose names match
- * {@code "foo//*:*"},
- * </li>
- * <li>
- * or you can <a href="#ChangeTo">narrow down</a> to the namespace
- * and obtain an MBeanServer
- * proxy that corresponds to an MBeanServer view of that namespace.
- * The JMXNamespaces class provides a static method that
- * allows you to narrow down to a name space, by calling
- * {@link javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String)
- * JMXNamespaces.narrowToNamespace}.
- * </li>
- * </ol>
- *
- * <h3 id="NamespacePrefix">Using Name Space Prefixes</h3>
- * <p>
- * As we have explained above, MBeans contained in name
- * spaces are not returned by {@code server.queryNames(null,null)} - or
- * <code>server.queryNames({@link javax.management.ObjectName#WILDCARD ObjectName.WILDCARD},null)</code>.
- * <br>
- * However, these MBeans can still be accessed from the top level
- * {@code MBeanServer} interface, without using any API specific to the
- * version 2.0 of the JMX API, simply by using object names with
- * name space prefixes:
- * <br>To list MBeans contained in a namespace {@code "foo"} you can
- * query for MBeans whose names match {@code "foo//*:*"}, as shown
- * earlier in this document:
- * <pre>
- * server.queryNames(new ObjectName("foo//*:*", null);
- * // or equivalently:
- * server.queryNames(JMXNamespaces.getWildcardFor("foo"), null);
- * </pre>
- * This will return a list of MBean names whose domain name starts
- * with {@code foo//}.
- * </p><p>
- * Using these names, you can invoke any operation on the corresponding
- * MBeans. For instance, to get the {@link javax.management.MBeanInfo
- * MBeanInfo} of an MBean
- * contained in name space {@code "foo"} (assuming
- * the name of the MBean within its name space is <i>domain:type=Thing</i>,
- * then simply call:
- * <pre>
- * server.getMBeanInfo(new ObjectName("foo//domain:type=Thing"));
- * </pre>
- * An easier way to access MBeans contained in a name space is to
- * <i>cd</i> inside the name space, as shown in the following paragraph.
- * </p><p id="RejectedNamespacePatterns">
- * Although ObjectName patterns where the characters
- * <code>*</code> and <code>?</code> 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.<br>
- * When invoking <code>queryNames</code> or <code>queryMBeans</code>,
- * only ObjectNames of the form:<br>
- * [<em>namespace-without-pattern</em>//]*[<em>pattern-without-namespace</em>]:<em>key-properties-with-or-without-pattern</em>
- * are valid.<br>
- * 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.
- * </p><p id="NamespaceAndQueries">
- * 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.<br>
- * In other words:</p>
- * <ul><li>{@code queryNames("foo//bar//?a?:*","b?z:type=Monitor,*")} will select
- * all MBeans in namespace <em>foo//bar</em> whose names match both
- * <em>?a?:*</em> and <em>b?z:type=Monitor,*</em>, but</li>
- * <li>{@code queryNames("foo//bar//?a?:*","foo//bar//b?z:type=Monitor,*")}
- * will select nothing because no name matching <em>?a?:*</em> will
- * also match <em>foo//bar//b?z:type=Monitor,*</em>.
- * </li>
- * </ul>
- *
- * <h3 id="ChangeTo">Narrowing Down Into a Name Spaces</h3>
- * <p>
- * As we have seen, name spaces are like MBean servers within MBean servers.
- * Therefore, it is possible to view a name space just as if it were
- * an other MBean server. This is similar to opening a sub
- * folder from a parent folder.<br>
- * This operation is illustrated in the code extract below:
- * <pre>
- * final MBeanServer foo =
- * JMXNamespaces.narrowToNamespace(platform, "foo");
- * final MBeanInfo info =
- * foo.getMBeanInfo(new ObjectName("domain:type=Thing"));
- * </pre>
- * The {@code MBeanServer} returned by {@link
- * javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String)
- * JMXNamespaces.narrowToNamespace} is an {@code MBeanServer} view that
- * narrows down into a given namespace. The MBeans contained inside that
- * namespace can now be accessed by their regular local name. <br>
- * The MBean server obtained by narrowing down
- * 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 {@link javax.management.RuntimeOperationsException
- * RuntimeOperationsException} if you try to call an operation which is not
- * supported by the underlying name space handler.
- * <br>For instance, {@link javax.management.MBeanServer#registerMBean
- * registerMBean} is not supported for name spaces mounted from remote
- * MBean servers.
- * </p>
- * <p>
- * <u>Note:</u> If you have a deep hierarchy of namespaces, and if you
- * are switching from one namespace to another in the course of your
- * application, it might be more convenient to use a
- * {@link javax.management.namespace.JMXNamespaceView}
- * in order to navigate in your namespaces.
- * </p>
- *
- * <h3 id="NamespaceTypes">Different Types of Name Spaces</h3>
- * <p>
- * This API lets you create several types of name spaces:
- * <ul>
- * <li id="RemoteNS">
- * You can use the {@link
- * javax.management.namespace.JMXRemoteNamespace
- * JMXRemoteNamespace} to create
- * <b>remote</b> name spaces, mounted from
- * a remote sub {@code MBeanServer} source, as shown
- * <a href="#HowToCreate">earlier</a> in this document.
- * </li>
- * <li id="LocalNS">
- * You can also use {@link
- * javax.management.namespace.JMXNamespace
- * JMXNamespace} to create
- * <b>local</b> name spaces,
- * by providing a direct reference to another {@code MBeanServer}
- * instance living in the same JVM.
- * </li>
- * <li id="VirtualNS">
- * Finally, you can create
- * name spaces containing <b>virtual</b> MBeans,
- * by subclassing the {@link
- * javax.management.namespace.MBeanServerSupport
- * MBeanServerSupport}, and passing an instance of
- * your own subclass to a {@link
- * javax.management.namespace.JMXNamespace JMXNamespace}.
- * </li>
- * <li id="CustomNS">
- * If none of these classes suit your needs, you can also provide
- * <b>your own</b> subclass of {@link
- * javax.management.namespace.JMXNamespace
- * JMXNamespace}. This is however discouraged.
- * </li>
- * </ul>
- * </p>
- *
- * <h3 id="SpecialOp">Name Spaces And Special Operations</h3>
- * <p>
- * MBean Naming considerations aside, Name Spaces are transparent for
- * most {@code MBeanServer} operations. There are however a few
- * exceptions:
- * </p>
- * <ul>
- * <li>
- * <p>MBeanServer only operations - these are the operations which are
- * supported by {@link javax.management.MBeanServer MBeanServer} but
- * are not present in {@link
- * javax.management.MBeanServerConnection
- * MBeanServerConnection}. Since a name space can be a local view of
- * a remote {@code MBeanServer}, accessible only through an
- * {@code MBeanServerConnection}, these
- * kinds of operations are not always supported.</p>
- * <ul>
- * <li id="registerMBean">
- * <p>registerMBean:</p>
- * <p> The {@link javax.management.MBeanServer#registerMBean
- * registerMBean}
- * operation is not supported by most name spaces. A call
- * to
- * <pre>
- * MBeanServer server = ....;
- * ThingMBean mbean = new Thing(...);
- * ObjectName name = new ObjectName("foo//domain:type=Thing");
- * server.registerMBean(mbean, name);
- * </pre>
- * will usually fail, unless the name space
- * {@code "foo"} is a <a href="#LocalNS">local</a> name
- * space. In the case where you attempt to cross
- * multiple name spaces, then all name spaces in the
- * path must support the {@code registerMBean} operation
- * in order for it to succeed.<br>
- * To create an MBean inside a name space, it is
- * usually safer to use {@code createMBean} -
- * although some <a href="#MBeanCreation">special
- * considerations</a> can also apply.
- * </p>
- * <p></p>
- * </li>
- * <li id="getClassLoader">
- * <p>getClassLoader:</p>
- * <p> Similarly to <a href="#registerMBean">registerMBean</a>,
- * and for the same reasons, {@link
- * javax.management.MBeanServer#getClassLoader
- * getClassLoader} will usually fail, unless the
- * class loader is an MBean registered in a
- * <a href="#LocalNS">local</a> name space.<br>
- * </p>
- * </li>
- * <li id="getClassLoaderFor">
- * <p>getClassLoaderFor:</p>
- * <p> The implementation of {@link
- * javax.management.MBeanServer#getClassLoaderFor
- * getClassLoaderFor} also depends on which
- * <a href="#NamespaceTypes">type of name space</a>
- * handler is used across the namespace path.
- * </p>
- * <p>
- * A <a href="#LocalNS">local</a> name space will usually
- * be able to implement this method just as a real
- * {@code MBeanServer} would. A
- * <a href="#RemoteNS">remote</a> name space will usually
- * return the default class loader configured on the
- * internal {@link javax.management.remote.JMXConnector
- * JMXConnector} used to connect to the remote server.
- * When a {@link
- * javax.management.namespace.JMXRemoteNamespace
- * JMXRemoteNamespace} is used to connect to a
- * remote server that contains MBeans which export
- * custom types, the {@link
- * javax.management.namespace.JMXRemoteNamespace
- * JMXRemoteNamespace} must thus be configured with
- * an options map such that the underlying connector
- * can obtain a default class loader able
- * to handle those types.
- * </p>
- * <p>
- * Other <a href="#NamespaceTypes">types of name spaces</a>
- * may implement this method
- * as best as they can.
- * </p>
- * </li>
- * </ul>
- * </li>
- * <li id="MBeanCreation">
- * <p>MBean creation</p>
- * <p> MBean creation through {@link
- * javax.management.MBeanServerConnection#createMBean
- * createMBean} might not be supported by all
- * name spaces: <a href="#LocalNS">local</a> name spaces and
- * <a href="#LocalNS">remote</a> name spaces will usually
- * support it, but <a href="#VirtualNS">virtual</a> name
- * spaces and <a href="#CustomNS">custom</a> name
- * spaces might not.
- * </p>
- * <p>
- * In that case, they will throw an {@link
- * java.lang.UnsupportedOperationException
- * UnsupportedOperationException} usually wrapped into an {@link
- * javax.management.MBeanRegistrationException}.
- * </p>
- * </li>
- * <li id="Notifications">
- * <p>Notifications</p>
- * <p> Some namespaces might not support JMX Notifications. In that
- * case, a call to add or remove notification listener for an
- * MBean contained in that name space will raise a
- * {@link javax.management.RuntimeOperationsException
- * RuntimeOperationsException} wrapping an {@link
- * java.lang.UnsupportedOperationException
- * UnsupportedOperationException} exception.
- * </p>
- * </li>
- * </ul>
- *
- * <h3 id="CrossingNamespace">Crossing Several Name Spaces</h3>
- * <p>
- * Just as folders can contain other folders, name spaces can contain
- * other name spaces. For instance, if an {@code MBeanServer} <i>S1</i>
- * containing a name space {@code "bar"} is mounted in another
- * {@code MBeanServer} <i>S2</i> with name space {@code "foo"}, then
- * an MBean <i>M1</i> named {@code "domain:type=Thing"} in namespace
- * {@code "bar"} will appear as {@code "foo//bar//domain:type=Thing"} in
- * {@code MBeanServer} <i>S2</i>.
- * </p>
- * <p>
- * When accessing the MBean <i>M1</i> from server <i>S2</i>, the
- * method call will traverse in a cascade {@code MBeanServer} <i>S2</i>,
- * then the name space handler for name space {@code "foo"}, then
- * {@code MBeanServer} <i>S1</i>, before coming to the name space
- * handler for name space {@code "bar"}. Any operation invoked
- * on the MBean from a "top-level" name space will therefore need to
- * traverse all the name spaces along the name space path until
- * it eventually reaches the named MBean. This means that an operation
- * like <a href="#registerMBean">registerMBean</a> for instance,
- * can only succeed if all the name spaces along the path support it.
- * </p>
- * <p>
- * Narrowing to a nested name space works just the same as narrowing
- * to a top level name space:
- * <pre>
- * final MBeanServer S2 = .... ;
- * final MBeanServer bar =
- * JMXNamespaces.narrowToNamespace(S2, "foo//bar");
- * final MBeanInfo info =
- * foo.getMBeanInfo(new ObjectName("domain:type=Thing"));
- * </pre>
- * </p>
- *
- * <h3 id="OperationResult">Name Spaces And Operation Results</h3>
- * <p>
- * Operation results, as well as attribute values returned by an MBean
- * contained in a name space must be interpreted in the context of that
- * name space.<br>
- * In other words, if an MBean in name space "foo" has an attribute of
- * type {@code ObjectName}, then it must be assumed that the
- * {@code ObjectName} returned by that MBean is relative to
- * name space "foo".<br>
- * The same rule aplies for MBean names that can be returned by
- * operations invoked on such an MBean. If one of the MBean operations
- * return, say, a {@code Set<ObjectName>} then those MBean names must
- * also be assumed to be relative to name space "foo".<br>
- * </p>
- * <p>
- * In the usual case, a JMX client will first
- * <a href="#ChangeTo">narrow to a name space</a> before invoking
- * any operation on the MBeans it contains. In that case the names
- * returned by the MBean invoked can be directly fed back to the
- * narrowed connection.
- * <br>
- * If however, the JMX client directly invoked the MBean from a higher
- * name space, without having narrowed to that name space first, then
- * the names that might be returned by that MBean will not be directly
- * usable - the JMX client will need to either
- * <a href="#ChangeTo">narrow to the name space</a> before using the
- * returned names, or convert the names to the higher level name space
- * context.
- * <br>
- * The {@link javax.management.namespace.JMXNamespaces JMXNamespaces}
- * class provides methods that can be used to perform that conversion.
- * </p>
- *
- * <h3 id="NamespacesAndNotifications">Name Spaces And Notifications</h3>
- * <p>
- * As <a href="#WhatIs">already explained</a>, name spaces are very
- * similar to {@code MBeanServer}s. It is thus possible to get
- * {@link javax.management.MBeanServerNotification MBeanServerNotifications}
- * when MBeans are added or removed within a name space, by registering
- * with the {@link javax.management.MBeanServerDelegate
- * MBeanServerDelegate} MBean of the corresponding name space.<br>
- * However, it must be noted that the notifications emitted by a
- * name space must be interpreted in the context of that name space.
- * For instance, if an MBean {@code "domain:type=Thing"} contained in
- * namespace "foo//bar" emits a notification, the source of the
- * notification will be {@code "domain:type=Thing"}, not
- * {@code "foo//bar//domain:type=Thing"}. <br>
- * It is therefore recommended to keep track of the name space
- * information when registering a listener with an MBean contained in
- * a name space, especially if the same listener is used to receive
- * notifications from different name spaces. An easy solution is to
- * use the handback, as illustrated in the code below.
- * <pre>
- * final MBeanServer server = ...;
- * final NotificationListener listener = new NotificationListener() {
- * public void handleNotification(Notification n, Object handback) {
- * if (!(n instanceof MBeanServerNotification)) {
- * System.err.println("Error: expected MBeanServerNotification");
- * return;
- * }
- * final MBeanServerNotification mbsn =
- * (MBeanServerNotification) n;
- *
- * // We will pass the namespace path in the handback.
- * //
- * // The received notification must be interpreted in
- * // the context of its source - therefore
- * // mbsn.getMBeanName() does not include the name space
- * // path...
- * //
- * final String namespace = (String) handback;
- * System.out.println("Received " + mbsn.getType() +
- * " for MBean " + mbsn.getMBeanName() +
- * " from name space " + namespace);
- * }
- * };
- * server.addNotificationListener(JMXNamespaces.insertPath("foo//bar",
- * MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//bar");
- * server.addNotificationListener(JMXNamespaces.insertPath("foo//joe",
- * MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//joe");
- * </pre>
- * </p>
- * <p>
- * JMX Connectors may require some configuration in order to be able
- * to forward notifications from MBeans located in name spaces.
- * The RMI JMX Connector Server
- * in the Java SE 7 platform is configured by default to internally
- * use the new {@linkplain javax.management.event event service} on
- * the server side.
- * When the connector server is configured in this way, JMX clients
- * which use the old JMX Notifications mechanism (such as clients
- * running on prior versions of the JDK) will be able to
- * to receive notifications from MBeans located in sub name spaces.
- * This is because the connector server will transparently delegate
- * their subscriptions to the underlying {@linkplain
- * javax.management.event event service}. In summary:
- * <ul>
- * <li>
- * On the server side: When exporting an {@code MBeanServer}
- * through a JMX Connector, you will need to make sure that the
- * connector server uses the new {@linkplain javax.management.event
- * event service} in order to register for notifications. If the
- * connector server doesn't use the event service, only clients
- * which explicitly use the new {@linkplain javax.management.event
- * event service} will be able to register for notifications
- * with MBeans located in sub name spaces.
- * </li>
- * <li>
- * On the client side: if the JMX Connector server (on the remote
- * server side) was configured to internally use the new
- * {@linkplain javax.management.event
- * event service}, then clients can continue to use the old
- * {@code MBeanServerConnection} add / remove notification
- * listener methods transparently. Otherwise, only clients which
- * explicitly use the new {@linkplain javax.management.event
- * event service} will be able to receive notifications from
- * MBeans contained in sub name spaces.
- * </li>
- * </ul>
- * </p>
- * <p>
- * These configuration issues apply at each node in the name space path,
- * whenever the name space points to a remote server. The
- * {@link javax.management.namespace.JMXRemoteNamespace
- * JMXRemoteNamespace} can be configured in such a way that it will
- * explicitly use an {@link javax.management.event.EventClient EventClient}
- * when forwarding subscription to the remote side. Note that this can be
- * unnecessary (and a waste of resources) if the underlying JMXConnector
- * returned by the JMXConnectorFactory (client side) already uses the
- * {@linkplain javax.management.event event service} to register for
- * notifications with the server side.
- * </p>
- *
- * <h3 id="Security">Name Spaces And Access Control</h3>
- * <p>
- * Access to MBeans exposed through JMX namespaces is controlled by
- * {@linkplain javax.management.namespace.JMXNamespacePermission
- * jmx namespace permissions}. These permissions are checked by the
- * MBeanServer in which the {@link
- * javax.management.namespace.JMXNamespace JMXNamespace} MBean is registered.
- * This is <a href="JMXNamespace.html#PermissionChecks">described in
- * details</a> in the {@link
- * javax.management.namespace.JMXNamespace JMXNamespace} class.
- * </p>
- * <p>
- * To implement a "firewall-like" access control in a JMX agent you
- * can also place an {@link
- * javax.management.remote.MBeanServerForwarder} in the JMX Connector
- * Server which exposes the top-level MBeanServer of your application.
- * This {@code MBeanServerForwarder} will be able to perform
- * authorization checks for all MBeans, including those located in
- * sub name spaces.
- * </p>
- * <p>
- * For a tighter access control we recommend using a {@link
- * java.lang.SecurityManager security manager}.
- * </p>
- * @since 1.7
- * <p></p>
- **/
-
-package javax.management.namespace;
-
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Wed Oct 21 16:50:44 2009 +0100
@@ -26,6 +26,8 @@
package javax.management.openmbean;
import com.sun.jmx.mbeanserver.MXBeanLookup;
+import com.sun.jmx.mbeanserver.MXBeanMapping;
+import com.sun.jmx.mbeanserver.MXBeanMappingFactory;
import com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -115,12 +117,7 @@
is null.
*/
public CompositeDataInvocationHandler(CompositeData compositeData) {
- this(compositeData, MXBeanMappingFactory.DEFAULT);
- }
-
- public CompositeDataInvocationHandler(CompositeData compositeData,
- MXBeanMappingFactory mappingFactory) {
- this(compositeData, mappingFactory, null);
+ this(compositeData, null);
}
/**
@@ -139,13 +136,11 @@
is null.
*/
CompositeDataInvocationHandler(CompositeData compositeData,
- MXBeanMappingFactory mappingFactory,
MXBeanLookup lookup) {
if (compositeData == null)
throw new IllegalArgumentException("compositeData");
this.compositeData = compositeData;
this.lookup = lookup;
- this.mappingFactory = mappingFactory;
}
/**
@@ -204,7 +199,7 @@
}
}
MXBeanMapping mapping =
- mappingFactory.mappingForType(method.getGenericReturnType(),
+ MXBeanMappingFactory.DEFAULT.mappingForType(method.getGenericReturnType(),
MXBeanMappingFactory.DEFAULT);
return mapping.fromOpenValue(openValue);
}
@@ -250,5 +245,4 @@
private final CompositeData compositeData;
private final MXBeanLookup lookup;
- private final MXBeanMappingFactory mappingFactory;
}
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java Wed Oct 21 16:50:44 2009 +0100
@@ -92,16 +92,16 @@
* @param itemNames <tt>itemNames</tt> must list, in any order, all the
* item names defined in <tt>compositeType</tt>; the order in which the
* names are listed, is used to match values in <tt>itemValues[]</tt>; must
- * not be null.
+ * not be null or empty.
*
* @param itemValues the values of the items, listed in the same order as
* their respective names in <tt>itemNames</tt>; each item value can be
* null, but if it is non-null it must be a valid value for the open type
* defined in <tt>compositeType</tt> for the corresponding item; must be of
- * the same size as <tt>itemNames</tt>; must not be null.
+ * the same size as <tt>itemNames</tt>; must not be null or empty.
*
* @throws IllegalArgumentException <tt>compositeType</tt> is null, or
- * <tt>itemNames[]</tt> or <tt>itemValues[]</tt> is null, or one
+ * <tt>itemNames[]</tt> or <tt>itemValues[]</tt> is null or empty, or one
* of the elements in <tt>itemNames[]</tt> is a null or empty string, or
* <tt>itemNames[]</tt> and <tt>itemValues[]</tt> are not of the same size.
*
@@ -124,6 +124,8 @@
if (itemNames == null || itemValues == null)
throw new IllegalArgumentException("Null itemNames or itemValues");
+ if (itemNames.length == 0 || itemValues.length == 0)
+ throw new IllegalArgumentException("Empty itemNames or itemValues");
if (itemNames.length != itemValues.length) {
throw new IllegalArgumentException(
"Different lengths: itemNames[" + itemNames.length +
@@ -154,10 +156,10 @@
* must not be null.
* @param items the mappings of all the item names to their values;
* <tt>items</tt> must contain all the item names defined in <tt>compositeType</tt>;
- * must not be null.
+ * must not be null or empty.
*
* @throws IllegalArgumentException <tt>compositeType</tt> is null, or
- * <tt>items</tt> is null, or one of the keys in <tt>items</tt> is a null
+ * <tt>items</tt> is null or empty, or one of the keys in <tt>items</tt> is a null
* or empty string.
* @throws OpenDataException <tt>items</tt>' size differs from the
* number of items defined in <tt>compositeType</tt>, or one of the
@@ -167,8 +169,6 @@
* <tt>compositeType</tt>.
* @throws ArrayStoreException one or more keys in <tt>items</tt> is not of
* the class <tt>java.lang.String</tt>.
- *
- * @see #toMap
*/
public CompositeDataSupport(CompositeType compositeType,
Map<String,?> items)
@@ -177,13 +177,13 @@
}
private static SortedMap<String, Object> makeMap(Map<String, ?> items) {
- if (items == null)
- throw new IllegalArgumentException("Null items map");
- if (items.containsKey(null) || items.containsKey(""))
- throw new IllegalArgumentException("Null or empty item name");
+ if (items == null || items.isEmpty())
+ throw new IllegalArgumentException("Null or empty items map");
SortedMap<String, Object> map = new TreeMap<String, Object>();
for (Object key : items.keySet()) {
+ if (key == null || key.equals(""))
+ throw new IllegalArgumentException("Null or empty item name");
if (!(key instanceof String)) {
throw new ArrayStoreException("Item name is not string: " + key);
// This can happen because of erasure. The particular
@@ -329,54 +329,6 @@
}
/**
- * <p>Returns a Map representing the contents of the given CompositeData.
- * Each item in the CompositeData is represented by an entry in the map,
- * where the name and value of the item are the key and value of the entry.
- * The returned value is modifiable but modifications to it have no effect
- * on the original CompositeData.</p>
- *
- * <p>For example, if you have a CompositeData {@code cd1} and you want
- * to produce another CompositeData {@code cd2} which is the same except
- * that the value of its {@code id} item has been changed to 253, you
- * could write:</p>
- *
- * <pre>
- * CompositeData cd1 = ...;
- * {@code Map<String, Object>} map = CompositeDataSupport.toMap(cd1);
- * assert(map.get("id") instanceof Integer);
- * map.put("id", 253);
- * CompositeData cd2 = {@link #CompositeDataSupport(CompositeType, Map)
- * new CompositeDataSupport}(cd1.getCompositeType(), map);
- * </pre>
- *
- * <p>Logically, this method would be a method in the {@link CompositeData}
- * interface, but cannot be for compatibility reasons.</p>
- *
- * @param cd the CompositeData to convert to a Map.
- *
- * @return a Map that is a copy of the contents of {@code cd}.
- *
- * @throws IllegalArgumentException if {@code cd} is null.
- *
- * @see #CompositeDataSupport(CompositeType, Map)
- */
- public static Map<String, Object> toMap(CompositeData cd) {
- if (cd == null)
- throw new IllegalArgumentException("Null argument");
-
- // If we really wanted, we could check whether cd is a
- // CompositeDataSupport and return a copy of cd.contents if so,
- // but I don't think that would be substantially faster.
- Map<String, Object> map = new LinkedHashMap<String, Object>();
- CompositeType ct = cd.getCompositeType();
- for (String key : ct.keySet()) {
- Object value = cd.get(key);
- map.put(key, value);
- }
- return map;
- }
-
- /**
* Compares the specified <var>obj</var> parameter with this
* <code>CompositeDataSupport</code> instance for equality.
* <p>
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeType.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeType.java Wed Oct 21 16:50:44 2009 +0100
@@ -89,7 +89,7 @@
* <br>
* @param itemNames The names of the items contained in the
* composite data values described by this <code>CompositeType</code> instance;
- * cannot be null; no element can be null or an empty string.
+ * cannot be null and should contain at least one element; no element can be a null or empty string.
* Note that the order in which the item names are given is not important to differentiate a
* <code>CompositeType</code> instance from another;
* the item names are internally stored sorted in ascending alphanumeric order.
@@ -125,7 +125,7 @@
//
super(CompositeData.class.getName(), typeName, description, false);
- // Check the 3 arrays are not null and that there is no null element or empty string in them
+ // Check the 3 arrays are not null or empty (ie length==0) and that there is no null element or empty string in them
//
checkForNullElement(itemNames, "itemNames");
checkForNullElement(itemDescriptions, "itemDescriptions");
@@ -159,8 +159,8 @@
}
private static void checkForNullElement(Object[] arg, String argName) {
- if (arg == null) {
- throw new IllegalArgumentException("Argument "+ argName +"[] cannot be null.");
+ if ( (arg == null) || (arg.length == 0) ) {
+ throw new IllegalArgumentException("Argument "+ argName +"[] cannot be null or empty.");
}
for (int i=0; i<arg.length; i++) {
if (arg[i] == null) {
--- a/jdk/src/share/classes/javax/management/openmbean/MXBeanMapping.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +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 javax.management.openmbean;
-
-import java.io.InvalidObjectException;
-import java.lang.reflect.Type;
-
-/**
- * <p>A custom mapping between Java types and Open types for use in MXBeans.
- * To define such a mapping, subclass this class and define at least the
- * {@link #fromOpenValue fromOpenValue} and {@link #toOpenValue toOpenValue}
- * methods, and optionally the {@link #checkReconstructible} method.
- * Then either use an {@link MXBeanMappingClass} annotation on your custom
- * Java types, or include this MXBeanMapping in an
- * {@link MXBeanMappingFactory}.</p>
- *
- * <p>For example, suppose we have a class {@code MyLinkedList}, which looks
- * like this:</p>
- *
- * <pre>
- * public class MyLinkedList {
- * public MyLinkedList(String name, MyLinkedList next) {...}
- * public String getName() {...}
- * public MyLinkedList getNext() {...}
- * }
- * </pre>
- *
- * <p>This is not a valid type for MXBeans, because it contains a
- * self-referential property "next" defined by the {@code getNext()}
- * method. MXBeans do not support recursive types. So we would like
- * to specify a mapping for {@code MyLinkedList} explicitly. When an
- * MXBean interface contains {@code MyLinkedList}, that will be mapped
- * into a {@code String[]}, which is a valid Open Type.</p>
- *
- * <p>To define this mapping, we first subclass {@code MXBeanMapping}:</p>
- *
- * <pre>
- * public class MyLinkedListMapping extends MXBeanMapping {
- * public MyLinkedListMapping(Type type) throws OpenDataException {
- * super(MyLinkedList.class, ArrayType.getArrayType(SimpleType.STRING));
- * if (type != MyLinkedList.class)
- * throw new OpenDataException("Mapping only valid for MyLinkedList");
- * }
- *
- * {@literal @Override}
- * public Object fromOpenValue(Object openValue) throws InvalidObjectException {
- * String[] array = (String[]) openValue;
- * MyLinkedList list = null;
- * for (int i = array.length - 1; i >= 0; i--)
- * list = new MyLinkedList(array[i], list);
- * return list;
- * }
- *
- * {@literal @Override}
- * public Object toOpenValue(Object javaValue) throws OpenDataException {
- * ArrayList<String> array = new ArrayList<String>();
- * for (MyLinkedList list = (MyLinkedList) javaValue; list != null;
- * list = list.getNext())
- * array.add(list.getName());
- * return array.toArray(new String[0]);
- * }
- * }
- * </pre>
- *
- * <p>The call to the superclass constructor specifies what the
- * original Java type is ({@code MyLinkedList.class}) and what Open
- * Type it is mapped to ({@code
- * ArrayType.getArrayType(SimpleType.STRING)}). The {@code
- * fromOpenValue} method says how we go from the Open Type ({@code
- * String[]}) to the Java type ({@code MyLinkedList}), and the {@code
- * toOpenValue} method says how we go from the Java type to the Open
- * Type.</p>
- *
- * <p>With this mapping defined, we can annotate the {@code MyLinkedList}
- * class appropriately:</p>
- *
- * <pre>
- * {@literal @MXBeanMappingClass}(MyLinkedListMapping.class)
- * public class MyLinkedList {...}
- * </pre>
- *
- * <p>Now we can use {@code MyLinkedList} in an MXBean interface and it
- * will work.</p>
- *
- * <p>If we are unable to modify the {@code MyLinkedList} class,
- * we can define an {@link MXBeanMappingFactory}. See the documentation
- * of that class for further details.</p>
- *
- * @see <a href="../MXBean.html#custom">MXBean specification, section
- * "Custom MXBean type mappings"</a>
- */
-public abstract class MXBeanMapping {
- private final Type javaType;
- private final OpenType<?> openType;
- private final Class<?> openClass;
-
- /**
- * <p>Construct a mapping between the given Java type and the given
- * Open Type.</p>
- *
- * @param javaType the Java type (for example, {@code MyLinkedList}).
- * @param openType the Open Type (for example, {@code
- * ArrayType.getArrayType(SimpleType.STRING)})
- *
- * @throws NullPointerException if either argument is null.
- */
- protected MXBeanMapping(Type javaType, OpenType<?> openType) {
- if (javaType == null || openType == null)
- throw new NullPointerException("Null argument");
- this.javaType = javaType;
- this.openType = openType;
- this.openClass = makeOpenClass(javaType, openType);
- }
-
- /**
- * <p>The Java type that was supplied to the constructor.</p>
- * @return the Java type that was supplied to the constructor.
- */
- public final Type getJavaType() {
- return javaType;
- }
-
- /**
- * <p>The Open Type that was supplied to the constructor.</p>
- * @return the Open Type that was supplied to the constructor.
- */
- public final OpenType<?> getOpenType() {
- return openType;
- }
-
- /**
- * <p>The Java class that corresponds to instances of the
- * {@linkplain #getOpenType() Open Type} for this mapping.</p>
- * @return the Java class that corresponds to instances of the
- * Open Type for this mapping.
- * @see OpenType#getClassName
- */
- public final Class<?> getOpenClass() {
- return openClass;
- }
-
- private static Class<?> makeOpenClass(Type javaType, OpenType<?> openType) {
- if (javaType instanceof Class<?> && ((Class<?>) javaType).isPrimitive())
- return (Class<?>) javaType;
- try {
- String className = OpenType.validClassName(openType.getClassName());
- return Class.forName(className, false, null);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e); // should not happen
- } catch (OpenDataException e) {
- throw new IllegalArgumentException("Bad OpenType: " + openType, e);
- }
- }
-
- /**
- * <p>Convert an instance of the Open Type into the Java type.
- * @param openValue the value to be converted.
- * @return the converted value.
- * @throws InvalidObjectException if the value cannot be converted.
- */
- public abstract Object fromOpenValue(Object openValue)
- throws InvalidObjectException;
-
- /**
- * <p>Convert an instance of the Java type into the Open Type.
- * @param javaValue the value to be converted.
- * @return the converted value.
- * @throws OpenDataException if the value cannot be converted.
- */
- public abstract Object toOpenValue(Object javaValue)
- throws OpenDataException;
-
-
- /**
- * <p>Throw an appropriate InvalidObjectException if we will not
- * be able to convert back from the open data to the original Java
- * object. The {@link #fromOpenValue fromOpenValue} throws an
- * exception if a given open data value cannot be converted. This
- * method throws an exception if <em>no</em> open data values can
- * be converted. The default implementation of this method never
- * throws an exception. Subclasses can override it as
- * appropriate.</p>
- * @throws InvalidObjectException if {@code fromOpenValue} will throw
- * an exception no matter what its argument is.
- */
- public void checkReconstructible() throws InvalidObjectException {}
-}
--- a/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingClass.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +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 javax.management.openmbean;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.management.NotCompliantMBeanException;
-
-/**
- * Specifies the MXBean mapping to be used for this Java type.
- * @see MXBeanMapping
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Documented @Inherited
-public @interface MXBeanMappingClass {
- /**
- * <p>The {@link MXBeanMapping} class to be used to map the
- * annotated type. This class must have a public constructor with
- * a single argument of type {@link java.lang.reflect.Type}. The
- * constructor will be called with the annotated type as an
- * argument. See the {@code MXBeanMapping} documentation
- * for an example.</p>
- *
- * <p>If the {@code MXBeanMapping} cannot in fact handle that
- * type, the constructor should throw an {@link
- * OpenDataException}. If the constructor throws this or any other
- * exception then an MXBean in which the annotated type appears is
- * invalid, and registering it in the MBean Server will produce a
- * {@link NotCompliantMBeanException}.
- */
- public Class<? extends MXBeanMapping> value();
-}
--- a/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +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 javax.management.openmbean;
-
-import com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory;
-import java.lang.reflect.Type;
-
-/**
- * <p>Defines how types are mapped for a given MXBean or set of MXBeans.
- * An {@code MXBeanMappingFactory} can be specified either through the
- * {@link MXBeanMappingFactoryClass} annotation, or through the
- * {@link javax.management.JMX.MBeanOptions JMX.MBeanOptions} argument to a
- * {@link javax.management.StandardMBean StandardMBean} constructor or MXBean
- * proxy.</p>
- *
- * <p>An {@code MXBeanMappingFactory} must return an {@code MXBeanMapping}
- * for any Java type that appears in the MXBeans that the factory is being
- * used for. Usually it does that by handling any custom types, and
- * forwarding everything else to the {@linkplain #DEFAULT default mapping
- * factory}.</p>
- *
- * <p>Consider the {@code MyLinkedList} example from the {@link MXBeanMapping}
- * documentation. If we are unable to change the {@code MyLinkedList} class
- * to add an {@link MXBeanMappingClass} annotation, we could achieve the same
- * effect by defining {@code MyLinkedListMappingFactory} as follows:</p>
- *
- * <pre>
- * public class MyLinkedListMappingFactory extends MXBeanMappingFactory {
- * public MyLinkedListMappingFactory() {}
- *
- * public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
- * throws OpenDataException {
- * if (t == MyLinkedList.class)
- * return new MyLinkedListMapping(t);
- * else
- * return MXBeanMappingFactory.DEFAULT.mappingForType(t, f);
- * }
- * }
- * </pre>
- *
- * <p>The mapping factory handles only the {@code MyLinkedList} class.
- * Every other type is forwarded to the default mapping factory.
- * This includes types such as {@code MyLinkedList[]} and
- * {@code List<MyLinkedList>}; the default mapping factory will recursively
- * invoke {@code MyLinkedListMappingFactory} to map the contained
- * {@code MyLinkedList} type.</p>
- *
- * <p>Once we have defined {@code MyLinkedListMappingFactory}, we can use
- * it in an MXBean interface like this:</p>
- *
- * <pre>
- * {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
- * public interface SomethingMXBean {
- * public MyLinkedList getSomething();
- * }
- * </pre>
- *
- * <p>Alternatively we can annotate the package that {@code SomethingMXBean}
- * appears in, or we can supply the factory to a {@link
- * javax.management.StandardMBean StandardMBean} constructor or MXBean
- * proxy.</p>
- *
- * @see <a href="../MXBean.html#custom">MXBean specification, section
- * "Custom MXBean type mappings"</a>
- */
-public abstract class MXBeanMappingFactory {
- /**
- * <p>Construct an instance of this class.</p>
- */
- protected MXBeanMappingFactory() {}
-
- /**
- * <p>Mapping factory that applies the default rules for MXBean
- * mappings, as described in the <a
- * href="../MXBean.html#MXBean-spec">MXBean specification</a>.</p>
- */
- public static final MXBeanMappingFactory DEFAULT =
- new DefaultMXBeanMappingFactory();
-
- /**
- * <p>Determine the appropriate MXBeanMappingFactory to use for the given
- * MXBean interface, based on its annotations. If the interface has an
- * {@link MXBeanMappingFactoryClass @MXBeanMappingFactoryClass} annotation,
- * that is used to determine the MXBeanMappingFactory. Otherwise, if the
- * package containing the interface has such an annotation, that is used.
- * Otherwise the MXBeanMappingFactory is the {@linkplain #DEFAULT default}
- * one.</p>
- *
- * @param intf the MXBean interface for which to determine the
- * MXBeanMappingFactory.
- *
- * @return the MXBeanMappingFactory for the given MXBean interface.
- *
- * @throws IllegalArgumentException if {@code intf} is null, or if an
- * exception occurs while trying constructing an MXBeanMappingFactory
- * based on an annotation. In the second case, the exception will appear
- * in the {@linkplain Throwable#getCause() cause chain} of the
- * {@code IllegalArgumentException}.
- */
- public static MXBeanMappingFactory forInterface(Class<?> intf) {
- if (intf == null)
- throw new IllegalArgumentException("Null interface");
- MXBeanMappingFactoryClass annot =
- intf.getAnnotation(MXBeanMappingFactoryClass.class);
- if (annot == null) {
- Package p = intf.getPackage();
- if (p != null)
- annot = p.getAnnotation(MXBeanMappingFactoryClass.class);
- }
- if (annot == null)
- return MXBeanMappingFactory.DEFAULT;
- Class<? extends MXBeanMappingFactory> factoryClass = annot.value();
- try {
- return annot.value().newInstance();
- } catch (Exception e) {
- throw new IllegalArgumentException(
- "Could not instantiate MXBeanMappingFactory " +
- factoryClass.getName() +
- " from @MXBeanMappingFactoryClass", e);
- }
- }
-
- /**
- * <p>Return the mapping for the given Java type. Typically, a
- * mapping factory will return mappings for types it handles, and
- * forward other types to another mapping factory, most often
- * the {@linkplain #DEFAULT default one}.</p>
- * @param t the Java type to be mapped.
- * @param f the original mapping factory that was consulted to do
- * the mapping. A mapping factory should pass this parameter intact
- * if it forwards a type to another mapping factory. In the example,
- * this is how {@code MyLinkedListMappingFactory} works for types
- * like {@code MyLinkedList[]} and {@code List<MyLinkedList>}.
- * @return the mapping for the given type.
- * @throws OpenDataException if this type cannot be mapped. This
- * exception is appropriate if the factory is supposed to handle
- * all types of this sort (for example, all linked lists), but
- * cannot handle this particular type.
- */
- public abstract MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
- throws OpenDataException;
-}
--- a/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingFactoryClass.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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 javax.management.openmbean;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>Specifies the MXBean mapping factory to be used for Java types
- * in an MXBean interface, or in all MXBean interfaces in a package.</p>
- *
- * <p>Applying a mapping factory to all Java types in an MXBean interface
- * looks like this:</p>
- *
- * <pre>
- * {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
- * public interface SomethingMXBean {
- * public MyLinkedList getSomething();
- * }
- * </pre>
- *
- * <p>Applying a mapping factory to all Java types in all MXBean interfaces
- * in a package, say {@code com.example.mxbeans}, looks like this. In the
- * package source directory, create a file called {@code package-info.java}
- * with these contents:</p>
- *
- * <pre>
- * {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
- * package com.example.mxbeans;
- * </pre>
- *
- * @see MXBeanMappingFactory
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.PACKAGE})
-@Documented @Inherited
-public @interface MXBeanMappingFactoryClass {
- /**
- * <p>The {@link MXBeanMappingFactory} class to be used to map
- * types in the annotated interface or package. This class must
- * have a public constructor with no arguments. See the {@code
- * MXBeanMappingFactory} documentation for an example.</p>
- */
- public Class<? extends MXBeanMappingFactory> value();
-}
--- a/jdk/src/share/classes/javax/management/openmbean/OpenType.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/openmbean/OpenType.java Wed Oct 21 16:50:44 2009 +0100
@@ -219,7 +219,7 @@
});
}
- static String validClassName(String className) throws OpenDataException {
+ private static String validClassName(String className) throws OpenDataException {
className = valid("className", className);
// Check if className describes an array class, and determines its elements' class name.
--- a/jdk/src/share/classes/javax/management/package.html Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/package.html Wed Oct 21 16:50:44 2009 +0100
@@ -128,42 +128,6 @@
class.</p>
- <h3 id="stdannot">Defining Standard MBeans with annotations</h3>
-
- <p>As an alternative to creating an interface such as
- <code>ConfigurationMBean</code> and a class that implements it,
- you can write just the class, and use annotations to pick out the
- public methods that will make up the management interface. For
- example, the following class has the same management interface
- as a <code>Configuration</code> class that implements the
- <code>ConfigurationMBean</code> interface above.</p>
-
- <pre>
- {@link javax.management.MBean @MBean}
- public class Configuration {
- {@link javax.management.ManagedAttribute @ManagedAttribute}
- public int getCacheSize() {...}
- @ManagedAttribute
- public void setCacheSize(int size) {...}
-
- @ManagedAttribute
- public long getLastChangedTime() {...}
-
- {@link javax.management.ManagedOperation @ManagedOperation}
- public void save() {...}
- ...
- }
- </pre>
-
- <p>This approach simplifies development, but it does have two
- potential drawbacks. First, if you run the Javadoc tool on
- this class, the documentation of the management interface may
- be mixed in with the documentation of non-management methods
- in the class. Second, you cannot make a proxy
- as described <a href="#proxy">below</a> if you do not have an
- interface like <code>ConfigurationMBean</code>.</p>
-
-
<h3>MXBeans</h3>
<p>An <em>MXBean</em> is a variant of Standard MBean where complex
@@ -173,11 +137,6 @@
classes in your MBean interface. They are described in detail
in the specification for {@link javax.management.MXBean MXBean}.</p>
- <p>You can define MXBeans using annotations as described
- in the <a href="#stdannot">previous section</a>, but
- using the <code>@MXBean</code> annotation instead of
- <code>@MBean</code>.</p>
-
<h3>Dynamic MBeans</h3>
@@ -305,7 +264,7 @@
perform the query.</p>
- <h3>MBean lifecycle and resource injection</h3>
+ <h3>MBean lifecycle</h3>
<p>An MBean can implement the {@link javax.management.MBeanRegistration
MBeanRegistration} interface in order to be told when it is registered
@@ -315,11 +274,6 @@
object and to get its <code>ObjectName</code> within the MBean
Server.</p>
- <p>If the only reason to implement <code>MBeanRegistration</code> is to
- discover the <code>MBeanServer</code> and <code>ObjectName</code>, <a
- href="MBeanRegistration.html#injection">resource injection</a> may be
- more convenient.</p>
-
<h2>Notifications</h2>
@@ -329,26 +283,16 @@
<em>type</em> string that can distinguish it from other
notifications of the same class.</p>
- <p>If an MBean is to emit notifications, it must do one of two things.</p>
-
- <ul>
- <li>It can implement the interface {@link
- javax.management.NotificationEmitter NotificationEmitter} (or
- its parent {@link javax.management.NotificationBroadcaster
- NotificationBroadcaster}), usually by subclassing
- {@link javax.management.NotificationBroadcasterSupport
- NotificationBroadcasterSupport} or delegating to an instance of
- that class.</li>
- <li>It can use <a href="MBeanRegistration.html#injection">resource
- injection</a> to obtain a {@link javax.management.SendNotification
- SendNotification} object that it can use to send
- notifications.</li>
- </ul>
-
- <p>The two classes below illustrate these two techniques:</p>
+ <p>An MBean that will emit notifications must implement the
+ {@link javax.management.NotificationBroadcaster
+ NotificationBroadcaster} or {@link
+ javax.management.NotificationEmitter NotificationEmitter}
+ interface. Usually, it does this by subclassing
+ {@link javax.management.NotificationBroadcasterSupport
+ NotificationBroadcasterSupport} or delegating to an instance of
+ that class. Here is an example:</p>
<pre>
- // Implementing NotificationEmitter (via NotificationBroadcasterSupport)
public class Configuration <b>extends NotificationBroadcasterSupport</b>
implements ConfigurationMBean {
...
@@ -358,17 +302,6 @@
sendNotification}(n)</b>;
}
}
-
- // Getting a SendNotification through resource injection
- public class Configuration implements ConfigurationMBean {
- <b>@Resource</b>
- private volatile SendNotification sender;
- ...
- private void updated() {
- Notification n = new Notification(...);
- <b>sender.sendNotification(n)</b>;
- }
- }
</pre>
@@ -410,88 +343,51 @@
<h3 id="interop">Interoperability between versions of the JMX
specification</h3>
- <p>When a client connects to a server using the JMX Remote
- API, it is possible that they do not have the same version
- of the JMX specification. The version of the JMX
- specification described here is version 2.0. Previous
- versions were 1.0, 1.1, 1.2, and 1.4. (There was no 1.3.)
- The standard JMX Remote API is defined to work with version
- 1.2 onwards, so in standards-based deployment the only
- interoperability questions that arise concern version 1.2
- onwards.</p>
+ <p>When a client connects to a server using the JMX Remote
+ API, it is possible that they do not have the same version
+ of the JMX specification. The version of the JMX
+ specification described here is version 1.4. Previous
+ versions were 1.0, 1.1, and 1.2. (There was no 1.3.)
+ The standard JMX Remote API is defined to work with version
+ 1.2 onwards, so in standards-based deployment the only
+ interoperability questions that arise concern version 1.2
+ onwards.</p>
- <p>Every version of the JMX specification continues to
- implement the features of previous versions. So when the
- client is running an earlier version than the server, there
- should not be any interoperability concerns. The only
- exception is the unlikely one where a pre-2.0 client used
- the string {@code //} in the domain part of an {@link
- javax.management.ObjectName ObjectName}.</p>
+ <p>Every version of the JMX specification continues to
+ implement the features of previous versions. So when the
+ client is running an earlier version than the server, there
+ should not be any interoperability concerns.</p>
- <p>When the client is running a later version than the server,
- certain newer features may not be available, as detailed in
- the next sections. The method {@link
- javax.management.JMX#getSpecificationVersion
- JMX.getSpecificationVersion} can be used to determine the
- server version to check if required features are
- available.</p>
+ <p>When the client is running a later version than the server,
+ certain newer features may not be available, as detailed in
+ the next sections. The client can determine the server's
+ version by examining the {@link
+ javax.management.MBeanServerDelegateMBean#getSpecificationVersion
+ SpecificationVersion} attribute of the {@code
+ MBeanServerDelegate}.</p>
- <h4 id="interop-1.4">If the remote MBean Server is 1.4</h4>
+ <h4 id="interop-1.2">If the remote MBean Server is 1.2</h4>
<ul>
- <li><p>You cannot use {@link
- javax.management.QueryNotificationFilter
- QueryNotificationFilter} in {@link
- javax.management.MBeanServerConnection#addNotificationListener
- addNotificationListener} since this class did not exist
- in 1.4.</p>
-
- <li><p>In an attribute in a query, you cannot access values
- inside complex types using dot syntax, for example
- {@link javax.management.Query#attr Query.attr}{@code
- ("HeapMemoryUsage.used")}.</p>
-
- <li><p>The packages {@link javax.management.event} and
- {@link javax.management.namespace} did not exist in 1.4,
- so you cannot remotely create instances of the MBeans
- they define.</p>
+ <li><p>You cannot use wildcards in a key property of an
+ {@link javax.management.ObjectName ObjectName}, for
+ example {@code domain:type=Foo,name=*}. Wildcards that
+ match whole properties are still allowed, for example
+ {@code *:*} or {@code *:type=Foo,*}.</p>
- <li><p>Even if the remote MBean Server is 2.0, you cannot in
- general suppose that {@link
- javax.management.event.EventClient EventClient} or
- {@link javax.management.ClientContext ClientContext}
- will work there without first checking. If the remote
- MBean Server is 1.4 then those checks will return false.
- An attempt to use these features without checking will
- fail in the same way as for a remote 2.0 that is not
- configured to support them.</p>
- </ul>
-
- <h4 id="interop-1.2">If the remote MBean Server is 1.2</h4>
-
- <p><b>In addition to the above</b>,</p>
-
- <ul>
+ <li><p>You cannot use {@link
+ javax.management.Query#isInstanceOf Query.isInstanceOf}
+ in a query.</p>
- <li><p>You cannot use wildcards in a key property of an
- {@link javax.management.ObjectName ObjectName}, for
- example {@code domain:type=Foo,name=*}. Wildcards that
- match whole properties are still allowed, for example
- {@code *:*} or {@code *:type=Foo,*}.</p>
+ <li><p>You cannot use dot syntax such as {@code
+ HeapMemoryUsage.used} in the {@linkplain
+ javax.management.monitor.Monitor#setObservedAttribute
+ observed attribute} of a monitor, as described in the
+ documentation for the {@link javax.management.monitor}
+ package.</p>
- <li><p>You cannot use {@link
- javax.management.Query#isInstanceOf Query.isInstanceOf}
- in a query.</p>
-
- <li><p>You cannot use dot syntax such as {@code
- HeapMemoryUsage.used} in the {@linkplain
- javax.management.monitor.Monitor#setObservedAttribute
- observed attribute} of a monitor, as described in the
- documentation for the {@link javax.management.monitor}
- package.</p>
-
- </ul>
+ </ul>
<p id="spec">
@see <a href="{@docRoot}/../technotes/guides/jmx/index.html">
--- a/jdk/src/share/classes/javax/management/remote/IdentityMBeanServerForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,303 +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 javax.management.remote;
-
-import java.io.ObjectInputStream;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.OperationsException;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.loading.ClassLoaderRepository;
-
-/**
- * An {@link MBeanServerForwarder} that forwards all {@link MBeanServer}
- * operations unchanged to the next {@code MBeanServer} in the chain.
- * This class is typically subclassed to override some but not all methods.
- */
-public class IdentityMBeanServerForwarder implements MBeanServerForwarder {
-
- private MBeanServer next;
-
- /**
- * <p>Construct a forwarder that has no next {@code MBeanServer}.
- * The resulting object will be unusable until {@link #setMBeanServer
- * setMBeanServer} is called to establish the next item in the chain.</p>
- */
- public IdentityMBeanServerForwarder() {
- }
-
- /**
- * <p>Construct a forwarder that forwards to the given {@code MBeanServer}.
- * It is not an error for {@code next} to be null, but the resulting object
- * will be unusable until {@link #setMBeanServer setMBeanServer} is called
- * to establish the next item in the chain.</p>
- */
- public IdentityMBeanServerForwarder(MBeanServer next) {
- this.next = next;
- }
-
- public synchronized MBeanServer getMBeanServer() {
- return next;
- }
-
- public synchronized void setMBeanServer(MBeanServer mbs) {
- next = mbs;
- }
-
- private synchronized MBeanServer next() {
- return next;
- }
-
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException, MBeanRegistrationException {
- next().unregisterMBean(name);
- }
-
- public AttributeList setAttributes(ObjectName name,
- AttributeList attributes)
- throws InstanceNotFoundException, ReflectionException {
- return next().setAttributes(name, attributes);
- }
-
- public void setAttribute(ObjectName name, Attribute attribute)
- throws InstanceNotFoundException, AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- next().setAttribute(name, attribute);
- }
-
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- next().removeNotificationListener(name, listener, filter, handback);
- }
-
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- next().removeNotificationListener(name, listener);
- }
-
- public void removeNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException, ListenerNotFoundException {
- next().removeNotificationListener(name, listener, filter, handback);
- }
-
- public void removeNotificationListener(ObjectName name, ObjectName listener)
- throws InstanceNotFoundException, ListenerNotFoundException {
- next().removeNotificationListener(name, listener);
- }
-
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException, MBeanRegistrationException,
- NotCompliantMBeanException {
- return next().registerMBean(object, name);
- }
-
- public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- return next().queryNames(name, query);
- }
-
- public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
- return next().queryMBeans(name, query);
- }
-
- public boolean isRegistered(ObjectName name) {
- return next().isRegistered(name);
- }
-
- public boolean isInstanceOf(ObjectName name, String className)
- throws InstanceNotFoundException {
- return next().isInstanceOf(name, className);
- }
-
- public Object invoke(ObjectName name, String operationName, Object[] params,
- String[] signature)
- throws InstanceNotFoundException, MBeanException,
- ReflectionException {
- return next().invoke(name, operationName, params, signature);
- }
-
- public Object instantiate(String className, ObjectName loaderName,
- Object[] params, String[] signature)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- return next().instantiate(className, loaderName, params, signature);
- }
-
- public Object instantiate(String className, Object[] params,
- String[] signature)
- throws ReflectionException, MBeanException {
- return next().instantiate(className, params, signature);
- }
-
- public Object instantiate(String className, ObjectName loaderName)
- throws ReflectionException, MBeanException,
- InstanceNotFoundException {
- return next().instantiate(className, loaderName);
- }
-
- public Object instantiate(String className)
- throws ReflectionException, MBeanException {
- return next().instantiate(className);
- }
-
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException {
- return next().getObjectInstance(name);
- }
-
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException, IntrospectionException,
- ReflectionException {
- return next().getMBeanInfo(name);
- }
-
- public Integer getMBeanCount() {
- return next().getMBeanCount();
- }
-
- public String[] getDomains() {
- return next().getDomains();
- }
-
- public String getDefaultDomain() {
- return next().getDefaultDomain();
- }
-
- public ClassLoaderRepository getClassLoaderRepository() {
- return next().getClassLoaderRepository();
- }
-
- public ClassLoader getClassLoaderFor(ObjectName mbeanName)
- throws InstanceNotFoundException {
- return next().getClassLoaderFor(mbeanName);
- }
-
- public ClassLoader getClassLoader(ObjectName loaderName)
- throws InstanceNotFoundException {
- return next().getClassLoader(loaderName);
- }
-
- public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException {
- return next().getAttributes(name, attributes);
- }
-
- public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException,
- InstanceNotFoundException, ReflectionException {
- return next().getAttribute(name, attribute);
- }
-
- @Deprecated
- public ObjectInputStream deserialize(String className,
- ObjectName loaderName,
- byte[] data)
- throws InstanceNotFoundException, OperationsException,
- ReflectionException {
- return next().deserialize(className, loaderName, data);
- }
-
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException {
- return next().deserialize(className, data);
- }
-
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException {
- return next().deserialize(name, data);
- }
-
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName, Object[] params,
- String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- return next().createMBean(className, name, loaderName, params, signature);
- }
-
- public ObjectInstance createMBean(String className, ObjectName name,
- Object[] params, String[] signature)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- return next().createMBean(className, name, params, signature);
- }
-
- public ObjectInstance createMBean(String className, ObjectName name,
- ObjectName loaderName)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- return next().createMBean(className, name, loaderName);
- }
-
- public ObjectInstance createMBean(String className, ObjectName name)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException {
- return next().createMBean(className, name);
- }
-
- public void addNotificationListener(ObjectName name, ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- next().addNotificationListener(name, listener, filter, handback);
- }
-
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException {
- next().addNotificationListener(name, listener, filter, handback);
- }
-}
--- a/jdk/src/share/classes/javax/management/remote/JMXConnector.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/JMXConnector.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2007 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
@@ -57,26 +57,6 @@
public static final String CREDENTIALS =
"jmx.remote.credentials";
- /**
- * <p>Name of the attribute that specifies whether to use the
- * {@linkplain javax.management.event Event Service} to handle
- * notifications for this connector. The value associated with
- * this attribute, if any, is a String, which must be equal,
- * ignoring case, to {@code "true"} or {@code "false"}.</p>
- *
- * <p>Not all connectors will understand this attribute, but the
- * standard {@linkplain javax.management.remote.rmi.RMIConnector
- * RMI Connector} does.</p>
- *
- * <p>If this attribute is not present, then the system property of the
- * same name (<code>{@value}</code>) is consulted. If that is not set
- * either, then the Event Service is not used.</p>
- *
- * @since 1.7
- */
- public static final String USE_EVENT_SERVICE =
- "jmx.remote.use.event.service";
-
/**
* <p>Establishes the connection to the connector server. This
* method is equivalent to {@link #connect(Map)
--- a/jdk/src/share/classes/javax/management/remote/JMXConnectorServer.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorServer.java Wed Oct 21 16:50:44 2009 +0100
@@ -26,22 +26,17 @@
package javax.management.remote;
-import com.sun.jmx.remote.util.EnvHelp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
-import javax.management.ClientContext;
-import javax.management.MBeanInfo; // for javadoc
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;
-import javax.management.event.EventClientDelegate;
/**
* <p>Superclass of every connector server. A connector server is
@@ -80,98 +75,6 @@
public static final String AUTHENTICATOR =
"jmx.remote.authenticator";
- /**
- * <p>Name of the attribute that specifies whether this connector
- * server can delegate notification handling to the
- * {@linkplain javax.management.event Event Service}.
- * The value associated with
- * this attribute, if any, is a String, which must be equal,
- * ignoring case, to {@code "true"} or {@code "false"}.</p>
- *
- * <p>Not all connector servers will understand this attribute, but the
- * standard {@linkplain javax.management.remote.rmi.RMIConnectorServer
- * RMI Connector Server} does.</p>
- *
- * <p>If this attribute is not present, then the system property of the
- * same name (<code>{@value}</code>) is consulted. If that is not set
- * either, then the Event Service is used if the connector server
- * supports it.</p>
- *
- * @since 1.7
- */
- public static final String DELEGATE_TO_EVENT_SERVICE =
- "jmx.remote.delegate.event.service";
-
- /**
- * <p>Name of the attribute that specifies whether this connector
- * server allows clients to communicate a context with each request.
- * The value associated with this attribute, if any, must be a string
- * that is equal to {@code "true"} or {@code "false"}, ignoring case.
- * If it is {@code "true"}, then the connector server will simulate
- * a namespace {@code jmx.context//}, as described in
- * {@link ClientContext#newContextForwarder}. This namespace is needed
- * for {@link ClientContext#withContext ClientContext.withContext} to
- * function correctly.</p>
- *
- * <p>Not all connector servers will understand this attribute, but the
- * standard {@linkplain javax.management.remote.rmi.RMIConnectorServer
- * RMI Connector Server} does. For a connector server that understands
- * this attribute, the default value is {@code "true"}.</p>
- *
- * @since 1.7
- */
- public static final String CONTEXT_FORWARDER =
- "jmx.remote.context.forwarder";
-
- /**
- * <p>Name of the attribute that specifies whether this connector server
- * localizes the descriptions in the {@link MBeanInfo} object returned by
- * {@link MBeanServer#getMBeanInfo MBeanServer.getMBeanInfo}, based on the
- * locale communicated by the client.</p>
- *
- * <p>The value associated with this attribute, if any, must be a string
- * that is equal to {@code "true"} or {@code "false"}, ignoring case.
- * If it is {@code "true"}, then the connector server will localize
- * {@code MBeanInfo} descriptions as specified in {@link
- * ClientContext#newLocalizeMBeanInfoForwarder}.</p>
- *
- * <p>Not all connector servers will understand this attribute, but the
- * standard {@linkplain javax.management.remote.rmi.RMIConnectorServer
- * RMI Connector Server} does. For a connector server that understands
- * this attribute, the default value is {@code "false"}.</p>
- *
- * <p>Because localization requires the client to be able to communicate
- * its locale, it does not make sense to specify this attribute as
- * {@code "true"} if {@link #CONTEXT_FORWARDER} is not also {@code "true"}.
- * For a connector server that understands these attributes, specifying
- * this inconsistent combination will result in an {@link
- * IllegalArgumentException}.</p>
- *
- * @since 1.7
- */
- public static final String LOCALIZE_MBEAN_INFO_FORWARDER =
- "jmx.remote.localize.mbean.info";
-
- /**
- * <p>Name of the attribute that specifies whether this connector
- * server simulates the existence of the {@link EventClientDelegate}
- * MBean. The value associated with this attribute, if any, must
- * be a string that is equal to {@code "true"} or {@code "false"},
- * ignoring case. If it is {@code "true"}, then the connector server
- * will simulate an EventClientDelegate MBean, as described in {@link
- * EventClientDelegate#newForwarder}. This MBean is needed for {@link
- * javax.management.event.EventClient EventClient} to function correctly.</p>
- *
- * <p>Not all connector servers will understand this attribute, but the
- * standard {@linkplain javax.management.remote.rmi.RMIConnectorServer
- * RMI Connector Server} does. For a connector server that understands
- * this attribute, the default value is {@code "true"}.</p>
- *
- * @since 1.7
- */
- public static final String EVENT_CLIENT_DELEGATE_FORWARDER =
- "jmx.remote.event.client.delegate.forwarder";
-
/**
* <p>Constructs a connector server that will be registered as an
* MBean in the MBean server it is attached to. This constructor
@@ -194,322 +97,27 @@
* to an MBean server by being registered in it.
*/
public JMXConnectorServer(MBeanServer mbeanServer) {
- insertUserMBeanServer(mbeanServer);
+ this.mbeanServer = mbeanServer;
}
/**
* <p>Returns the MBean server that this connector server is
- * attached to, or the first in a chain of user-added
- * {@link MBeanServerForwarder}s, if any.</p>
+ * attached to.</p>
*
* @return the MBean server that this connector server is attached
* to, or null if it is not yet attached to an MBean server.
- *
- * @see #setMBeanServerForwarder
- * @see #getSystemMBeanServerForwarder
*/
public synchronized MBeanServer getMBeanServer() {
- return userMBeanServer;
+ return mbeanServer;
}
- public synchronized void setMBeanServerForwarder(MBeanServerForwarder mbsf) {
+ public synchronized void setMBeanServerForwarder(MBeanServerForwarder mbsf)
+ {
if (mbsf == null)
throw new IllegalArgumentException("Invalid null argument: mbsf");
- if (userMBeanServer != null)
- mbsf.setMBeanServer(userMBeanServer);
- insertUserMBeanServer(mbsf);
- }
-
- /**
- * <p>Remove a forwarder from the chain of forwarders. The forwarder can
- * be in the system chain or the user chain. On successful return from
- * this method, the first occurrence in the chain of an object that is
- * {@linkplain Object#equals equal} to {@code mbsf} will have been
- * removed.</p>
- *
- * @param mbsf the forwarder to remove
- *
- * @throws NoSuchElementException if there is no occurrence of {@code mbsf}
- * in the chain.
- * @throws IllegalArgumentException if {@code mbsf} is null or is the
- * {@linkplain #getSystemMBeanServerForwarder() system forwarder}.
- *
- * @since 1.7
- */
- public synchronized void removeMBeanServerForwarder(MBeanServerForwarder mbsf) {
- if (mbsf == null)
- throw new IllegalArgumentException("Invalid null argument: mbsf");
- if (systemMBeanServerForwarder.equals(mbsf))
- throw new IllegalArgumentException("Cannot remove system forwarder");
-
- MBeanServerForwarder prev = systemMBeanServerForwarder;
- MBeanServer curr;
- while (true) {
- curr = prev.getMBeanServer();
- if (mbsf.equals(curr))
- break;
- if (curr instanceof MBeanServerForwarder)
- prev = (MBeanServerForwarder) curr;
- else
- throw new NoSuchElementException("MBeanServerForwarder not in chain");
- }
- MBeanServer next = mbsf.getMBeanServer();
- prev.setMBeanServer(next);
- if (userMBeanServer == mbsf)
- userMBeanServer = next;
- }
-
- /*
- * Set userMBeanServer to mbs and arrange for the end of the chain of
- * system MBeanServerForwarders to point to it. See the comment before
- * the systemMBeanServer and userMBeanServer field declarations.
- */
- private void insertUserMBeanServer(MBeanServer mbs) {
- MBeanServerForwarder lastSystemMBSF = systemMBeanServerForwarder;
- while (true) {
- MBeanServer mbsi = lastSystemMBSF.getMBeanServer();
- if (mbsi == userMBeanServer)
- break;
- lastSystemMBSF = (MBeanServerForwarder) mbsi;
- }
- userMBeanServer = mbs;
- lastSystemMBSF.setMBeanServer(mbs);
- }
-
- /**
- * <p>Returns the first item in the chain of system and then user
- * forwarders. There is a chain of {@link MBeanServerForwarder}s between
- * a {@code JMXConnectorServer} and its {@code MBeanServer}. This chain
- * consists of two sub-chains: first the <em>system chain</em> and then
- * the <em>user chain</em>. Incoming requests are given to the first
- * forwarder in the system chain. Each forwarder can handle a request
- * itself, or more usually forward it to the next forwarder, perhaps with
- * some extra behavior such as logging or security checking before or after
- * the forwarding. The last forwarder in the system chain is followed by
- * the first forwarder in the user chain.</p>
- *
- * <p>The object returned by this method is the first forwarder in the
- * system chain. For a given {@code JMXConnectorServer}, this method
- * always returns the same object, which simply forwards every request
- * to the next object in the chain.</p>
- *
- * <p>Not all connector servers support a system chain of forwarders,
- * although the standard {@linkplain
- * javax.management.remote.rmi.RMIConnectorServer RMI connector
- * server} does. For those that do not, this method will throw {@code
- * UnsupportedOperationException}. All
- * connector servers do support a user chain of forwarders.</p>
- *
- * <p>The <em>system chain</em> is usually defined by a
- * connector server based on the environment Map; see {@link
- * JMXConnectorServerFactory#newJMXConnectorServer
- * JMXConnectorServerFactory.newJMXConnectorServer}. Allowing
- * the connector server to define its forwarders in this way
- * ensures that they are in the correct order - some forwarders
- * need to be inserted before others for correct behavior. It is
- * possible to modify the system chain, for example using {@code
- * connectorServer.getSystemMBeanServerForwarder().setMBeanServer(mbsf)} or
- * {@link #removeMBeanServerForwarder removeMBeanServerForwarder}, but in
- * that case the system chain is no longer guaranteed to be correct.</p>
- *
- * <p>The <em>user chain</em> is defined by calling {@link
- * #setMBeanServerForwarder setMBeanServerForwarder} to insert forwarders
- * at the head of the user chain.</p>
- *
- * <p>This code illustrates how the chains can be traversed:</p>
- *
- * <pre>
- * JMXConnectorServer cs;
- * System.out.println("system chain:");
- * MBeanServer mbs = cs.getSystemMBeanServerForwarder();
- * while (true) {
- * if (mbs == cs.getMBeanServer())
- * System.out.println("user chain:");
- * if (!(mbs instanceof MBeanServerForwarder))
- * break;
- * MBeanServerForwarder mbsf = (MBeanServerForwarder) mbs;
- * System.out.println("--forwarder: " + mbsf);
- * mbs = mbsf.getMBeanServer();
- * }
- * System.out.println("--MBean Server");
- * </pre>
- *
- * <h4>Note for connector server implementors</h4>
- *
- * <p>Existing connector server implementations can be updated to support
- * a system chain of forwarders as follows:</p>
- *
- * <ul>
- * <li><p>Override the {@link #supportsSystemMBeanServerForwarder()}
- * method so that it returns true.</p>
- *
- * <li><p>Call {@link #installStandardForwarders} from the constructor of
- * the connector server.</p>
- *
- * <li><p>Direct incoming requests to the result of {@link
- * #getSystemMBeanServerForwarder()} instead of the result of {@link
- * #getMBeanServer()}.</p>
- * </ul>
- *
- * @return the first item in the system chain of forwarders.
- *
- * @throws UnsupportedOperationException if {@link
- * #supportsSystemMBeanServerForwarder} returns false.
- *
- * @see #supportsSystemMBeanServerForwarder
- * @see #setMBeanServerForwarder
- *
- * @since 1.7
- */
- public MBeanServerForwarder getSystemMBeanServerForwarder() {
- if (!supportsSystemMBeanServerForwarder()) {
- throw new UnsupportedOperationException(
- "System MBeanServerForwarder not supported by this " +
- "connector server");
- }
- return systemMBeanServerForwarder;
- }
-
- /**
- * <p>Returns true if this connector server supports a system chain of
- * {@link MBeanServerForwarder}s. The default implementation of this
- * method returns false. Connector servers that do support the system
- * chain must override this method to return true.
- *
- * @return true if this connector server supports the system chain of
- * forwarders.
- *
- * @since 1.7
- */
- public boolean supportsSystemMBeanServerForwarder() {
- return false;
- }
-
- /**
- * Closes a client connection. If the connection is successfully closed,
- * the method {@link #connectionClosed} is called to notify interested parties.
- * <P>Not all connector servers support this method. For those that do, it
- * should be possible to cause a new client connection to fail before it
- * can be used, by calling this method from within a
- * {@link javax.management.NotificationListener}
- * when it receives a {@link JMXConnectionNotification#OPENED} notification.
- * This allows the owner of a connector server to deny certain connections,
- * typically based on the information in the connection id.
- * <P>The implementation of this method in {@code JMXConnectorServer} throws
- * {@code UnsupportedOperationException}. Subclasses can override this
- * method to support closing a specified client connection.
- *
- * @param connectionId the id of the client connection to be closed.
- * @throws IllegalStateException if the server is not started or is closed.
- * @throws IllegalArgumentException if {@code connectionId} is null or is
- * not the id of any open connection.
- * @throws java.io.IOException if an I/O error appears when closing the
- * connection.
- *
- * @since 1.7
- */
- public void closeConnection(String connectionId)
- throws IOException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * <p>Install {@link MBeanServerForwarder}s in the system chain
- * based on the attributes in the given {@code Map}. A connector
- * server that {@linkplain #supportsSystemMBeanServerForwarder supports}
- * a system chain of {@code MBeanServerForwarder}s can call this method
- * to add forwarders to that chain based on the contents of {@code env}.
- * In order:</p>
- *
- * <ul>
- *
- * <li>If {@link #EVENT_CLIENT_DELEGATE_FORWARDER} is absent, or is
- * present with the value {@code "true"}, then a forwarder
- * equivalent to {@link EventClientDelegate#newForwarder
- * EventClientDelegate.newForwarder}{@code (sysMBSF.getMBeanServer(),
- * sysMBSF)} is inserted at the start of the system chain,
- * where {@code sysMBSF} is the object returned by {@link
- * #getSystemMBeanServerForwarder()}. </li>
- *
- * <li>If {@link #LOCALIZE_MBEAN_INFO_FORWARDER} is present with the
- * value {@code "true"}, then a forwarder equivalent to
- * {@link ClientContext#newLocalizeMBeanInfoForwarder
- * ClientContext.newLocalizeMBeanInfoForwarder}{@code
- * (sysMBSF.getMBeanServer())} is inserted at the start of the system
- * chain.</li>
- *
- * <li>If {@link #CONTEXT_FORWARDER} is absent, or is present with
- * the value {@code "true"}, then a forwarder equivalent to
- * {@link ClientContext#newContextForwarder
- * ClientContext.newContextForwarder}{@code (sysMSBF.getMBeanServer(),
- * sysMBSF)} is inserted at the tart of the system chain.</li>
- *
- * </ul>
- *
- * <p>For {@code EVENT_CLIENT_DELEGATE_FORWARDER} and {@code
- * CONTEXT_FORWARDER}, if the attribute is absent from the {@code
- * Map} and a system property of the same name is defined, then
- * the value of the system property is used as if it were in the
- * {@code Map}.
- *
- * <p>Since each forwarder is inserted at the start of the chain,
- * the final order of the forwarders is the <b>reverse</b> of the order
- * above. This is important, because the {@code
- * LOCALIZE_MBEAN_INFO_FORWARDER} can only work if the {@code
- * CONTEXT_FORWARDER} has already installed the remote client's locale
- * in the {@linkplain ClientContext#getContext context} of the current
- * thread.</p>
- *
- * <p>Attributes in {@code env} that are not listed above are ignored
- * by this method.</p>
- *
- * @throws UnsupportedOperationException if {@link
- * #supportsSystemMBeanServerForwarder} is false.
- *
- * @throws IllegalArgumentException if the relevant attributes in {@code env} are
- * inconsistent, for example if {@link #LOCALIZE_MBEAN_INFO_FORWARDER} is
- * {@code "true"} but {@link #CONTEXT_FORWARDER} is {@code "false"}; or
- * if one of the attributes has an illegal value.
- *
- * @since 1.7
- */
- protected void installStandardForwarders(Map<String, ?> env) {
- MBeanServerForwarder sysMBSF = getSystemMBeanServerForwarder();
-
- // Remember that forwarders must be added in reverse order!
-
- boolean ecd = EnvHelp.computeBooleanFromString(
- env, EVENT_CLIENT_DELEGATE_FORWARDER, false, true);
- boolean localize = EnvHelp.computeBooleanFromString(
- env, LOCALIZE_MBEAN_INFO_FORWARDER, false, false);
- boolean context = EnvHelp.computeBooleanFromString(
- env, CONTEXT_FORWARDER, false, true);
-
- if (localize && !context) {
- throw new IllegalArgumentException(
- "Inconsistent environment parameters: " +
- LOCALIZE_MBEAN_INFO_FORWARDER + "=\"true\" requires " +
- CONTEXT_FORWARDER + "=\"true\"");
- }
-
- if (ecd) {
- MBeanServerForwarder mbsf = EventClientDelegate.newForwarder(
- sysMBSF.getMBeanServer(), sysMBSF);
- sysMBSF.setMBeanServer(mbsf);
- }
-
- if (localize) {
- MBeanServerForwarder mbsf = ClientContext.newLocalizeMBeanInfoForwarder(
- sysMBSF.getMBeanServer());
- sysMBSF.setMBeanServer(mbsf);
- }
-
- if (context) {
- MBeanServerForwarder mbsf = ClientContext.newContextForwarder(
- sysMBSF.getMBeanServer(), sysMBSF);
- sysMBSF.setMBeanServer(mbsf);
- }
+ if (mbeanServer != null) mbsf.setMBeanServer(mbeanServer);
+ mbeanServer = mbsf;
}
public String[] getConnectionIds() {
@@ -753,8 +361,8 @@
ObjectName name) {
if (mbs == null || name == null)
throw new NullPointerException("Null MBeanServer or ObjectName");
- if (userMBeanServer == null) {
- insertUserMBeanServer(mbs);
+ if (mbeanServer == null) {
+ mbeanServer = mbs;
myName = name;
}
return name;
@@ -788,53 +396,10 @@
myName = null;
}
- /*
- * Fields describing the chains of forwarders (MBeanServerForwarders).
- * In the general case, the forwarders look something like this:
- *
- * userMBeanServer
- * |
- * v
- * systemMBeanServerForwarder -> mbsf2 -> mbsf3 -> mbsf4 -> mbsf5 -> mbs
- *
- * Here, each mbsfi is an MBeanServerForwarder, and the arrows
- * illustrate its getMBeanServer() method. The last MBeanServerForwarder
- * can point to an MBeanServer that is not instanceof MBeanServerForwarder,
- * here mbs.
- *
- * The system chain is never empty because it always has at least
- * systemMBeanServerForwarder. Initially, the user chain can be empty if
- * this JMXConnectorServer was constructed without an MBeanServer. In
- * this case, userMBS will be null. If there is initially an MBeanServer,
- * userMBS will point to it.
- *
- * Whenever userMBS is changed, the system chain must be updated. Before
- * the update, the last forwarder in the system chain points to the old
- * value of userMBS (possibly null). It must be updated to point to
- * the new value. The invariant is that starting from systemMBSF and
- * repeatedly calling MBSF.getMBeanServer() you will end up at userMBS.
- * The implication is that you will not see any MBeanServer object on the
- * way that is not also an MBeanServerForwarder.
- *
- * The method insertUserMBeanServer contains the logic to change userMBS
- * and adjust the system chain appropriately.
- *
- * If userMBS is null and this JMXConnectorServer is registered in an
- * MBeanServer, then userMBS becomes that MBeanServer, and the system
- * chain must be updated as just described.
- *
- * When systemMBSF is updated, there is no effect on userMBS. The system
- * chain may contain forwarders even though the user chain is empty
- * (there is no MBeanServer). In that case an attempt to forward an
- * incoming request through the chain will fall off the end and fail with a
- * NullPointerException. Usually a connector server will refuse to start()
- * if it is not attached to an MBS, so this situation should not arise.
+ /**
+ * The MBeanServer used by this server to execute a client request.
*/
-
- private MBeanServer userMBeanServer;
-
- private final MBeanServerForwarder systemMBeanServerForwarder =
- new IdentityMBeanServerForwarder();
+ private MBeanServer mbeanServer = null;
/**
* The name used to registered this server in an MBeanServer.
@@ -842,7 +407,7 @@
*/
private ObjectName myName;
- private List<String> connectionIds = new ArrayList<String>();
+ private final List<String> connectionIds = new ArrayList<String>();
private static final int[] sequenceNumberLock = new int[0];
private static long sequenceNumber;
--- a/jdk/src/share/classes/javax/management/remote/JMXConnectorServerMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorServerMBean.java Wed Oct 21 16:50:44 2009 +0100
@@ -130,18 +130,12 @@
* <code>MBeanServer</code>.</p>
* </ul>
*
- * <p>A connector server may support two chains of forwarders,
- * a system chain and a user chain. See {@link
- * JMXConnectorServer#getSystemMBeanServerForwarder} for details.</p>
- *
* @param mbsf the new <code>MBeanServerForwarder</code>.
*
* @exception IllegalArgumentException if the call to {@link
* MBeanServerForwarder#setMBeanServer mbsf.setMBeanServer} fails
* with <code>IllegalArgumentException</code>. This includes the
* case where <code>mbsf</code> is null.
- *
- * @see JMXConnectorServer#getSystemMBeanServerForwarder
*/
public void setMBeanServerForwarder(MBeanServerForwarder mbsf);
--- a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java Wed Oct 21 16:50:44 2009 +0100
@@ -36,8 +36,6 @@
import java.net.UnknownHostException;
import java.util.BitSet;
import java.util.StringTokenizer;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.InvalidKeyException;
/**
* <p>The address of a JMX API connector server. Instances of this class
@@ -338,50 +336,6 @@
validate();
}
- /**
- * <p>Construct a {@code JMXServiceURL} instance from the given
- * {@code CompositeData}. The presence of this method means that
- * {@code JMXServiceURL} is <a href="../MXBean.html#reconstructible-def">
- * reconstructible</a> in MXBeans.</p>
- *
- * <p>(The effect of this method could have been obtained more simply
- * with a @{@link java.beans.ConstructorProperties ConstructorProperties}
- * annotation on the four-parameter {@linkplain #JMXServiceURL(
- * String, String, int, String) constructor}, but that would have meant
- * that this API could not be implemented on versions of the Java platform
- * that predated the introduction of that annotation.)</p>
- *
- * @param cd a {@code CompositeData} object that must contain items called
- * {@code protocol}, {@code host}, and {@code URLPath} of type {@code String}
- * and {@code port} of type {@code Integer}. Such an object will be produced
- * by the MXBean framework when <a
- * href="../MXBean.html#composite-map">mapping</a> a {@code JMXServiceURL}
- * instance to an Open Data value.
- *
- * @return a {@code JMXServiceURL} constructed with the protocol, host,
- * port, and URL path extracted from the given {@code CompositeData}.
- *
- * @throws MalformedURLException if the given {@code CompositeData} does
- * not contain all the required items with the required types or if the
- * resultant URL is syntactically incorrect.
- */
- public static JMXServiceURL from(CompositeData cd)
- throws MalformedURLException {
- try {
- String proto = (String) cd.get("protocol");
- String host = (String) cd.get("host");
- int port = (Integer) cd.get("port");
- String urlPath = (String) cd.get("URLPath");
- return new JMXServiceURL(proto, host, port, urlPath);
- } catch (RuntimeException e) {
- // Could be InvalidKeyException if the item is missing,
- // or ClassCastException if it is present but with the wrong type.
- MalformedURLException x = new MalformedURLException(e.getMessage());
- x.initCause(e);
- throw x;
- }
- }
-
private void validate() throws MalformedURLException {
// Check protocol
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,12 +25,10 @@
package javax.management.remote.rmi;
-import com.sun.jmx.mbeanserver.Util;
import static com.sun.jmx.mbeanserver.Util.cast;
import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
import com.sun.jmx.remote.internal.ServerNotifForwarder;
import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
-import com.sun.jmx.remote.security.NotificationAccessController;
import com.sun.jmx.remote.security.SubjectDelegator;
import com.sun.jmx.remote.util.ClassLoaderWithRepository;
import com.sun.jmx.remote.util.ClassLogger;
@@ -38,7 +36,6 @@
import com.sun.jmx.remote.util.OrderClassLoaders;
import java.io.IOException;
-import java.lang.reflect.UndeclaredThrowableException;
import java.rmi.MarshalledObject;
import java.rmi.UnmarshalException;
import java.rmi.server.Unreferenced;
@@ -59,25 +56,18 @@
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
-import javax.management.JMX;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.EventClientNotFoundException;
-import javax.management.event.FetchingEventForwarder;
-import javax.management.namespace.JMXNamespaces;
import javax.management.remote.JMXServerErrorException;
import javax.management.remote.NotificationResult;
import javax.management.remote.TargetedNotification;
@@ -168,6 +158,17 @@
this.env = env;
}
+ private synchronized ServerNotifForwarder getServerNotifFwd() {
+ // Lazily created when first use. Mainly when
+ // addNotificationListener is first called.
+ if (serverNotifForwarder == null)
+ serverNotifForwarder =
+ new ServerNotifForwarder(mbeanServer,
+ env,
+ rmiServer.getNotifBuffer(),
+ connectionId);
+ return serverNotifForwarder;
+ }
public String getConnectionId() throws IOException {
// We should call reqIncomming() here... shouldn't we?
@@ -178,7 +179,6 @@
final boolean debug = logger.debugOn();
final String idstr = (debug?"["+this.toString()+"]":null);
- final SubscriptionManager mgr;
synchronized (this) {
if (terminated) {
if (debug) logger.debug("close",idstr + " already terminated.");
@@ -193,12 +193,11 @@
serverCommunicatorAdmin.terminate();
}
- mgr = subscriptionManager;
- subscriptionManager = null;
+ if (serverNotifForwarder != null) {
+ serverNotifForwarder.terminate();
+ }
}
- if (mgr != null) mgr.terminate();
-
rmiServer.clientClosed(this);
if (debug) logger.debug("close",idstr + " closed.");
@@ -997,7 +996,8 @@
// remove all registered listeners
for (int j=0; j<i; j++) {
try {
- doRemoveListener(names[j],ids[j]);
+ getServerNotifFwd().removeNotificationListener(names[j],
+ ids[j]);
} catch (Exception eee) {
// strange
}
@@ -1247,330 +1247,22 @@
final long csn = clientSequenceNumber;
final int mn = maxNotifications;
final long t = timeout;
-
- final PrivilegedExceptionAction<NotificationResult> action =
- new PrivilegedExceptionAction<NotificationResult>() {
- public NotificationResult run() throws IOException {
- return doFetchNotifs(csn, t, mn);
+ PrivilegedAction<NotificationResult> action =
+ new PrivilegedAction<NotificationResult>() {
+ public NotificationResult run() {
+ return getServerNotifFwd().fetchNotifs(csn, t, mn);
}
};
- try {
- if (acc == null)
- return action.run();
- else
- return AccessController.doPrivileged(action, acc);
- } catch (IOException x) {
- throw x;
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- // should not happen
- throw new UndeclaredThrowableException(x);
- }
-
+ if (acc == null)
+ return action.run();
+ else
+ return AccessController.doPrivileged(action, acc);
} finally {
serverCommunicatorAdmin.rspOutgoing();
}
}
/**
- * This is an abstraction class that let us use the legacy
- * ServerNotifForwarder and the new EventClientDelegateMBean
- * indifferently.
- **/
- private static interface SubscriptionManager {
- public void removeNotificationListener(ObjectName name, Integer id)
- throws InstanceNotFoundException, ListenerNotFoundException, IOException;
- public void removeNotificationListener(ObjectName name, Integer[] ids)
- throws Exception;
- public NotificationResult fetchNotifications(long csn, long timeout, int maxcount)
- throws IOException;
- public Integer addNotificationListener(ObjectName name, NotificationFilter filter)
- throws InstanceNotFoundException, IOException;
- public void terminate()
- throws IOException;
- }
-
- /**
- * A SubscriptionManager that uses a ServerNotifForwarder.
- **/
- private static class LegacySubscriptionManager implements SubscriptionManager {
- private final ServerNotifForwarder forwarder;
- LegacySubscriptionManager(ServerNotifForwarder forwarder) {
- this.forwarder = forwarder;
- }
-
- public void removeNotificationListener(ObjectName name, Integer id)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- if (!JMXNamespaces.getContainingNamespace(name).equals("")) {
- logger.debug("removeNotificationListener",
- "This connector server is not configured to support " +
- "forwarding of notification subscriptions to name spaces");
- throw new RuntimeOperationsException(
- new UnsupportedOperationException(
- "removeNotificationListener on name space MBeans. "));
- }
- forwarder.removeNotificationListener(name,id);
- }
-
- public void removeNotificationListener(ObjectName name, Integer[] ids)
- throws Exception {
- if (!JMXNamespaces.getContainingNamespace(name).equals("")) {
- logger.debug("removeNotificationListener",
- "This connector server is not configured to support " +
- "forwarding of notification subscriptions to name spaces");
- throw new RuntimeOperationsException(
- new UnsupportedOperationException(
- "removeNotificationListener on name space MBeans. "));
- }
- forwarder.removeNotificationListener(name,ids);
- }
-
- public NotificationResult fetchNotifications(long csn, long timeout, int maxcount) {
- return forwarder.fetchNotifs(csn,timeout,maxcount);
- }
-
- public Integer addNotificationListener(ObjectName name,
- NotificationFilter filter)
- throws InstanceNotFoundException, IOException {
- if (!JMXNamespaces.getContainingNamespace(name).equals("")) {
- logger.debug("addNotificationListener",
- "This connector server is not configured to support " +
- "forwarding of notification subscriptions to name spaces");
- throw new RuntimeOperationsException(
- new UnsupportedOperationException(
- "addNotificationListener on name space MBeans. "));
- }
- return forwarder.addNotificationListener(name,filter);
- }
-
- public void terminate() {
- forwarder.terminate();
- }
- }
-
- /**
- * A SubscriptionManager that uses an EventClientDelegateMBean.
- **/
- private static class EventSubscriptionManager
- implements SubscriptionManager {
- private final MBeanServer mbeanServer;
- private final EventClientDelegateMBean delegate;
- private final NotificationAccessController notifAC;
- private final boolean checkNotificationEmission;
- private final String clientId;
- private final String connectionId;
- private volatile String mbeanServerName;
-
- EventSubscriptionManager(
- MBeanServer mbeanServer,
- EventClientDelegateMBean delegate,
- Map<String, ?> env,
- String clientId,
- String connectionId) {
- this.mbeanServer = mbeanServer;
- this.delegate = delegate;
- this.notifAC = EnvHelp.getNotificationAccessController(env);
- this.checkNotificationEmission =
- EnvHelp.computeBooleanFromString(
- env, "jmx.remote.x.check.notification.emission", false);
- this.clientId = clientId;
- this.connectionId = connectionId;
- }
-
- private String mbeanServerName() {
- if (mbeanServerName != null) return mbeanServerName;
- else return (mbeanServerName = getMBeanServerName(mbeanServer));
- }
-
- @SuppressWarnings("serial") // no serialVersionUID
- private class AccessControlFilter implements NotificationFilter {
- private final NotificationFilter wrapped;
- private final ObjectName name;
-
- AccessControlFilter(ObjectName name, NotificationFilter wrapped) {
- this.name = name;
- this.wrapped = wrapped;
- }
-
- public boolean isNotificationEnabled(Notification notification) {
- try {
- if (checkNotificationEmission) {
- ServerNotifForwarder.checkMBeanPermission(
- mbeanServerName(), mbeanServer, name,
- "addNotificationListener");
- }
- notifAC.fetchNotification(
- connectionId, name, notification, getSubject());
- return (wrapped == null) ? true :
- wrapped.isNotificationEnabled(notification);
- } catch (InstanceNotFoundException e) {
- return false;
- } catch (SecurityException e) {
- return false;
- }
- }
-
- }
-
- public Integer addNotificationListener(
- ObjectName name, NotificationFilter filter)
- throws InstanceNotFoundException, IOException {
- if (notifAC != null) {
- notifAC.addNotificationListener(connectionId, name, getSubject());
- filter = new AccessControlFilter(name, filter);
- }
- try {
- return delegate.addListener(clientId,name,filter);
- } catch (EventClientNotFoundException x) {
- throw new IOException("Unknown clientId: "+clientId,x);
- }
- }
-
- public void removeNotificationListener(ObjectName name, Integer id)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- if (notifAC != null)
- notifAC.removeNotificationListener(connectionId, name, getSubject());
- try {
- delegate.removeListenerOrSubscriber(clientId, id);
- } catch (EventClientNotFoundException x) {
- throw new IOException("Unknown clientId: "+clientId,x);
- }
- }
-
- public void removeNotificationListener(ObjectName name, Integer[] ids)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- if (notifAC != null)
- notifAC.removeNotificationListener(connectionId, name, getSubject());
- try {
- for (Integer id : ids)
- delegate.removeListenerOrSubscriber(clientId, id);
- } catch (EventClientNotFoundException x) {
- throw new IOException("Unknown clientId: "+clientId,x);
- }
- }
-
- public NotificationResult fetchNotifications(long csn, long timeout,
- int maxcount)
- throws IOException {
- try {
- // For some reason the delegate doesn't accept a negative
- // sequence number. However legacy clients will always call
- // fetchNotifications with a negative sequence number, when
- // they call it for the first time.
- // In that case, we will use 0 instead.
- //
- return delegate.fetchNotifications(
- clientId, Math.max(csn, 0), maxcount, timeout);
- } catch (EventClientNotFoundException x) {
- throw new IOException("Unknown clientId: "+clientId,x);
- }
- }
-
- public void terminate()
- throws IOException {
- try {
- delegate.removeClient(clientId);
- } catch (EventClientNotFoundException x) {
- throw new IOException("Unknown clientId: "+clientId,x);
- }
- }
-
- private static Subject getSubject() {
- return Subject.getSubject(AccessController.getContext());
- }
- }
-
- /**
- * Creates a SubscriptionManager that uses either the legacy notifications
- * mechanism (ServerNotifForwarder) or the new event service
- * (EventClientDelegateMBean) depending on which option was passed in
- * the connector's map.
- **/
- private SubscriptionManager createSubscriptionManager()
- throws IOException {
- if (EnvHelp.delegateToEventService(env) &&
- mbeanServer.isRegistered(EventClientDelegate.OBJECT_NAME)) {
- final EventClientDelegateMBean mbean =
- JMX.newMBeanProxy(mbeanServer,
- EventClientDelegate.OBJECT_NAME,
- EventClientDelegateMBean.class);
- String clientId;
- try {
- clientId =
- mbean.addClient(
- FetchingEventForwarder.class.getName(),
- new Object[] {EnvHelp.getNotifBufferSize(env)},
- new String[] {int.class.getName()});
- } catch (Exception e) {
- if (e instanceof IOException)
- throw (IOException) e;
- else
- throw new IOException(e);
- }
-
- // we're going to call remove client...
- try {
- mbean.lease(clientId, Long.MAX_VALUE);
- } catch (EventClientNotFoundException x) {
- throw new IOException("Unknown clientId: "+clientId,x);
- }
- return new EventSubscriptionManager(mbeanServer, mbean, env,
- clientId, connectionId);
- } else {
- final ServerNotifForwarder serverNotifForwarder =
- new ServerNotifForwarder(mbeanServer,
- env,
- rmiServer.getNotifBuffer(),
- connectionId);
- return new LegacySubscriptionManager(serverNotifForwarder);
- }
- }
-
- /**
- * Lazy creation of a SubscriptionManager.
- **/
- private synchronized SubscriptionManager getSubscriptionManager()
- throws IOException {
- // Lazily created when first use. Mainly when
- // addNotificationListener is first called.
-
- if (subscriptionManager == null) {
- subscriptionManager = createSubscriptionManager();
- }
- return subscriptionManager;
- }
-
- // calls SubscriptionManager.
- private void doRemoveListener(ObjectName name, Integer id)
- throws InstanceNotFoundException, ListenerNotFoundException,
- IOException {
- getSubscriptionManager().removeNotificationListener(name,id);
- }
-
- // calls SubscriptionManager.
- private void doRemoveListener(ObjectName name, Integer[] ids)
- throws Exception {
- getSubscriptionManager().removeNotificationListener(name,ids);
- }
-
- // calls SubscriptionManager.
- private NotificationResult doFetchNotifs(long csn, long timeout, int maxcount)
- throws IOException {
- return getSubscriptionManager().fetchNotifications(csn, timeout, maxcount);
- }
-
- // calls SubscriptionManager.
- private Integer doAddListener(ObjectName name, NotificationFilter filter)
- throws InstanceNotFoundException, IOException {
- return getSubscriptionManager().addNotificationListener(name,filter);
- }
-
-
- /**
* <p>Returns a string representation of this object. In general,
* the <code>toString</code> method returns a string that
* "textually represents" this object. The result should be a
@@ -1787,8 +1479,9 @@
return null;
case ADD_NOTIFICATION_LISTENERS:
- return doAddListener((ObjectName)params[0],
- (NotificationFilter)params[1]);
+ return getServerNotifFwd().addNotificationListener(
+ (ObjectName)params[0],
+ (NotificationFilter)params[1]);
case ADD_NOTIFICATION_LISTENER_OBJECTNAME:
mbeanServer.addNotificationListener((ObjectName)params[0],
@@ -1798,7 +1491,9 @@
return null;
case REMOVE_NOTIFICATION_LISTENER:
- doRemoveListener((ObjectName)params[0],(Integer[])params[1]);
+ getServerNotifFwd().removeNotificationListener(
+ (ObjectName)params[0],
+ (Integer[])params[1]);
return null;
case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME:
@@ -1909,15 +1604,6 @@
return e;
}
- private static String getMBeanServerName(final MBeanServer server) {
- final PrivilegedAction<String> action = new PrivilegedAction<String>() {
- public String run() {
- return Util.getMBeanServerSecurityName(server);
- }
- };
- return AccessController.doPrivileged(action);
- }
-
private static final Object[] NO_OBJECTS = new Object[0];
private static final String[] NO_STRINGS = new String[0];
@@ -2033,7 +1719,7 @@
// SERVER NOTIFICATION
//--------------------
- private SubscriptionManager subscriptionManager;
+ private ServerNotifForwarder serverNotifForwarder;
private Map<String, ?> env;
// TRACES & DEBUG
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,9 +25,6 @@
package javax.management.remote.rmi;
-import com.sun.jmx.event.DaemonThreadFactory;
-import com.sun.jmx.event.EventConnection;
-import com.sun.jmx.mbeanserver.PerThreadGroupPool;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
import com.sun.jmx.remote.internal.ClientListenerInfo;
@@ -72,11 +69,6 @@
import java.util.Properties;
import java.util.Set;
import java.util.WeakHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
@@ -84,7 +76,6 @@
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
-import javax.management.JMX;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
@@ -102,8 +93,6 @@
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ReflectionException;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegateMBean;
import javax.management.remote.JMXConnectionNotification;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
@@ -224,6 +213,7 @@
*
* @return a String representation of this object.
**/
+ @Override
public String toString() {
final StringBuilder b = new StringBuilder(this.getClass().getName());
b.append(":");
@@ -330,8 +320,6 @@
//
connectionId = getConnectionId();
- eventServiceEnabled = EnvHelp.eventServiceEnabled(env);
-
Notification connectedNotif =
new JMXConnectionNotification(JMXConnectionNotification.OPENED,
this,
@@ -341,8 +329,6 @@
null);
sendNotification(connectedNotif);
- // whether or not event service
-
if (tracing) logger.trace("connect",idstr + " done...");
} catch (IOException e) {
if (tracing)
@@ -400,38 +386,10 @@
}
rmbsc = new RemoteMBeanServerConnection(delegationSubject);
- if (eventServiceEnabled) {
- EventClientDelegateMBean ecd = JMX.newMBeanProxy(
- rmbsc, EventClientDelegateMBean.OBJECT_NAME,
- EventClientDelegateMBean.class);
- EventClient ec = new EventClient(ecd, null, defaultExecutor(), null,
- EventClient.DEFAULT_REQUESTED_LEASE_TIME);
-
- rmbsc = EventConnection.Factory.make(rmbsc, ec);
- ec.addEventClientListener(
- lostNotifListener, null, null);
- }
rmbscMap.put(delegationSubject, rmbsc);
return rmbsc;
}
- private static Executor defaultExecutor() {
- PerThreadGroupPool.Create<ThreadPoolExecutor> create =
- new PerThreadGroupPool.Create<ThreadPoolExecutor>() {
- public ThreadPoolExecutor createThreadPool(ThreadGroup group) {
- ThreadFactory daemonThreadFactory = new DaemonThreadFactory(
- "JMX RMIConnector listener dispatch %d");
- ThreadPoolExecutor executor = new ThreadPoolExecutor(
- 1, 10, 1, TimeUnit.SECONDS,
- new LinkedBlockingQueue<Runnable>(),
- daemonThreadFactory);
- executor.allowCoreThreadTimeOut(true);
- return executor;
- }
- };
- return listenerDispatchThreadPool.getThreadPoolExecutor(create);
- }
-
public void
addConnectionNotificationListener(NotificationListener listener,
NotificationFilter filter,
@@ -511,17 +469,6 @@
communicatorAdmin.terminate();
}
- // close all EventClient
- for (MBeanServerConnection rmbsc : rmbscMap.values()) {
- if (rmbsc instanceof EventConnection) {
- try {
- ((EventConnection)rmbsc).getEventClient().close();
- } catch (Exception e) {
- // OK
- }
- }
- }
-
if (rmiNotifClient != null) {
try {
rmiNotifClient.terminate();
@@ -660,8 +607,6 @@
private class RemoteMBeanServerConnection implements MBeanServerConnection {
private Subject delegationSubject;
- public EventClient eventClient = null;
-
public RemoteMBeanServerConnection() {
this(null);
}
@@ -1504,6 +1449,7 @@
super(period);
}
+ @Override
public void gotIOException(IOException ioe) throws IOException {
if (ioe instanceof NoSuchObjectException) {
// need to restart
@@ -1865,26 +1811,6 @@
terminated = false;
connectionBroadcaster = new NotificationBroadcasterSupport();
-
- lostNotifListener =
- new NotificationListener() {
- public void handleNotification(Notification n, Object hb) {
- if (n != null && EventClient.NOTIFS_LOST.equals(n.getType())) {
- Long lost = (Long)n.getUserData();
- final String msg =
- "May have lost up to " + lost +
- " notification" + (lost.longValue() == 1 ? "" : "s");
- sendNotification(new JMXConnectionNotification(
- JMXConnectionNotification.NOTIFS_LOST,
- RMIConnector.this,
- connectionId,
- clientNotifCounter++,
- msg,
- lost));
-
- }
- }
- };
}
//--------------------------------------------------------------------
@@ -2609,11 +2535,6 @@
private transient ClientCommunicatorAdmin communicatorAdmin;
- private boolean eventServiceEnabled;
-// private transient EventRelay eventRelay;
-
- private transient NotificationListener lostNotifListener;
-
/**
* A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to
* connect unconnected stubs.
@@ -2632,7 +2553,4 @@
private static String strings(final String[] strs) {
return objects(strs);
}
-
- private static final PerThreadGroupPool<ThreadPoolExecutor> listenerDispatchThreadPool =
- PerThreadGroupPool.make();
}
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Wed Oct 21 16:50:44 2009 +0100
@@ -230,8 +230,6 @@
this.address = url;
this.rmiServerImpl = rmiServerImpl;
-
- installStandardForwarders(this.attributes);
}
/**
@@ -383,7 +381,7 @@
try {
if (tracing) logger.trace("start", "setting default class loader");
defaultClassLoader = EnvHelp.resolveServerClassLoader(
- attributes, getSystemMBeanServerForwarder());
+ attributes, getMBeanServer());
} catch (InstanceNotFoundException infc) {
IllegalArgumentException x = new
IllegalArgumentException("ClassLoader not found: "+infc);
@@ -398,7 +396,7 @@
else
rmiServer = newServer();
- rmiServer.setMBeanServer(getSystemMBeanServerForwarder());
+ rmiServer.setMBeanServer(getMBeanServer());
rmiServer.setDefaultClassLoader(defaultClassLoader);
rmiServer.setRMIConnectorServer(this);
rmiServer.export();
@@ -592,34 +590,12 @@
return Collections.unmodifiableMap(map);
}
- /**
- * {@inheritDoc}
- * @return true, since this connector server does support a system chain
- * of forwarders.
- */
@Override
- public boolean supportsSystemMBeanServerForwarder() {
- return true;
- }
-
- /**
- * {@inheritDoc}
- * <P>The {@code RMIConnectorServer} class does support closing a specified
- * client connection.
- * @throws IllegalStateException if the server is not started or is closed.
- * @throws IllegalArgumentException if {@code connectionId} is null or is
- * not the id of any open connection.
- * @since 1.7
- */
- @Override
- public void closeConnection(String connectionId)
- throws IOException {
- if (isActive()) {
- rmiServerImpl.closeConnection(connectionId);
- } else {
- throw new IllegalStateException(
- "The server is not started or is closed.");
- }
+ public synchronized
+ void setMBeanServerForwarder(MBeanServerForwarder mbsf) {
+ super.setMBeanServerForwarder(mbsf);
+ if (rmiServerImpl != null)
+ rmiServerImpl.setMBeanServer(getMBeanServer());
}
/* We repeat the definitions of connection{Opened,Closed,Failed}
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -271,52 +271,6 @@
}
/**
- * Closes a client connection.
- * @param connectionId the id of the client connection to be closed.
- * @throws IllegalArgumentException if {@code connectionId} is null or is
- * not the id of any open connection.
- * @throws java.io.IOException if an I/O error appears when closing the
- * connection.
- *
- * @since 1.7
- */
- public void closeConnection(String connectionId)
- throws IOException {
- final boolean debug = logger.debugOn();
-
- if (debug) logger.trace("closeConnection","cconnectionId="+connectionId);
-
- if (connectionId == null)
- throw new IllegalArgumentException("Null connectionId.");
-
- RMIConnection client = null;
- synchronized (clientList) {
- dropDeadReferences();
- for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
- it.hasNext(); ) {
- client = it.next().get();
- if (client != null && connectionId.equals(client.getConnectionId())) {
- it.remove();
- break;
- }
- }
- }
-
- if (client == null) {
- throw new IllegalArgumentException("Unknown id: "+connectionId);
- }
-
- if (debug) logger.trace("closeConnection", "closing client connection.");
- closeClient(client);
-
- if (debug) logger.trace("closeConnection", "sending notif");
- connServer.connectionClosed(connectionId,
- "Client connection closed", null);
-
- if (debug) logger.trace("closeConnection","done");
- }
-
- /**
* <p>Creates a new client connection. This method is called by
* the public method {@link #newClient(Object)}.</p>
*
--- a/jdk/src/share/classes/sun/management/ClassLoadingImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/ClassLoadingImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -71,6 +71,6 @@
native static void setVerboseClass(boolean value);
public ObjectName getObjectName() {
- return ObjectName.valueOf(ManagementFactory.CLASS_LOADING_MXBEAN_NAME);
+ return Util.newObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME);
}
}
--- a/jdk/src/share/classes/sun/management/CompilationImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/CompilationImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -70,7 +70,7 @@
}
public ObjectName getObjectName() {
- return ObjectName.valueOf(ManagementFactory.COMPILATION_MXBEAN_NAME);
+ return Util.newObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
}
--- a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,9 +25,9 @@
package sun.management;
-import java.util.*;
import java.io.IOException;
-import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
import javax.management.ObjectName;
import com.sun.management.HotSpotDiagnosticMXBean;
@@ -117,6 +117,6 @@
}
public ObjectName getObjectName() {
- return ObjectName.valueOf("com.sun.management:type=HotSpotDiagnostic");
+ return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
}
}
--- a/jdk/src/share/classes/sun/management/HotspotInternal.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/HotspotInternal.java Wed Oct 21 16:50:44 2009 +0100
@@ -41,7 +41,7 @@
private final static String HOTSPOT_INTERNAL_MBEAN_NAME =
"sun.management:type=HotspotInternal";
- private static ObjectName objName = ObjectName.valueOf(HOTSPOT_INTERNAL_MBEAN_NAME);
+ private static ObjectName objName = Util.newObjectName(HOTSPOT_INTERNAL_MBEAN_NAME);
private MBeanServer server = null;
/**
--- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Wed Oct 21 16:50:44 2009 +0100
@@ -160,7 +160,7 @@
if (result == null) {
synchronized (this) {
if (objname == null) {
- result = ObjectName.valueOf(BUFFER_POOL_MXBEAN_NAME +
+ result = Util.newObjectName(BUFFER_POOL_MXBEAN_NAME +
",name=" + pool.getName());
objname = result;
}
@@ -257,7 +257,7 @@
*/
private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) {
try {
- final ObjectName objName = ObjectName.valueOf(mbeanName);
+ final ObjectName objName = Util.newObjectName(mbeanName);
// inner class requires these fields to be final
final MBeanServer mbs0 = mbs;
@@ -317,7 +317,7 @@
private static void unregisterMBean(MBeanServer mbs, String mbeanName) {
try {
- final ObjectName objName = ObjectName.valueOf(mbeanName);
+ final ObjectName objName = Util.newObjectName(mbeanName);
// inner class requires these fields to be final
final MBeanServer mbs0 = mbs;
--- a/jdk/src/share/classes/sun/management/MemoryImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/MemoryImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -34,15 +34,7 @@
import javax.management.ObjectName;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ListenerNotFoundException;
import javax.management.openmbean.CompositeData;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.ListIterator;
-import java.util.Collections;
/**
* Implementation class for the memory subsystem.
@@ -177,7 +169,7 @@
}
public ObjectName getObjectName() {
- return ObjectName.valueOf(ManagementFactory.MEMORY_MXBEAN_NAME);
+ return Util.newObjectName(ManagementFactory.MEMORY_MXBEAN_NAME);
}
}
--- a/jdk/src/share/classes/sun/management/OperatingSystemImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/OperatingSystemImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -74,7 +74,7 @@
}
}
public ObjectName getObjectName() {
- return ObjectName.valueOf(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
+ return Util.newObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
}
}
--- a/jdk/src/share/classes/sun/management/RuntimeImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/RuntimeImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -33,12 +33,6 @@
import java.util.Map;
import java.util.Set;
import java.util.Properties;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.OpenDataException;
import javax.management.ObjectName;
/**
@@ -149,7 +143,7 @@
}
public ObjectName getObjectName() {
- return ObjectName.valueOf(ManagementFactory.RUNTIME_MXBEAN_NAME);
+ return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
}
}
--- a/jdk/src/share/classes/sun/management/ThreadImpl.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/ThreadImpl.java Wed Oct 21 16:50:44 2009 +0100
@@ -29,10 +29,6 @@
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
-import java.lang.management.LockInfo;
-import java.lang.management.MonitorInfo;
-import java.util.Map;
-import java.util.HashMap;
import javax.management.ObjectName;
@@ -415,7 +411,7 @@
private static native void resetContentionTimes0(long tid);
public ObjectName getObjectName() {
- return ObjectName.valueOf(ManagementFactory.THREAD_MXBEAN_NAME);
+ return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME);
}
}
--- a/jdk/src/share/classes/sun/management/Util.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/src/share/classes/sun/management/Util.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,26 +25,34 @@
package sun.management;
-import java.lang.management.*;
+import java.lang.management.ManagementPermission;
import java.util.List;
-import java.security.Permission;
import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;
-import static java.lang.management.ManagementFactory.*;
-class Util {
+public class Util {
+ private Util() {} // there are no instances of this class
+
static RuntimeException newException(Exception e) {
throw new RuntimeException(e);
}
private static final String[] EMPTY_STRING_ARRAY = new String[0];
static String[] toStringArray(List<String> list) {
- return (String[]) list.toArray(EMPTY_STRING_ARRAY);
+ return list.toArray(EMPTY_STRING_ARRAY);
}
public static ObjectName newObjectName(String domainAndType, String name) {
- return ObjectName.valueOf(domainAndType + ",name=" + name);
+ return newObjectName(domainAndType + ",name=" + name);
+ }
+
+ public static ObjectName newObjectName(String name) {
+ try {
+ return ObjectName.getInstance(name);
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException(e);
+ }
}
private static ManagementPermission monitorPermission =
--- a/jdk/test/javax/management/Introspector/AnnotatedMBeanTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,337 +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.
- *
- * 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.
- */
-
-/*
- * @test %M% %I%
- * @bug 6323980
- * @summary Test MBeans defined with @MBean
- * @author Eamonn McManus
- * @run main/othervm -ea AnnotatedMBeanTest
- */
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.Descriptor;
-import javax.management.DescriptorKey;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MXBean;
-import javax.management.MalformedObjectNameException;
-import javax.management.ManagedAttribute;
-import javax.management.ManagedOperation;
-import javax.management.MBean;
-import javax.management.ObjectName;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeType;
-
-public class AnnotatedMBeanTest {
- private static MBeanServer mbs;
- private static final ObjectName objectName;
- static {
- try {
- objectName = new ObjectName("test:type=Test");
- } catch (MalformedObjectNameException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static void main(String[] args) throws Exception {
- if (!AnnotatedMBeanTest.class.desiredAssertionStatus())
- throw new Exception("Test must be run with -ea");
-
- File policyFile = File.createTempFile("jmxperms", ".policy");
- policyFile.deleteOnExit();
- PrintWriter pw = new PrintWriter(policyFile);
- pw.println("grant {");
- pw.println(" permission javax.management.MBeanPermission \"*\", \"*\";");
- pw.println(" permission javax.management.MBeanServerPermission \"*\";");
- pw.println(" permission javax.management.MBeanTrustPermission \"*\";");
- pw.println("};");
- pw.close();
-
- System.setProperty("java.security.policy", policyFile.getAbsolutePath());
- System.setSecurityManager(new SecurityManager());
-
- String failure = null;
-
- for (Method m : AnnotatedMBeanTest.class.getDeclaredMethods()) {
- if (Modifier.isStatic(m.getModifiers()) &&
- m.getName().startsWith("test") &&
- m.getParameterTypes().length == 0) {
- mbs = MBeanServerFactory.newMBeanServer();
- try {
- m.invoke(null);
- System.out.println(m.getName() + " OK");
- } catch (InvocationTargetException ite) {
- System.out.println(m.getName() + " got exception:");
- Throwable t = ite.getCause();
- t.printStackTrace(System.out);
- failure = m.getName() + ": " + t.toString();
- }
- }
- }
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- public static class Stats {
- private final int used;
- private final int size;
- private final boolean interesting;
-
- public Stats(int used, int size, boolean interesting) {
- this.used = used;
- this.size = size;
- this.interesting = interesting;
- }
-
- public int getUsed() {
- return used;
- }
-
- public int getSize() {
- return size;
- }
-
- public boolean isInteresting() {
- return interesting;
- }
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- public static @interface Units {
- @DescriptorKey("units")
- String value();
- }
-
- @MBean
- public static class Cache {
- private int used = 23;
- private int size = 99;
-
- @ManagedAttribute
- @Units("bytes")
- public int getUsed() {
- return used;
- }
-
- @ManagedAttribute
- public int getSize() {
- return size;
- }
-
- @ManagedAttribute
- public void setSize(int x) {
- this.size = x;
- }
-
- @ManagedAttribute
- public boolean isInteresting() {
- return false;
- }
-
- @ManagedAttribute
- public Stats getStats() {
- return new Stats(used, size, false);
- }
-
- @ManagedOperation
- public int dropOldest(int n) {
- return 55;
- }
-
- private void irrelevantMethod() {}
- private int getIrrelevant() {return 0;}
- public int getIrrelevant2() {return 0;}
-
- public int otherIrrelevantMethod() {return 5;}
- }
-
- public static class SubCache extends Cache {
- // SubCache does not have the @MBean annotation
- // but its parent does. It doesn't add any @ManagedAttribute or
- // @ManagedOperation methods, so its management interface
- // should be the same.
- private void irrelevantMethod2() {}
- public int otherIrrelevantMethod3() {return 0;}
-
- public int getX() {return 0;}
- public void setX(int x) {}
- }
-
- @MXBean
- public static class CacheMX {
- private int used = 23;
- private int size = 99;
-
- @ManagedAttribute
- @Units("bytes")
- public int getUsed() {
- return used;
- }
-
- @ManagedAttribute
- public int getSize() {
- return size;
- }
-
- @ManagedAttribute
- public void setSize(int x) {
- this.size = x;
- }
-
- @ManagedAttribute
- public boolean isInteresting() {
- return false;
- }
-
- @ManagedAttribute
- public Stats getStats() {
- return new Stats(used, size, false);
- }
-
- @ManagedOperation
- public int dropOldest(int n) {
- return 55;
- }
-
- private void irrelevantMethod() {}
- private int getIrrelevant() {return 0;}
- public int getIrrelevant2() {return 0;}
-
- public int otherIrrelevantMethod() {return 5;}
- }
-
- public static class SubCacheMX extends CacheMX {
- private void irrelevantMethod2() {}
- public int otherIrrelevantMethod3() {return 0;}
-
- public int getX() {return 0;}
- public void setX(int x) {}
- }
-
- private static void testSimpleManagedResource() throws Exception {
- testResource(new Cache(), false);
- }
-
- private static void testSubclassManagedResource() throws Exception {
- testResource(new SubCache(), false);
- }
-
- private static void testMXBeanResource() throws Exception {
- testResource(new CacheMX(), true);
- }
-
- private static void testSubclassMXBeanResource() throws Exception {
- testResource(new SubCacheMX(), true);
- }
-
- private static void testResource(Object resource, boolean mx) throws Exception {
- mbs.registerMBean(resource, objectName);
-
- MBeanInfo mbi = mbs.getMBeanInfo(objectName);
- assert mbi.getDescriptor().getFieldValue("mxbean").equals(Boolean.toString(mx));
-
- MBeanAttributeInfo[] mbais = mbi.getAttributes();
-
- assert mbais.length == 4: mbais.length;
-
- for (MBeanAttributeInfo mbai : mbais) {
- String name = mbai.getName();
- if (name.equals("Used")) {
- assert mbai.isReadable();
- assert !mbai.isWritable();
- assert !mbai.isIs();
- assert mbai.getType().equals("int");
- assert "bytes".equals(mbai.getDescriptor().getFieldValue("units"));
- } else if (name.equals("Size")) {
- assert mbai.isReadable();
- assert mbai.isWritable();
- assert !mbai.isIs();
- assert mbai.getType().equals("int");
- } else if (name.equals("Interesting")) {
- assert mbai.isReadable();
- assert !mbai.isWritable();
- assert mbai.isIs();
- assert mbai.getType().equals("boolean");
- } else if (name.equals("Stats")) {
- assert mbai.isReadable();
- assert !mbai.isWritable();
- assert !mbai.isIs();
- Descriptor d = mbai.getDescriptor();
- if (mx) {
- assert mbai.getType().equals(CompositeData.class.getName());
- assert d.getFieldValue("originalType").equals(Stats.class.getName());
- CompositeType ct = (CompositeType) d.getFieldValue("openType");
- Set<String> names = new HashSet<String>(
- Arrays.asList("used", "size", "interesting"));
- assert ct.keySet().equals(names) : ct.keySet();
- } else {
- assert mbai.getType().equals(Stats.class.getName());
- }
- } else
- assert false : name;
- }
-
- MBeanOperationInfo[] mbois = mbi.getOperations();
-
- assert mbois.length == 1: mbois.length;
-
- MBeanOperationInfo mboi = mbois[0];
- assert mboi.getName().equals("dropOldest");
- assert mboi.getReturnType().equals("int");
- MBeanParameterInfo[] mbpis = mboi.getSignature();
- assert mbpis.length == 1: mbpis.length;
- assert mbpis[0].getType().equals("int");
-
- assert mbs.getAttribute(objectName, "Used").equals(23);
-
- assert mbs.getAttribute(objectName, "Size").equals(99);
- mbs.setAttribute(objectName, new Attribute("Size", 55));
- assert mbs.getAttribute(objectName, "Size").equals(55);
-
- assert mbs.getAttribute(objectName, "Interesting").equals(false);
-
- Object stats = mbs.getAttribute(objectName, "Stats");
- assert (mx ? CompositeData.class : Stats.class).isInstance(stats) : stats.getClass();
-
- int ret = (Integer) mbs.invoke(
- objectName, "dropOldest", new Object[] {66}, new String[] {"int"});
- assert ret == 55;
- }
-}
--- a/jdk/test/javax/management/Introspector/AnnotatedNotificationInfoTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,442 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6323980 6772779
- * @summary Test @NotificationInfo annotation
- * @author Eamonn McManus
- * @run main/othervm -ea AnnotatedNotificationInfoTest
- */
-
-import java.io.Serializable;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import javax.annotation.Resource;
-import javax.management.AttributeChangeNotification;
-import javax.management.Description;
-import javax.management.Descriptor;
-import javax.management.ImmutableDescriptor;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBean;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MXBean;
-import javax.management.Notification;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationInfo;
-import javax.management.NotificationInfos;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.SendNotification;
-
-public class AnnotatedNotificationInfoTest {
-
- static final Descriptor expectedDescriptor = new ImmutableDescriptor(
- "foo=bar", "descriptionResourceBundleBaseName=bundle",
- "descriptionResourceKey=key");
- static final MBeanNotificationInfo expected = new MBeanNotificationInfo(
- new String[] {"foo", "bar"},
- AttributeChangeNotification.class.getName(),
- "description",
- expectedDescriptor);
-
- // Data for the first kind of test. This tests that MBeanNotificationInfo
- // is correctly derived from @NotificationInfo.
- // Every static field called mbean* is expected to be an MBean
- // with a single MBeanNotificationInfo that has the same value
- // in each case.
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static interface Intf1MBean {}
-
- public static class Intf1
- extends NotificationBroadcasterSupport implements Intf1MBean {}
-
- private static Object mbeanIntf1 = new Intf1();
-
- @NotificationInfos(
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"}))
- public static interface Intf2MBean {}
-
- public static class Intf2
- extends NotificationBroadcasterSupport implements Intf2MBean {}
-
- private static Object mbeanIntf2 = new Intf2();
-
- @NotificationInfos({})
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static interface Intf3MBean {}
-
- public static class Intf3
- extends NotificationBroadcasterSupport implements Intf3MBean {}
-
- private static Object mbeanIntf3 = new Intf3();
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static interface ParentIntf {}
-
- public static interface Intf4MBean extends Serializable, ParentIntf, Cloneable {}
-
- public static class Intf4
- extends NotificationBroadcasterSupport implements Intf4MBean {}
-
- private static Object mbeanIntf4 = new Intf4();
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static interface Intf5MXBean {}
-
- public static class Intf5Impl
- extends NotificationBroadcasterSupport implements Intf5MXBean {}
-
- private static Object mbeanIntf5 = new Intf5Impl();
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static interface Intf6MBean {}
-
- public static class Intf6 implements Intf6MBean {
- @Resource
- private volatile SendNotification send;
- }
-
- private static Object mbeanIntf6 = new Intf6();
-
- public static interface Impl1MBean {}
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static class Impl1
- extends NotificationBroadcasterSupport implements Impl1MBean {}
-
- private static Object mbeanImpl1 = new Impl1();
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static class ParentImpl extends NotificationBroadcasterSupport {}
-
- public static interface Impl2MBean {}
-
- public static class Impl2 extends ParentImpl implements Impl2MBean {}
-
- private static Object mbeanImpl2 = new Impl2();
-
- public static interface Impl3MXBean {}
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static class Impl3
- extends NotificationBroadcasterSupport implements Impl3MXBean {}
-
- private static Object mbeanImpl3 = new Impl3();
-
- public static class Impl4 extends ParentImpl implements Impl3MXBean {}
-
- private static Object mbeanImpl4 = new Impl4();
-
- @MBean
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static class MBean1 extends NotificationBroadcasterSupport {}
-
- private static Object mbeanMBean1 = new MBean1();
-
- @MBean
- public static class MBean2 extends ParentImpl {}
-
- private static Object mbeanMBean2 = new MBean2();
-
- @MBean
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static class MBean3 {
- @Resource
- private volatile SendNotification send;
- }
-
- private static Object mbeanMBean3 = new MBean3();
-
- @MXBean
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static class MXBean1 extends NotificationBroadcasterSupport {}
-
- private static Object mbeanMXBean1 = new MXBean1();
-
- @MXBean
- public static class MXBean2 extends ParentImpl {}
-
- private static Object mbeanMXBean2 = new MXBean2();
-
- // Test that @NotificationInfo and @NotificationInfos are ignored if
- // the MBean returns a non-empty MBeanNotificationInfo[] from its
- // NotificationBroadcaster.getNotifications() implementation.
-
- @NotificationInfo(types={"blim", "blam"})
- public static interface Explicit1MBean {}
-
- public static class Explicit1
- extends NotificationBroadcasterSupport implements Explicit1MBean {
- public Explicit1() {
- super(expected);
- }
- }
-
- private static Object mbeanExplicit1 = new Explicit1();
-
- @NotificationInfos(
- {
- @NotificationInfo(types="blim"), @NotificationInfo(types="blam")
- }
- )
- public static interface Explicit2MXBean {}
-
- public static class Explicit2
- implements NotificationBroadcaster, Explicit2MXBean {
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback) {}
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {}
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return new MBeanNotificationInfo[] {expected};
- }
- }
-
- // Data for the second kind of test. This tests that @NotificationInfo is
- // ignored if the MBean is not a notification source. Every static
- // field called ignoredMBean* is expected to be an MBean on which
- // isInstanceOf(NotificationBroadcaster.class.getName() is false,
- // addNotificationListener produces an exception, and the
- // MBeanNotificationInfo array is empty.
- @NotificationInfo(types={"com.example.notifs.create",
- "com.example.notifs.destroy"})
- public static interface CacheMBean {
- public int getCachedNum();
- }
-
- public static class Cache implements CacheMBean {
- public int getCachedNum() {
- return 0;
- }
- }
-
- private static Object ignoredMBean1 = new Cache();
-
- @NotificationInfos(
- @NotificationInfo(types={"foo", "bar"})
- )
- public static interface Cache2MBean {
- public int getCachedNum();
- }
-
- public static class Cache2 implements Cache2MBean {
- public int getCachedNum() {
- return 0;
- }
- }
-
- private static Object ignoredMBean2 = new Cache2();
-
- private static final NotificationListener nullListener =
- new NotificationListener() {
- public void handleNotification(
- Notification notification, Object handback) {}
- };
-
- // Test that inheriting inconsistent @NotificationInfo annotations is
- // an error, but not if they are overridden by a non-empty getNotifications()
-
- @NotificationInfo(types={"blim"})
- public static interface Inconsistent1 {}
-
- @NotificationInfo(types={"blam"})
- public static interface Inconsistent2 {}
-
- public static interface InconsistentMBean extends Inconsistent1, Inconsistent2 {}
-
- public static class Inconsistent
- extends NotificationBroadcasterSupport implements InconsistentMBean {}
-
- public static class Consistent
- extends Inconsistent implements NotificationBroadcaster {
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback) {}
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {}
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return new MBeanNotificationInfo[] {expected};
- }
- }
-
- private static Object mbeanConsistent = new Consistent();
-
- @NotificationInfo(
- types = {"foo", "bar"},
- notificationClass = AttributeChangeNotification.class,
- description = @Description(
- value = "description",
- bundleBaseName = "bundle",
- key = "key"),
- descriptorFields = {"foo=bar"})
- public static interface Consistent2MBean extends Inconsistent1, Inconsistent2 {}
-
- public static class Consistent2
- extends NotificationBroadcasterSupport implements Consistent2MBean {}
-
- private static Object mbeanConsistent2 = new Consistent2();
-
- public static void main(String[] args) throws Exception {
- if (!AnnotatedNotificationInfoTest.class.desiredAssertionStatus())
- throw new Exception("Test must be run with -ea");
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName on = new ObjectName("a:b=c");
-
- System.out.println("Testing MBeans...");
- for (Field mbeanField :
- AnnotatedNotificationInfoTest.class.getDeclaredFields()) {
- boolean notifier;
- if (mbeanField.getName().startsWith("mbean"))
- notifier = true;
- else if (mbeanField.getName().startsWith("ignoredMBean"))
- notifier = false;
- else
- continue;
- System.out.println("..." + mbeanField.getName());
- Object mbean = mbeanField.get(null);
- mbs.registerMBean(mbean, on);
- MBeanInfo mbi = mbs.getMBeanInfo(on);
- MBeanNotificationInfo[] mbnis = mbi.getNotifications();
- if (notifier) {
- assert mbnis.length == 1 : mbnis.length;
- assert mbnis[0].equals(expected) : mbnis[0];
- } else {
- assert mbnis.length == 0 : mbnis.length;
- assert !mbs.isInstanceOf(on, NotificationBroadcaster.class.getName());
- try {
- mbs.addNotificationListener(on, nullListener, null, null);
- assert false : "addNotificationListener works";
- } catch (Exception e) {
- // OK: addNL correctly refused
- }
- }
- mbs.unregisterMBean(on);
- }
-
- // Test that inconsistent @NotificationInfo annotations produce an
- // error.
- try {
- mbs.registerMBean(new Inconsistent(), on);
- System.out.println(mbs.getMBeanInfo(on));
- assert false : "Inconsistent @NotificationInfo not detected";
- } catch (Exception e) {
- System.out.println(
- "Inconsistent @NotificationInfo correctly produced " + e);
- }
- }
-}
--- a/jdk/test/javax/management/Introspector/AnnotationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/Introspector/AnnotationTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -32,15 +32,22 @@
* @run main AnnotationTest
*/
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
-import javax.management.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.Descriptor;
+import javax.management.DescriptorRead;
+import javax.management.DescriptorKey;
+import javax.management.ImmutableDescriptor;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
/*
This test checks that annotations produce Descriptor entries as
- specified in javax.management.DescriptorKey and javax.management.DescriptorField.
- It does the following:
+ specified in javax.management.DescriptorKey. It does two things:
- An annotation consisting of an int and a String, each with an
appropriate @DescriptorKey annotation, is placed on every program
@@ -62,10 +69,6 @@
The test checks that in each case the corresponding Descriptor
appears in the appropriate place inside the MBean's MBeanInfo.
- - A @DescriptorFields annotation defining two fields is placed in the
- same places and again the test checks that the two fields appear
- in the corresponding MBean*Info objects.
-
- An annotation consisting of enough other types to ensure coverage
is placed on a getter. The test checks that the generated
MBeanAttributeInfo contains the corresponding Descriptor. The tested
@@ -111,12 +114,11 @@
boolean[] booleanArrayValue();
}
- /* We use the annotations @Pair(x = 3, y = "foo")
- and @DescriptorFields({"foo=bar", "baz="}) everywhere, and this is
- the Descriptor that they should produce: */
+ /* We use the annotation @Pair(x = 3, y = "foo") everywhere, and this is
+ the Descriptor that it should produce: */
private static Descriptor expectedDescriptor =
- new ImmutableDescriptor(new String[] {"x", "y", "foo", "baz"},
- new Object[] {3, "foo", "bar", ""});
+ new ImmutableDescriptor(new String[] {"x", "y"},
+ new Object[] {3, "foo"});
private static Descriptor expectedFullDescriptor =
new ImmutableDescriptor(new String[] {
@@ -136,10 +138,8 @@
});
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
public static interface ThingMBean {
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
@Full(classValue=Full.class,
enumValue=RetentionPolicy.RUNTIME,
booleanValue=false,
@@ -151,47 +151,32 @@
int getReadOnly();
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
void setWriteOnly(int x);
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
int getReadWrite1();
void setReadWrite1(int x);
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
int getReadWrite2();
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
void setReadWrite2(int x);
int getReadWrite3();
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
void setReadWrite3(int x);
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- int operation(@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- int p1,
- @Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- int p2);
+ int operation(@Pair(x = 3, y = "foo") int p1,
+ @Pair(x = 3, y = "foo") int p2);
}
public static class Thing implements ThingMBean {
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
public Thing() {}
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- public Thing(
- @Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- int p1) {}
+ public Thing(@Pair(x = 3, y = "foo") int p1) {}
public int getReadOnly() {return 0;}
@@ -210,20 +195,14 @@
}
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
public static interface ThingMXBean extends ThingMBean {}
public static class ThingImpl implements ThingMXBean {
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
public ThingImpl() {}
@Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- public ThingImpl(
- @Pair(x = 3, y = "foo")
- @DescriptorFields({"foo=bar", "baz="})
- int p1) {}
+ public ThingImpl(@Pair(x = 3, y = "foo") int p1) {}
public int getReadOnly() {return 0;}
@@ -241,79 +220,6 @@
public int operation(int p1, int p2) {return 0;}
}
- @Retention(RetentionPolicy.RUNTIME)
- public static @interface DefaultTest {
- @DescriptorKey(value = "string1", omitIfDefault = true)
- String string1() default "";
- @DescriptorKey(value = "string2", omitIfDefault = true)
- String string2() default "tiddly pom";
- @DescriptorKey(value = "int", omitIfDefault = true)
- int intx() default 23;
- @DescriptorKey(value = "intarray1", omitIfDefault = true)
- int[] intArray1() default {};
- @DescriptorKey(value = "intarray2", omitIfDefault = true)
- int[] intArray2() default {1, 2};
- @DescriptorKey(value = "stringarray1", omitIfDefault = true)
- String[] stringArray1() default {};
- @DescriptorKey(value = "stringarray2", omitIfDefault = true)
- String[] stringArray2() default {"foo", "bar"};
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- public static @interface Expect {
- String[] value() default {};
- }
-
- public static interface DefaultMBean {
- @DefaultTest
- @Expect()
- public void a();
-
- @DefaultTest(string1="")
- @Expect()
- public void b();
-
- @DefaultTest(string1="nondefault")
- @Expect("string1=nondefault")
- public void c();
-
- @DefaultTest(string2="tiddly pom")
- @Expect()
- public void d();
-
- @DefaultTest(intx=23)
- @Expect()
- public void e();
-
- @DefaultTest(intx=34)
- @Expect("int=34")
- public void f();
-
- @DefaultTest(intArray1={})
- @Expect()
- public void g();
-
- @DefaultTest(intArray1={2,3})
- @Expect("intarray1=[2, 3]")
- public void h();
-
- @DefaultTest(intArray2={})
- @Expect("intarray2=[]")
- public void i();
-
- @DefaultTest(stringArray1={})
- @Expect()
- public void j();
-
- @DefaultTest(stringArray1={"foo"})
- @Expect("stringarray1=[foo]")
- public void k();
-
- @DefaultTest(stringArray2={})
- @Expect("stringarray2=[]")
- public void l();
- }
-
public static void main(String[] args) throws Exception {
System.out.println("Testing that annotations are correctly " +
"reflected in Descriptor entries");
@@ -336,43 +242,6 @@
}
check(mbs, on);
- System.out.println();
- System.out.println("Testing that omitIfDefault works");
- DefaultMBean defaultImpl = (DefaultMBean) Proxy.newProxyInstance(
- DefaultMBean.class.getClassLoader(),
- new Class<?>[] {DefaultMBean.class},
- new InvocationHandler(){
- public Object invoke(Object proxy, Method method, Object[] args) {
- return null;
- }
- });
- DynamicMBean mbean = new StandardMBean(defaultImpl, DefaultMBean.class);
- MBeanOperationInfo[] ops = mbean.getMBeanInfo().getOperations();
- for (MBeanOperationInfo op : ops) {
- String name = op.getName();
- Expect expect =
- DefaultMBean.class.getMethod(name).getAnnotation(Expect.class);
- Descriptor opd = op.getDescriptor();
- List<String> fields = new ArrayList<String>();
- for (String fieldName : opd.getFieldNames()) {
- Object value = opd.getFieldValue(fieldName);
- String s = Arrays.deepToString(new Object[] {value});
- s = s.substring(1, s.length() - 1);
- fields.add(fieldName + "=" + s);
- }
- Descriptor opds = new ImmutableDescriptor(fields.toArray(new String[0]));
- Descriptor expd = new ImmutableDescriptor(expect.value());
- if (opds.equals(expd))
- System.out.println("OK: op " + name + ": " + opds);
- else {
- String failure = "Bad descriptor for op " + name + ": " +
- "expected " + expd + ", got " + opds;
- System.out.println("NOT OK: " + failure);
- failed = failure;
- }
- }
- System.out.println();
-
if (failed == null)
System.out.println("Test passed");
else
--- a/jdk/test/javax/management/Introspector/ExceptionsDescriptorTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +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.
- *
- * 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.
- */
-
-/*
- * @test %M% %I%
- * @bug 6250014
- * @summary Test that Exceptions are added to the MbeanInfo
- * @author Jean-Francois Denise
- * @run main/othervm ExceptionsDescriptorTest
- */
-import java.lang.management.ManagementFactory;
-import java.util.HashSet;
-import java.util.Set;
-import javax.management.Descriptor;
-import javax.management.JMX;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanConstructorInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.ObjectName;
-
-public class ExceptionsDescriptorTest {
-
- private static final ObjectName OBJECT_NAME = ObjectName.valueOf(":type=Foo");
- final static String EXCEPTION_NAME = Exception.class.getName();
- final static String ILLEGAL_ARGUMENT_EXCEPTION_NAME =
- IllegalArgumentException.class.getName();
- final static Set<String> ONE_EXCEPTION = new HashSet<String>();
- final static Set<String> TWO_EXCEPTION = new HashSet<String>();
- static {
- ONE_EXCEPTION.add(EXCEPTION_NAME);
- TWO_EXCEPTION.add(EXCEPTION_NAME);
- TWO_EXCEPTION.add(ILLEGAL_ARGUMENT_EXCEPTION_NAME);
- }
- public interface TestMBean {
-
- public void doIt();
-
- public void doIt(String str) throws Exception;
-
- public void doIt(String str, boolean b) throws Exception,
- IllegalArgumentException;
-
- public String getThat();
-
- public void setThat(String that);
-
- public String getThe() throws Exception;
-
- public void setThe(String the);
-
- public String getThese();
-
- public void setThese(String the) throws Exception;
-
- public String getIt() throws Exception;
-
- public void setIt(String str) throws Exception;
-
- public String getThis() throws Exception, IllegalArgumentException;
-
- public void setThose(String str) throws Exception,
- IllegalArgumentException;
- }
-
- public static class Test implements TestMBean {
-
- public Test() {
- }
-
- public Test(int i) throws Exception {
- }
-
- public Test(int i, int j) throws Exception, IllegalArgumentException {
- }
-
- public void doIt() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void doIt(String str) throws Exception {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void doIt(String str, boolean b) throws Exception, IllegalArgumentException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public String getThat() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setThat(String that) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public String getThe() throws Exception {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setThe(String the) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public String getThese() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setThese(String the) throws Exception {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public String getIt() throws Exception {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setIt(String str) throws Exception {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public String getThis() throws Exception, IllegalArgumentException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setThose(String str) throws Exception, IllegalArgumentException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
- }
-
- private static void check(Descriptor d,
- Set<String> exceptionsExpectedValue,
- boolean exceptionsExpected,
- Set<String> setExceptionsExpectedValue,
- boolean setExceptionsExpected) throws Exception {
- String[] exceptionsValues = (String[]) d.getFieldValue(JMX.EXCEPTIONS_FIELD);
- String[] setExceptionsValues = (String[]) d.getFieldValue(JMX.SET_EXCEPTIONS_FIELD);
-
- if (exceptionsExpected && exceptionsValues == null) {
- throw new Exception("exceptions is expected but null value");
- }
- if (!exceptionsExpected && exceptionsValues != null) {
- throw new Exception("exceptions is not expected but non null value");
- }
- if (setExceptionsExpected && setExceptionsValues == null) {
- throw new Exception("setExceptions is expected but null value");
- }
- if (!setExceptionsExpected && setExceptionsValues != null) {
- throw new Exception("setExceptions is not expected but non null value");
- }
-
- if (exceptionsExpected) {
- checkValues(exceptionsExpectedValue, exceptionsValues);
- }
- if (setExceptionsExpected) {
- checkValues(setExceptionsExpectedValue, setExceptionsValues);
- }
- }
-
- private static void checkValues(Set<String> expectedValuesSet,
- String[] realValues) throws Exception {
-
- Set<String> realValuesSet = new HashSet<String>();
- for (String ex : realValues) {
- realValuesSet.add(ex);
- }
- if (!realValuesSet.equals(expectedValuesSet)) {
- throw new Exception("Invalid content for exceptions. Was expecting " +
- expectedValuesSet + ". Found " + realValuesSet);
- }
- }
-
- public static void main(String[] args) throws Exception {
- Test t = new Test();
- ManagementFactory.getPlatformMBeanServer().registerMBean(t, OBJECT_NAME);
- MBeanInfo info = ManagementFactory.getPlatformMBeanServer().
- getMBeanInfo(OBJECT_NAME);
- //Constructors
- for (MBeanConstructorInfo ctr : info.getConstructors()) {
- if (ctr.getSignature().length == 0) {
- check(ctr.getDescriptor(), null, false, null, false);
- }
- if (ctr.getSignature().length == 1) {
- check(ctr.getDescriptor(), ONE_EXCEPTION, true, null, false);
- }
- if (ctr.getSignature().length == 2) {
- check(ctr.getDescriptor(),TWO_EXCEPTION,true, null, false);
- }
- }
- //Attributes
- for (MBeanAttributeInfo attr : info.getAttributes()) {
- if (attr.getName().equals("That")) {
- check(attr.getDescriptor(), null, false, null, false);
- }
- if (attr.getName().equals("The")) {
- check(attr.getDescriptor(), ONE_EXCEPTION,true,null, false);
- }
- if (attr.getName().equals("These")) {
- check(attr.getDescriptor(), null, false, ONE_EXCEPTION,true);
- }
- if (attr.getName().equals("It")) {
- check(attr.getDescriptor(), ONE_EXCEPTION,true,ONE_EXCEPTION,
- true);
- }
- if (attr.getName().equals("This")) {
- check(attr.getDescriptor(), TWO_EXCEPTION,true,null,false);
- }
- if (attr.getName().equals("Those")) {
- check(attr.getDescriptor(), null,false,TWO_EXCEPTION,true);
- }
- }
- //Operations
- for (MBeanOperationInfo oper : info.getOperations()) {
- if (oper.getSignature().length == 0) {
- check(oper.getDescriptor(), null, false, null, false);
- }
- if (oper.getSignature().length == 1) {
- check(oper.getDescriptor(), ONE_EXCEPTION, true, null, false);
- }
- if (oper.getSignature().length == 2) {
- check(oper.getDescriptor(), TWO_EXCEPTION,true, null, false);
- }
- }
- System.out.println("Test passed");
- }
-}
--- a/jdk/test/javax/management/Introspector/MBeanDescriptionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,830 +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.
- *
- * 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.
- */
-
-/*
- * @test %M% %I%
- * @bug 6323980
- * @summary Test @Description
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import javax.management.Description;
-import javax.management.IntrospectionException;
-import javax.management.MBean;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanConstructorInfo;
-import javax.management.MBeanFeatureInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MBeanServer;
-import javax.management.MXBean;
-import javax.management.ManagedAttribute;
-import javax.management.ManagedOperation;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-
-public class MBeanDescriptionTest {
- private static String failure;
- private static final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- private static final ObjectName name;
- static {
- try {
- name = new ObjectName("a:b=c");
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public static interface Interface {
- @Description("A description")
- public String getA();
-
- @Description("B description")
- public int getB();
- public void setB(int x);
-
- public boolean isC();
- @Description("C description")
- public void setC(boolean x);
-
- @Description("D description")
- public void setD(float x);
-
- @Description("H description")
- public int getH();
- @Description("H description")
- public void setH(int x);
-
- public String getE();
-
- public int getF();
- public void setF(int x);
-
- public void setG(boolean x);
-
- @Description("opA description")
- public int opA(
- @Description("p1 description")
- int p1,
- @Description("p2 description")
- int p2);
-
- public void opB(float x);
- }
-
- @Description("MBean description")
- public static interface TestMBean extends Interface {}
-
- public static class Test implements TestMBean {
- @Description("0-arg constructor description")
- public Test() {}
-
- public Test(String why) {}
-
- @Description("2-arg constructor description")
- public Test(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {
- }
-
- public String getA() {
- return null;
- }
-
- public int getB() {
- return 0;
- }
-
- public void setB(int x) {
- }
-
- public boolean isC() {
- return false;
- }
-
- public void setC(boolean x) {
- }
-
- public void setD(float x) {
- }
-
- public String getE() {
- return null;
- }
-
- public int getF() {
- return 0;
- }
-
- public void setF(int x) {
- }
-
- public void setG(boolean x) {
- }
-
- public int getH() {
- return 0;
- }
-
- public void setH(int x) {
- }
-
- public int opA(int p1, int p2) {
- return 0;
- }
-
- public void opB(float x) {
- }
- }
-
- public static class TestSub extends Test {
- @Description("0-arg constructor description")
- public TestSub() {}
-
- public TestSub(String why) {}
-
- @Description("2-arg constructor description")
- public TestSub(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {
- }
- }
-
- public static class StandardSub extends StandardMBean implements TestMBean {
- @Description("0-arg constructor description")
- public StandardSub() {
- super(TestMBean.class, false);
- }
-
- public StandardSub(String why) {
- super(TestMBean.class, false);
- }
-
- @Description("2-arg constructor description")
- public StandardSub(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {
- super(TestMBean.class, false);
- }
-
- public String getA() {
- return null;
- }
-
- public int getB() {
- return 0;
- }
-
- public void setB(int x) {
- }
-
- public boolean isC() {
- return false;
- }
-
- public void setC(boolean x) {
- }
-
- public void setD(float x) {
- }
-
- public String getE() {
- return null;
- }
-
- public int getF() {
- return 0;
- }
-
- public void setF(int x) {
- }
-
- public void setG(boolean x) {
- }
-
- public int opA(int p1, int p2) {
- return 0;
- }
-
- public void opB(float x) {
- }
-
- public int getH() {
- return 0;
- }
-
- public void setH(int x) {
- }
- }
-
- @Description("MBean description")
- public static interface TestMXBean extends Interface {}
-
- public static class TestMXBeanImpl implements TestMXBean {
- @Description("0-arg constructor description")
- public TestMXBeanImpl() {}
-
- public TestMXBeanImpl(String why) {}
-
- @Description("2-arg constructor description")
- public TestMXBeanImpl(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {
- }
-
- public String getA() {
- return null;
- }
-
- public int getB() {
- return 0;
- }
-
- public void setB(int x) {
- }
-
- public boolean isC() {
- return false;
- }
-
- public void setC(boolean x) {
- }
-
- public void setD(float x) {
- }
-
- public String getE() {
- return null;
- }
-
- public int getF() {
- return 0;
- }
-
- public void setF(int x) {
- }
-
- public void setG(boolean x) {
- }
-
- public int opA(int p1, int p2) {
- return 0;
- }
-
- public void opB(float x) {
- }
-
- public int getH() {
- return 0;
- }
-
- public void setH(int x) {
- }
- }
-
- public static class StandardMXSub extends StandardMBean implements TestMXBean {
- @Description("0-arg constructor description")
- public StandardMXSub() {
- super(TestMXBean.class, true);
- }
-
- public StandardMXSub(String why) {
- super(TestMXBean.class, true);
- }
-
- @Description("2-arg constructor description")
- public StandardMXSub(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {
- super(TestMXBean.class, true);
- }
-
- public String getA() {
- return null;
- }
-
- public int getB() {
- return 0;
- }
-
- public void setB(int x) {
- }
-
- public boolean isC() {
- return false;
- }
-
- public void setC(boolean x) {
- }
-
- public void setD(float x) {
- }
-
- public String getE() {
- return null;
- }
-
- public int getF() {
- return 0;
- }
-
- public void setF(int x) {
- }
-
- public void setG(boolean x) {
- }
-
- public int opA(int p1, int p2) {
- return 0;
- }
-
- public void opB(float x) {
- }
-
- public int getH() {
- return 0;
- }
-
- public void setH(int x) {
- }
- }
-
- @MBean
- @Description("MBean description")
- public static class AnnotatedMBean {
- @Description("0-arg constructor description")
- public AnnotatedMBean() {}
-
- public AnnotatedMBean(String why) {}
-
- @Description("2-arg constructor description")
- public AnnotatedMBean(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {}
-
- @ManagedAttribute
- @Description("A description")
- public String getA() {
- return null;
- }
-
- @ManagedAttribute
- @Description("B description")
- public int getB() {
- return 0;
- }
-
- @ManagedAttribute
- public void setB(int x) {
- }
-
- @ManagedAttribute
- public boolean isC() {
- return false;
- }
-
- @ManagedAttribute
- @Description("C description")
- public void setC(boolean x) {
- }
-
- @ManagedAttribute
- @Description("D description")
- public void setD(float x) {
- }
-
- @ManagedAttribute
- public String getE() {
- return null;
- }
-
- @ManagedAttribute
- public int getF() {
- return 0;
- }
-
- @ManagedAttribute
- public void setF(int x) {
- }
-
- @ManagedAttribute
- public void setG(boolean x) {
- }
-
- @ManagedAttribute
- @Description("H description")
- public int getH() {
- return 0;
- }
-
- @ManagedAttribute
- @Description("H description")
- public void setH(int x) {
- }
-
- @ManagedOperation
- @Description("opA description")
- public int opA(
- @Description("p1 description") int p1,
- @Description("p2 description") int p2) {
- return 0;
- }
-
- @ManagedOperation
- public void opB(float x) {
- }
- }
-
- @MXBean
- @Description("MBean description")
- public static class AnnotatedMXBean {
- @Description("0-arg constructor description")
- public AnnotatedMXBean() {}
-
- public AnnotatedMXBean(String why) {}
-
- @Description("2-arg constructor description")
- public AnnotatedMXBean(
- @Description("p1 description")
- int x,
- @Description("p2 description")
- String y) {}
-
- @ManagedAttribute
- @Description("A description")
- public String getA() {
- return null;
- }
-
- @ManagedAttribute
- @Description("B description")
- public int getB() {
- return 0;
- }
-
- @ManagedAttribute
- public void setB(int x) {
- }
-
- @ManagedAttribute
- public boolean isC() {
- return false;
- }
-
- @ManagedAttribute
- @Description("C description")
- public void setC(boolean x) {
- }
-
- @ManagedAttribute
- @Description("D description")
- public void setD(float x) {
- }
-
- @ManagedAttribute
- public String getE() {
- return null;
- }
-
- @ManagedAttribute
- public int getF() {
- return 0;
- }
-
- @ManagedAttribute
- public void setF(int x) {
- }
-
- @ManagedAttribute
- public void setG(boolean x) {
- }
-
- @ManagedAttribute
- @Description("H description")
- public int getH() {
- return 0;
- }
-
- @ManagedAttribute
- @Description("H description")
- public void setH(int x) {
- }
-
- @ManagedOperation
- @Description("opA description")
- public int opA(
- @Description("p1 description") int p1,
- @Description("p2 description") int p2) {
- return 0;
- }
-
- @ManagedOperation
- public void opB(float x) {
- }
- }
-
- // Negative tests follow.
-
- // Inconsistent descriptions
- public static interface BadInterface {
- @Description("foo")
- public String getFoo();
- @Description("bar")
- public void setFoo(String x);
- }
-
- public static interface BadMBean extends BadInterface {}
-
- public static class Bad implements BadMBean {
- public String getFoo() {
- return null;
- }
-
- public void setFoo(String x) {
- }
- }
-
- public static interface BadMXBean extends BadInterface {}
-
- public static class BadMXBeanImpl implements BadMXBean {
- public String getFoo() {
- return null;
- }
-
- public void setFoo(String x) {
- }
- }
-
- private static interface Defaults {
- public String defaultAttributeDescription(String name);
- public String defaultOperationDescription(String name);
- public String defaultParameterDescription(int index);
- }
-
- private static class StandardDefaults implements Defaults {
- public String defaultAttributeDescription(String name) {
- return "Attribute exposed for management";
- }
-
- public String defaultOperationDescription(String name) {
- return "Operation exposed for management";
- }
-
- public String defaultParameterDescription(int index) {
- return "";
- }
- }
- private static final Defaults standardDefaults = new StandardDefaults();
-
- private static class MXBeanDefaults implements Defaults {
- public String defaultAttributeDescription(String name) {
- return name;
- }
-
- public String defaultOperationDescription(String name) {
- return name;
- }
-
- public String defaultParameterDescription(int index) {
- return "p" + index;
- }
- }
- private static final Defaults mxbeanDefaults = new MXBeanDefaults();
-
- private static class TestCase {
- final String name;
- final Object mbean;
- final Defaults defaults;
- TestCase(String name, Object mbean, Defaults defaults) {
- this.name = name;
- this.mbean = mbean;
- this.defaults = defaults;
- }
- }
-
- private static class ExceptionTest {
- final String name;
- final Object mbean;
- ExceptionTest(String name, Object mbean) {
- this.name = name;
- this.mbean = mbean;
- }
- }
-
- private static final TestCase[] tests = {
- new TestCase("Standard MBean", new Test(), standardDefaults),
- new TestCase("Standard MBean subclass", new TestSub(), standardDefaults),
- new TestCase("StandardMBean delegating",
- new StandardMBean(new Test(), TestMBean.class, false),
- standardDefaults),
- new TestCase("StandardMBean delegating to subclass",
- new StandardMBean(new TestSub(), TestMBean.class, false),
- standardDefaults),
- new TestCase("StandardMBean subclass", new StandardSub(), standardDefaults),
-
- new TestCase("MXBean", new TestMXBeanImpl(), mxbeanDefaults),
- new TestCase("StandardMBean MXBean delegating",
- new StandardMBean(new TestMXBeanImpl(), TestMXBean.class, true),
- mxbeanDefaults),
- new TestCase("StandardMBean MXBean subclass",
- new StandardMXSub(), mxbeanDefaults),
-
- new TestCase("@MBean", new AnnotatedMBean(), standardDefaults),
- new TestCase("@MXBean", new AnnotatedMXBean(), mxbeanDefaults),
- new TestCase("StandardMBean @MBean delegating",
- new StandardMBean(new AnnotatedMBean(), null, false),
- standardDefaults),
- new TestCase("StandardMBean @MXBean delegating",
- new StandardMBean(new AnnotatedMXBean(), null, true),
- mxbeanDefaults),
- };
-
- private static final ExceptionTest[] exceptionTests = {
- new ExceptionTest("Standard MBean with inconsistent get/set", new Bad()),
- new ExceptionTest("MXBean with inconsistent get/set", new BadMXBeanImpl()),
- };
-
- public static void main(String[] args) throws Exception {
- System.out.println("=== Testing correct MBeans ===");
- for (TestCase test : tests) {
- System.out.println("Testing " + test.name + "...");
- mbs.registerMBean(test.mbean, name);
- boolean expectConstructors =
- (test.mbean.getClass() != StandardMBean.class);
- check(mbs.getMBeanInfo(name), test.defaults, expectConstructors);
- mbs.unregisterMBean(name);
- }
- System.out.println();
-
- System.out.println("=== Testing incorrect MBeans ===");
- for (ExceptionTest test : exceptionTests) {
- System.out.println("Testing " + test.name);
- try {
- mbs.registerMBean(test.mbean, name);
- fail("Registration succeeded but should not have");
- mbs.unregisterMBean(name);
- } catch (NotCompliantMBeanException e) {
- // OK
- } catch (Exception e) {
- fail("Registration failed with wrong exception: " +
- "expected NotCompliantMBeanException, got " +
- e.getClass().getName());
- }
- }
- System.out.println();
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static void check(
- MBeanInfo mbi, Defaults defaults, boolean expectConstructors)
- throws Exception {
- assertEquals("MBean description", mbi.getDescription());
-
- // These attributes have descriptions
- for (String attr : new String[] {"A", "B", "C", "D", "H"}) {
- MBeanAttributeInfo mbai = getAttributeInfo(mbi, attr);
- assertEquals(attr + " description", mbai.getDescription());
- }
-
- // These attributes don't have descriptions
- for (String attr : new String[] {"E", "F", "G"}) {
- // If we ever change the default description, we'll need to change
- // this test accordingly.
- MBeanAttributeInfo mbai = getAttributeInfo(mbi, attr);
- assertEquals(
- defaults.defaultAttributeDescription(attr), mbai.getDescription());
- }
-
- // This operation has a description, as do its parameters
- MBeanOperationInfo opA = getOperationInfo(mbi, "opA");
- assertEquals("opA description", opA.getDescription());
- checkSignature(opA.getSignature());
-
- // This operation has the default description, as does its parameter
- MBeanOperationInfo opB = getOperationInfo(mbi, "opB");
- assertEquals(defaults.defaultOperationDescription("opB"), opB.getDescription());
- MBeanParameterInfo opB0 = opB.getSignature()[0];
- assertEquals(defaults.defaultParameterDescription(0), opB0.getDescription());
-
- if (expectConstructors) {
- // The 0-arg and 2-arg constructors have descriptions
- MBeanConstructorInfo con0 = getConstructorInfo(mbi, 0);
- assertEquals("0-arg constructor description", con0.getDescription());
- MBeanConstructorInfo con2 = getConstructorInfo(mbi, 2);
- assertEquals("2-arg constructor description", con2.getDescription());
- checkSignature(con2.getSignature());
-
- // The 1-arg constructor does not have a description.
- // The default description for constructors and their
- // parameters is the same for all types of MBean.
- MBeanConstructorInfo con1 = getConstructorInfo(mbi, 1);
- assertEquals("Public constructor of the MBean", con1.getDescription());
- assertEquals("", con1.getSignature()[0].getDescription());
- }
- }
-
- private static void checkSignature(MBeanParameterInfo[] params) {
- for (int i = 0; i < params.length; i++) {
- MBeanParameterInfo mbpi = params[i];
- assertEquals("p" + (i+1) + " description", mbpi.getDescription());
- }
- }
-
- private static MBeanAttributeInfo getAttributeInfo(MBeanInfo mbi, String attr)
- throws Exception {
- return getFeatureInfo(mbi.getAttributes(), attr);
- }
-
- private static MBeanOperationInfo getOperationInfo(MBeanInfo mbi, String op)
- throws Exception {
- return getFeatureInfo(mbi.getOperations(), op);
- }
-
- private static MBeanConstructorInfo getConstructorInfo(MBeanInfo mbi, int nparams)
- throws Exception {
- for (MBeanConstructorInfo mbci : mbi.getConstructors()) {
- if (mbci.getSignature().length == nparams)
- return mbci;
- }
- throw new Exception("Constructor not found: " + nparams);
- }
-
- private static <T extends MBeanFeatureInfo> T getFeatureInfo(
- T[] features, String name) throws Exception {
- for (T feature : features) {
- if (feature.getName().equals(name))
- return feature;
- }
- throw new Exception("Feature not found: " + name);
- }
-
- private static void assertEquals(Object expected, Object actual) {
- if (!expected.equals(actual))
- fail("Expected " + string(expected) + ", got " + string(actual));
- }
-
- private static String string(Object x) {
- if (x instanceof String)
- return quote((String) x);
- else
- return String.valueOf(x);
- }
-
- private static String quote(String s) {
- return '"' + s.replace("\\", "\\\\").replace("\"", "\\\"") + '"';
- }
-
- private static void fail(String why) {
- StackTraceElement[] stack = new Throwable().getStackTrace();
- int n = 0;
- for (StackTraceElement elmt : stack) {
- String method = elmt.getMethodName();
- if (method.equals("fail") || method.equals("assertEquals") ||
- method.equals("checkSignature"))
- continue;
- n = elmt.getLineNumber();
- break;
- }
- System.out.println("FAILED: " + why + " (line " + n + ")");
- failure = why;
- }
-}
--- a/jdk/test/javax/management/Introspector/ObjectNameTemplateTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +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.
- *
- * 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.
- */
-
-/*
- * @test %M% %I%
- * @bug 6675526
- * @summary Test MBeans named with @ObjectNameTemplate
- * @author Jean-Francois Denise
- * @run main/othervm ObjectNameTemplateTest
- */
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.List;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.ImmutableDescriptor;
-import javax.management.InvalidAttributeValueException;
-import javax.management.JMX;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.MXBean;
-import javax.management.MBean;
-import javax.management.ManagedAttribute;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-import javax.management.ObjectNameTemplate;
-import javax.management.ReflectionException;
-import javax.management.StandardMBean;
-
-public class ObjectNameTemplateTest {
-
- private static MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- private static final String NAME_TEMPLATE_MULTI =
- "com.example:type=MultiStdCache,name={Name}";
- private static final String NAME_TEMPLATE_MONO =
- "com.example:{Type}={TypeValue}";
- private static final String NAME_TEMPLATE_QUOTED =
- "com.example:type=Quotted,name=\"{Name}\"";
- private static final String NAME_TEMPLATE_WRAPPED =
- "com.example:type=MgtInterface,id={Id}";
- private static final String NAME_TEMPLATE_FULL =
- "{Naming}";
- private static final String FULL_NAME = "com.example:type=NotAdvised";
- private static final String NAME1 = "toto1";
- private static final String NAME2 = "toto2";
- private static final String TYPE_KEY = "thisIsTheType";
- private static final String TYPE_VALUE = "aTypeValue";
- private static final String INVALID_NAME = "?,=*,\n, ";
- private static final int ID = 999;
- private static Object[] EMPTY_PARAMS = {};
- private static String[] EMPTY_SIGNATURE = {};
- private static final ObjectName OBJECTNAME_CACHE =
- ObjectName.valueOf("com.example:type=Cache");
- private static final ObjectName OBJECTNAME_SUBCACHE =
- ObjectName.valueOf("com.example:type=SubCache");
- private static final ObjectName OBJECTNAME_CACHEMX =
- ObjectName.valueOf("com.example:type=CacheMX");
- private static final ObjectName OBJECTNAME_SUBCACHEMX =
- ObjectName.valueOf("com.example:type=SubCacheMX");
- private static final ObjectName OBJECTNAME_DYNACACHE =
- ObjectName.valueOf("com.example:type=DynaCache");
- private static final ObjectName OBJECTNAME_STDCACHE =
- ObjectName.valueOf("com.example:type=StdCache");
- private static final ObjectName OBJECTNAME_STDCACHEMX =
- ObjectName.valueOf("com.example:type=StdCacheMX");
- private static final ObjectName OBJECTNAME_MULTI_1 =
- ObjectName.valueOf("com.example:" +
- "type=MultiStdCache,name=" + NAME1);
- private static final ObjectName OBJECTNAME_MULTI_2 =
- ObjectName.valueOf("com.example:" +
- "type=MultiStdCache,name=" + NAME2);
- private static final ObjectName OBJECTNAME_MONO =
- ObjectName.valueOf("com.example:" + TYPE_KEY + "=" +
- TYPE_VALUE);
- private static final ObjectName OBJECTNAME_QUOTED =
- ObjectName.valueOf("com.example:type=Quotted," +
- "name="+ObjectName.quote(INVALID_NAME));
- private static final ObjectName OBJECTNAME_WRAPPED_RESOURCE =
- ObjectName.valueOf("com.example:type=MgtInterface,id=" + ID);
- private static final ObjectName OBJECTNAME_FULL =
- ObjectName.valueOf(FULL_NAME);
-
- private static void test(Class<?> mbean, Object[] params,
- String[] signature, ObjectName name, String template)
- throws Exception {
- mbs.createMBean(mbean.getName(), null, params, signature);
- test(name, template);
- List<Class<?>> parameters = new ArrayList<Class<?>>();
- for (String sig : signature) {
- parameters.add(Class.forName(sig));
- }
- Class<?> classes[] = new Class<?>[parameters.size()];
- Constructor ctr = mbean.getConstructor(parameters.toArray(classes));
- Object inst = ctr.newInstance(params);
- test(inst, name, template);
- }
-
- private static void test(Object obj, ObjectName name, String template)
- throws Exception {
- mbs.registerMBean(obj, null);
- test(name, template);
- }
-
- private static void test(ObjectName name, String template)
- throws Exception {
- if (!mbs.isRegistered(name)) {
- throw new Exception("Wrong " + name + " name");
- }
- if (template != null && !mbs.getMBeanInfo(name).getDescriptor().
- getFieldValue("objectNameTemplate").equals(template)) {
- throw new Exception("Invalid Derscriptor");
- }
- mbs.unregisterMBean(name);
- }
-
- public static void main(String[] args) throws Exception {
- test(Cache.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_CACHE,
- OBJECTNAME_CACHE.toString());
-
- test(CacheMX.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_CACHEMX,
- OBJECTNAME_CACHEMX.toString());
-
- test(SubCache.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_SUBCACHE,
- OBJECTNAME_SUBCACHE.toString());
-
- test(SubCacheMX.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_SUBCACHEMX,
- OBJECTNAME_SUBCACHEMX.toString());
-
- test(DynaCache.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_DYNACACHE,
- null);
-
- test(StdCacheMX.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_STDCACHEMX,
- OBJECTNAME_STDCACHEMX.toString());
-
- test(StdCache.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_STDCACHE,
- OBJECTNAME_STDCACHE.toString());
- String[] sig = {String.class.getName()};
- Object[] params = {NAME1};
- test(MultiStdCache.class, params, sig, OBJECTNAME_MULTI_1,
- NAME_TEMPLATE_MULTI);
- Object[] params2 = {NAME2};
- test(MultiStdCache.class, params2, sig, OBJECTNAME_MULTI_2,
- NAME_TEMPLATE_MULTI);
-
- test(MonoStdCache.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_MONO,
- NAME_TEMPLATE_MONO);
-
- test(Quoted.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_QUOTED,
- NAME_TEMPLATE_QUOTED);
-
- test(new StandardMBean(new WrappedResource(), MgtInterface.class),
- OBJECTNAME_WRAPPED_RESOURCE, NAME_TEMPLATE_WRAPPED);
-
- test(FullName.class, EMPTY_PARAMS, EMPTY_SIGNATURE, OBJECTNAME_FULL,
- NAME_TEMPLATE_FULL);
- try {
- test(Wrong.class, EMPTY_PARAMS, EMPTY_SIGNATURE, null, null);
- throw new Exception("No treceived expected Exception");
- } catch (NotCompliantMBeanException ncex) {
- if (!(ncex.getCause() instanceof AttributeNotFoundException)) {
- throw new Exception("Invalid initCause");
- }
- }
- }
-
- @MBean
- @ObjectNameTemplate("{Naming}")
- public static class FullName {
-
- @ManagedAttribute
- public String getNaming() {
- return FULL_NAME;
- }
- }
-
- @ObjectNameTemplate("com.example:type=MgtInterface,id={Id}")
- public interface MgtInterface {
-
- public int getId();
- }
-
- public static class WrappedResource implements MgtInterface {
-
- public int getId() {
- return ID;
- }
- }
-
- @MBean
- @ObjectNameTemplate("com.example:type=Cache")
- public static class Cache {
- }
-
- @ObjectNameTemplate("com.example:type=SubCache")
- public static class SubCache extends Cache {
- }
-
- @MXBean
- @ObjectNameTemplate("com.example:type=CacheMX")
- public static class CacheMX {
- }
-
- @ObjectNameTemplate("com.example:type=SubCacheMX")
- public static class SubCacheMX extends CacheMX {
- }
-
- @ObjectNameTemplate("com.example:type=StdCache")
- public interface StdCacheMBean {
- }
-
- public static class StdCache implements StdCacheMBean {
- }
-
- @ObjectNameTemplate("com.example:type=StdCacheMX")
- public interface StdCacheMXBean {
- }
-
- public static class StdCacheMX implements StdCacheMXBean {
- }
-
- public static class DynaCache implements DynamicMBean {
-
- public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public AttributeList getAttributes(String[] attributes) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public MBeanInfo getMBeanInfo() {
- ImmutableDescriptor d = new ImmutableDescriptor(JMX.OBJECT_NAME_TEMPLATE + "=com.example:type=DynaCache");
-
- return new MBeanInfo("DynaCache", "Description", null, null, null, null, d);
- }
- }
-
- @ObjectNameTemplate("com.example:type=MultiStdCache,name={Name}")
- public interface MultiStdCacheMXBean {
-
- public String getName();
- }
-
- public static class MultiStdCache implements MultiStdCacheMXBean {
-
- private String name;
-
- public MultiStdCache(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
- }
-
- @ObjectNameTemplate("com.example:{Type}={TypeValue}")
- public interface MonoStdCacheMXBean {
-
- public String getTypeValue();
-
- public String getType();
- }
-
- public static class MonoStdCache implements MonoStdCacheMXBean {
-
- public String getTypeValue() {
- return TYPE_VALUE;
- }
-
- public String getType() {
- return TYPE_KEY;
- }
- }
-
- @ObjectNameTemplate("com.example:type=Quotted,name=\"{Name}\"")
- public interface QuottedMXBean {
-
- public String getName();
- }
-
- public static class Quoted implements QuottedMXBean {
-
- public String getName() {
- return INVALID_NAME;
- }
- }
-
- @ObjectNameTemplate("com.example:{Type}={TypeValue}, name={Name}")
- public interface WrongMXBean {
-
- public String getTypeValue();
-
- public String getType();
- }
-
- public static class Wrong implements WrongMXBean {
-
- public String getTypeValue() {
- return TYPE_VALUE;
- }
-
- public String getType() {
- return TYPE_KEY;
- }
- }
-}
--- a/jdk/test/javax/management/Introspector/ParameterNameTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +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.
- *
- * 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.
- */
-
-/*
- * @test %M% %I%
- * @bug 6323980
- * @summary Test that parameter names can be specified with @Name.
- * @author Eamonn McManus
- */
-
-import javax.management.MBean;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MXBean;
-import javax.management.ObjectName;
-
-import annot.Name;
-import javax.management.ManagedOperation;
-
-public class ParameterNameTest {
- public static interface NoddyMBean {
- public int add(int x, @Name("y") int y);
- }
-
- public static class Noddy implements NoddyMBean {
- public int add(int x, int y) {
- return x + y;
- }
- }
-
- public static interface NoddyMXBean {
- public int add(int x, @Name("y") int y);
- }
-
- public static class NoddyImpl implements NoddyMXBean {
- public int add(int x, int y) {
- return x + y;
- }
- }
-
- @MBean
- public static class NoddyAnnot {
- @ManagedOperation
- public int add(int x, @Name("y") int y) {
- return x + y;
- }
- }
-
- @MXBean
- public static class NoddyAnnotMX {
- @ManagedOperation
- public int add(int x, @Name("y") int y) {
- return x + y;
- }
- }
-
- private static final Object[] mbeans = {
- new Noddy(), new NoddyImpl(), new NoddyAnnot(), new NoddyAnnotMX(),
- };
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- ObjectName name = new ObjectName("a:b=c");
- for (Object mbean : mbeans) {
- System.out.println("Testing " + mbean.getClass().getName());
- mbs.registerMBean(mbean, name);
- MBeanInfo mbi = mbs.getMBeanInfo(name);
- MBeanOperationInfo[] mbois = mbi.getOperations();
- assertEquals(1, mbois.length);
- MBeanParameterInfo[] mbpis = mbois[0].getSignature();
- assertEquals(2, mbpis.length);
- boolean mx = Boolean.parseBoolean(
- (String) mbi.getDescriptor().getFieldValue("mxbean"));
- assertEquals(mx ? "p0" : "p1", mbpis[0].getName());
- assertEquals("y", mbpis[1].getName());
- mbs.unregisterMBean(name);
- }
- System.out.println("TEST PASSED");
- }
-
- private static void assertEquals(Object expect, Object actual)
- throws Exception {
- boolean eq;
- if (expect == null)
- eq = (actual == null);
- else
- eq = expect.equals(actual);
- if (!eq) {
- throw new Exception(
- "TEST FAILED: expected " + expect + ", found " + actual);
- }
- }
-}
--- a/jdk/test/javax/management/Introspector/ResourceInjectionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,656 +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.
- *
- * 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.
- */
-
-/*
- * @test %M% %I%
- * @bug 6323980
- * @summary Test resource injection via @Resource
- * @author Eamonn McManus
- * @run main/othervm -ea ResourceInjectionTest
- */
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import javax.annotation.Resource;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBean;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MXBean;
-import javax.management.MalformedObjectNameException;
-import javax.management.ManagedAttribute;
-import javax.management.ManagedOperation;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.SendNotification;
-import javax.management.StandardEmitterMBean;
-import javax.management.StandardMBean;
-import javax.management.openmbean.MXBeanMappingFactory;
-
-public class ResourceInjectionTest {
- private static MBeanServer mbs;
- private static final ObjectName objectName;
- static {
- try {
- objectName = new ObjectName("test:type=Test");
- } catch (MalformedObjectNameException e) {
- throw new RuntimeException(e);
- }
- }
-
- /* This is somewhat nasty. In the current state of affairs, a
- * StandardEmitterMBean can only get the
- * MBeanServer to rewrite the source of a Notification from
- * the originating object's reference to its ObjectName IF
- * StandardEmitterMBean.getResource() returns a reference to the
- * wrapped object. By default it doesn't, and you need to specify
- * the option below to make it do so. We may hope that this is
- * obscure enough for users to run into it rarely if ever.
- */
- private static final StandardMBean.Options withWrappedVisible;
- private static final StandardMBean.Options withWrappedVisibleMX;
- static {
- withWrappedVisible = new StandardMBean.Options();
- withWrappedVisible.setWrappedObjectVisible(true);
- withWrappedVisibleMX = withWrappedVisible.clone();
- withWrappedVisibleMX.setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- private static @interface ExpectException {
- Class<? extends Exception> value();
- }
-
- public static void main(String[] args) throws Exception {
- if (!ResourceInjectionTest.class.desiredAssertionStatus())
- throw new Exception("Test must be run with -ea");
-
- File policyFile = File.createTempFile("jmxperms", ".policy");
- policyFile.deleteOnExit();
- PrintWriter pw = new PrintWriter(policyFile);
- pw.println("grant {");
- pw.println(" permission javax.management.MBeanPermission \"*\", \"*\";");
- pw.println(" permission javax.management.MBeanServerPermission \"*\";");
- pw.println(" permission javax.management.MBeanTrustPermission \"*\";");
- pw.println("};");
- pw.close();
-
- System.setProperty("java.security.policy", policyFile.getAbsolutePath());
- System.setSecurityManager(new SecurityManager());
-
- String failure = null;
-
- for (Method m : ResourceInjectionTest.class.getDeclaredMethods()) {
- if (Modifier.isStatic(m.getModifiers()) &&
- m.getName().startsWith("test") &&
- m.getParameterTypes().length == 0) {
- ExpectException expexc = m.getAnnotation(ExpectException.class);
- mbs = MBeanServerFactory.newMBeanServer();
- try {
- m.invoke(null);
- if (expexc != null) {
- failure =
- m.getName() + " did not got expected exception " +
- expexc.value().getName();
- System.out.println(failure);
- } else
- System.out.println(m.getName() + " OK");
- } catch (InvocationTargetException ite) {
- Throwable t = ite.getCause();
- String prob = null;
- if (expexc != null) {
- if (expexc.value().isInstance(t)) {
- System.out.println(m.getName() + " OK (got expected " +
- expexc.value().getName() + ")");
- } else
- prob = "got wrong exception";
- } else
- prob = "got exception";
- if (prob != null) {
- failure = m.getName() + ": " + prob + " " +
- t.getClass().getName();
- System.out.println(failure);
- t.printStackTrace(System.out);
- }
- }
- }
- }
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static interface Send {
- public void send();
- }
-
- // Test @Resource in MBean defined by annotations
-
- @MBean
- public static class Annotated {
- @Resource
- private volatile MBeanServer mbeanServer;
- @Resource
- private volatile ObjectName myName;
-
- @ManagedAttribute
- public ObjectName getMyName() {
- return myName;
- }
-
- @ManagedOperation
- public void unregisterSelf()
- throws InstanceNotFoundException, MBeanRegistrationException {
- mbeanServer.unregisterMBean(myName);
- }
- }
-
- private static void testAnnotated() throws Exception {
- testMBean(new Annotated());
- }
-
- private static void testAnnotatedWrapped() throws Exception {
- testMBean(new StandardMBean(new Annotated(), null));
- }
-
- @MBean
- public static class AnnotatedSend extends Annotated implements Send {
- @Resource
- private volatile SendNotification sender;
-
- @ManagedOperation
- public void send() {
- sender.sendNotification(new Notification("type", this, 0L));
- }
- }
-
- private static void testAnnotatedSend() throws Exception {
- testMBean(new AnnotatedSend());
- }
-
- private static void testAnnotatedSendWrapped() throws Exception {
- testMBean(new StandardEmitterMBean(
- new AnnotatedSend(), null, withWrappedVisible, null));
- }
-
- // Test @Resource in MXBean defined by annotations
-
- @MXBean
- public static class AnnotatedMX {
- @Resource
- private volatile MBeanServer mbeanServer;
- @Resource
- private volatile ObjectName myName;
-
- @ManagedAttribute
- public ObjectName getMyName() {
- return myName;
- }
-
- @ManagedOperation
- public void unregisterSelf()
- throws InstanceNotFoundException, MBeanRegistrationException {
- mbeanServer.unregisterMBean(myName);
- }
- }
-
- private static void testAnnotatedMX() throws Exception {
- testMBean(new AnnotatedMX());
- }
-
- private static void testAnnotatedMXWrapped() throws Exception {
- testMBean(new StandardMBean(new AnnotatedMX(), null, true));
- }
-
- public static class AnnotatedMXSend extends AnnotatedMX implements Send {
- @Resource
- private volatile SendNotification sender;
-
- @ManagedOperation
- public void send() {
- sender.sendNotification(new Notification("type", this, 0L));
- }
- }
-
- private static void testAnnotatedMXSend() throws Exception {
- testMBean(new AnnotatedMXSend());
- }
-
- private static void testAnnotatedMXSendWrapped() throws Exception {
- testMBean(new StandardEmitterMBean(
- new AnnotatedMXSend(), null, withWrappedVisibleMX, null));
- }
-
- // Test @Resource in Standard MBean
-
- public static interface SimpleStandardMBean {
- public ObjectName getMyName();
- public void unregisterSelf() throws Exception;
- }
-
- public static class SimpleStandard implements SimpleStandardMBean {
- @Resource(type = MBeanServer.class)
- private volatile Object mbeanServer;
- @Resource(type = ObjectName.class)
- private volatile Object myName;
-
- public ObjectName getMyName() {
- return (ObjectName) myName;
- }
-
- public void unregisterSelf() throws Exception {
- ((MBeanServer) mbeanServer).unregisterMBean(getMyName());
- }
- }
-
- private static void testStandard() throws Exception {
- testMBean(new SimpleStandard());
- }
-
- private static void testStandardWrapped() throws Exception {
- testMBean(new StandardMBean(new SimpleStandard(), SimpleStandardMBean.class));
- }
-
- public static interface SimpleStandardSendMBean extends SimpleStandardMBean {
- public void send();
- }
-
- public static class SimpleStandardSend
- extends SimpleStandard implements SimpleStandardSendMBean {
- @Resource(type = SendNotification.class)
- private volatile Object sender;
-
- public void send() {
- ((SendNotification) sender).sendNotification(
- new Notification("type", this, 0L));
- }
- }
-
- private static void testStandardSend() throws Exception {
- testMBean(new SimpleStandardSend());
- }
-
- private static void testStandardSendWrapped() throws Exception {
- testMBean(new StandardEmitterMBean(
- new SimpleStandardSend(), SimpleStandardSendMBean.class,
- withWrappedVisible, null));
- }
-
- // Test @Resource in MXBean
-
- public static interface SimpleMXBean {
- public ObjectName getMyName();
- public void unregisterSelf() throws Exception;
- }
-
- public static class SimpleMX implements SimpleMXBean {
- @Resource(type = MBeanServer.class)
- private volatile Object mbeanServer;
- @Resource(type = ObjectName.class)
- private volatile Object myName;
-
- public ObjectName getMyName() {
- return (ObjectName) myName;
- }
-
- public void unregisterSelf() throws Exception {
- ((MBeanServer) mbeanServer).unregisterMBean(getMyName());
- }
- }
-
- private static void testMX() throws Exception {
- testMBean(new SimpleMX());
- }
-
- private static void testMXWrapped() throws Exception {
- testMBean(new StandardMBean(new SimpleMX(), SimpleMXBean.class, true));
- }
-
- public static interface SimpleMXBeanSend extends SimpleMXBean {
- public void send();
- }
-
- public MBeanServer getMbs() {
- return mbs;
- }
-
- public static class SimpleMXSend extends SimpleMX implements SimpleMXBeanSend {
- @Resource(type = SendNotification.class)
- private volatile Object sender;
-
- public void send() {
- ((SendNotification) sender).sendNotification(
- new Notification("type", this, 0L));
- }
- }
-
- private static void testMXSend() throws Exception {
- testMBean(new SimpleMXSend());
- }
-
- private static void testMXSendWrapped() throws Exception {
- testMBean(new StandardEmitterMBean(
- new SimpleMXSend(), SimpleMXBeanSend.class,
- withWrappedVisibleMX, null));
- }
-
- // Test @Resource in Dynamic MBean
-
- private static class SimpleDynamic implements DynamicMBean {
- private MBeanServer mbeanServer;
- private ObjectName myName;
-
- @Resource
- private synchronized void setMBeanServer(MBeanServer mbs) {
- mbeanServer = mbs;
- }
-
- @Resource(type = ObjectName.class)
- private synchronized void setObjectName(Serializable name) {
- myName = (ObjectName) name;
- }
-
- public synchronized Object getAttribute(String attribute)
- throws AttributeNotFoundException {
- if (attribute.equals("MyName"))
- return myName;
- throw new AttributeNotFoundException(attribute);
- }
-
- public void setAttribute(Attribute attribute)
- throws AttributeNotFoundException {
- throw new AttributeNotFoundException(attribute.getName());
- }
-
- public synchronized AttributeList getAttributes(String[] attributes) {
- AttributeList list = new AttributeList();
- for (String name : attributes) {
- if (name.equals("MyName"))
- list.add(new Attribute("MyName", myName));
- }
- return list;
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- return new AttributeList();
- }
-
- public synchronized Object invoke(
- String actionName, Object[] params, String[] signature)
- throws MBeanException, ReflectionException {
- if (actionName.equals("unregisterSelf") &&
- (params == null || params.length == 0) &&
- (signature == null || signature.length == 0)) {
- try {
- mbeanServer.unregisterMBean(myName);
- return null;
- } catch (Exception x) {
- throw new MBeanException(x);
- }
- } else {
- Exception x = new NoSuchMethodException(
- actionName + Arrays.toString(signature));
- throw new MBeanException(x);
- }
- }
-
- public MBeanInfo getMBeanInfo() {
- DynamicMBean mbean = new StandardMBean(
- new SimpleStandard(), SimpleStandardMBean.class, false);
- return mbean.getMBeanInfo();
- }
- }
-
- private static void testDynamic() throws Exception {
- testMBean(new SimpleDynamic());
- }
-
- private static class SimpleDynamicSend extends SimpleDynamic {
- private SendNotification sender;
-
- @Resource
- private synchronized void setSender(SendNotification sender) {
- this.sender = sender;
- }
-
- @Override
- public synchronized Object invoke(
- String actionName, Object[] params, String[] signature)
- throws MBeanException, ReflectionException {
- if (actionName.equals("send")) {
- sender.sendNotification(new Notification("type", this, 0L));
- return null;
- } else
- return super.invoke(actionName, params, signature);
- }
- }
-
- private static void testDynamicSend() throws Exception {
- testMBean(new SimpleDynamicSend());
- }
-
- // Test that @Resource classes don't have to be public
- // They can even be defined within methods!
- // But you can't have any @ManagedAttributes or @ManagedOperations
- // in such MBeans so their utility is limited.
-
- private static void testNonPublic() throws Exception {
- @MBean
- class NonPublic {
- @Resource
- ObjectName myName;
- }
- assert !Modifier.isPublic(NonPublic.class.getModifiers());
- NonPublic mbean = new NonPublic();
- mbs.registerMBean(mbean, objectName);
- assert objectName.equals(mbean.myName);
- }
-
- // Test inheritance and multiple injections of the same value
-
- private static class ManyResources extends AnnotatedSend {
- @Resource
- private volatile ObjectName myName; // same name as in parent!
- @Resource(type=ObjectName.class)
- private volatile Object myOtherName;
- private volatile ObjectName myThirdName;
- private volatile ObjectName myFourthName;
- private volatile int methodCalls;
- @Resource
- private volatile SendNotification send1;
- @Resource(type = SendNotification.class)
- private volatile Object send2;
-
- @Resource
- void setMyName(ObjectName name) {
- myThirdName = name;
- methodCalls++;
- }
-
- @Resource(type=ObjectName.class)
- private void setMyNameAgain(ObjectName name) {
- myFourthName = name;
- methodCalls++;
- }
-
- void check() {
- assert objectName.equals(myName) : myName;
- for (ObjectName name : new ObjectName[] {
- (ObjectName)myOtherName, myThirdName, myFourthName
- }) {
- assert myName == name : name;
- }
- assert methodCalls == 2 : methodCalls;
- assert send1 != null && send2 == send1;
- }
- }
-
- private static void testManyResources() throws Exception {
- ManyResources mr = new ManyResources();
- testMBean(mr);
- mr.check();
- }
-
- // Test that method override doesn't lead to multiple calls of the same method
-
- private static class ManyResourcesSub extends ManyResources {
- private boolean called;
-
- @Override
- @Resource
- void setMyName(ObjectName name) {
- super.setMyName(name);
- called = true;
- }
-
- void check2() {
- assert called;
- }
- }
-
- private static void testOverride() throws Exception {
- ManyResourcesSub mrs = new ManyResourcesSub();
- testMBean(mrs);
- mrs.check();
- mrs.check2();
- }
-
- // Test that @Resource is illegal on static fields
-
- @MBean
- public static class StaticResource {
- @Resource
- private static ObjectName name;
- }
-
- @ExpectException(NotCompliantMBeanException.class)
- private static void testStaticResource() throws Exception {
- testMBean(new StaticResource());
- }
-
- // Test that @Resource is illegal on static methods
-
- @MBean
- public static class StaticResourceMethod {
- @Resource
- private static void setObjectName(ObjectName name) {}
- }
-
- @ExpectException(NotCompliantMBeanException.class)
- private static void testStaticResourceMethod() throws Exception {
- testMBean(new StaticResourceMethod());
- }
-
- // Test that @Resource is illegal on methods that don't return void
-
- @MBean
- public static class NonVoidMethod {
- @Resource
- private String setObjectName(ObjectName name) {
- return "oops";
- }
- }
-
- @ExpectException(NotCompliantMBeanException.class)
- private static void testNonVoidMethod() throws Exception {
- testMBean(new NonVoidMethod());
- }
-
- // Test that @Resource is illegal on methods with no arguments
-
- @MBean
- public static class NoArgMethod {
- @Resource(type=ObjectName.class)
- private void setObjectName() {}
- }
-
- @ExpectException(NotCompliantMBeanException.class)
- private static void testNoArgMethod() throws Exception {
- testMBean(new NoArgMethod());
- }
-
- // Test that @Resource is illegal on methods with more than one argument
-
- @MBean
- public static class MultiArgMethod {
- @Resource
- private void setObjectName(ObjectName name, String what) {}
- }
-
- @ExpectException(NotCompliantMBeanException.class)
- private static void testMultiArgMethod() throws Exception {
- testMBean(new MultiArgMethod());
- }
-
- private static class CountListener implements NotificationListener {
- volatile int count;
- public void handleNotification(Notification notification, Object handback) {
- count++;
- }
- }
-
- private static void testMBean(Object mbean) throws Exception {
- mbs.registerMBean(mbean, objectName);
-
- final ObjectName name = (ObjectName) mbs.getAttribute(objectName, "MyName");
- assert objectName.equals(name) : name;
-
- if (mbean instanceof Send || mbean instanceof NotificationEmitter) {
- assert mbs.isInstanceOf(name, NotificationEmitter.class.getName());
- CountListener countL = new CountListener();
- mbs.addNotificationListener(name, countL, null, null);
- NotificationListener checkSource = new NotificationListener() {
- public void handleNotification(Notification n, Object h) {
- assert n.getSource().equals(name) : n.getSource();
- }
- };
- mbs.addNotificationListener(name, checkSource, null, null);
- mbs.invoke(objectName, "send", null, null);
- assert countL.count == 1;
- mbs.removeNotificationListener(name, checkSource);
- mbs.removeNotificationListener(name, countL, null, null);
- }
-
- mbs.invoke(objectName, "unregisterSelf", null, null);
- assert !mbs.isRegistered(objectName);
- }
-}
--- a/jdk/test/javax/management/MBeanServer/AttributeListMapTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6336968
- * @summary Test AttributeList.toMap
- * @author Eamonn McManus
- */
-
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-
-public class AttributeListMapTest {
-
- private static String failure;
-
- public static void main(String[] args) throws Exception {
- AttributeList attrs = new AttributeList(Arrays.asList(
- new Attribute("Str", "Five"),
- new Attribute("Int", 5),
- new Attribute("Flt", 5.0)));
-
- Map<String, Object> map = attrs.toMap();
- final Map<String, Object> expectMap = new HashMap<String, Object>();
- for (Attribute attr : attrs.asList())
- expectMap.put(attr.getName(), attr.getValue());
- assertEquals("Initial map", expectMap, map);
- assertEquals("Initial map size", 3, map.size());
- assertEquals("Name set", expectMap.keySet(), map.keySet());
- assertEquals("Values", new HashSet<Object>(expectMap.values()),
- new HashSet<Object>(map.values()));
- assertEquals("Entry set", expectMap.entrySet(), map.entrySet());
-
- AttributeList attrs2 = new AttributeList(map);
- assertEquals("AttributeList from Map", attrs, attrs2);
- // This assumes that the Map conserves the order of the attributes,
- // which is not specified but true because we use LinkedHashMap.
-
- // Check that toMap fails if the list contains non-Attribute elements.
- AttributeList attrs3 = new AttributeList(attrs);
- attrs3.add("Hello"); // allowed but curious
- try {
- map = attrs3.toMap();
- fail("toMap succeeded on list with non-Attribute elements");
- } catch (Exception e) {
- assertEquals("Exception for toMap with non-Atttribute elements",
- IllegalArgumentException.class, e.getClass());
- }
-
- // Check that the Map does not reflect changes made to the list after
- // the Map was obtained.
- AttributeList attrs4 = new AttributeList(attrs);
- map = attrs4.toMap();
- attrs4.add(new Attribute("Big", new BigInteger("5")));
- assertEquals("Map after adding element to list", expectMap, map);
-
- // Check that if there is more than one Attribute with the same name
- // then toMap() chooses the last of them.
- AttributeList attrs5 = new AttributeList(attrs);
- attrs5.add(new Attribute("Str", "Cinq"));
- map = attrs5.toMap();
- assertEquals("Size of Map for list with duplicate attribute name",
- 3, map.size());
- Object value = map.get("Str");
- assertEquals("Value of Str in Map for list with two values for it",
- "Cinq", value);
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static void assertEquals(String what, Object expect, Object actual) {
- if (eq(expect, actual))
- System.out.println("OK: " + what);
- else
- fail(what + ": expected " + expect + ", got " + actual);
- }
-
- private static boolean eq(Object x, Object y) {
- return (x == null) ? (y == null) : x.equals(y);
- }
-
- private static void fail(String why) {
- System.out.println("FAIL: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/MBeanServer/DynamicWrapperMBeanTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,405 +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.
- *
- * 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.
- */
-
-/*
- * @test DynamicWrapperMBeanTest
- * @bug 6624232 6776225
- * @summary Test the DynamicWrapperMBean interface
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import javax.annotation.Resource;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationInfo;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.SendNotification;
-import javax.management.StandardEmitterMBean;
-import javax.management.StandardMBean;
-import javax.management.modelmbean.ModelMBeanInfo;
-import javax.management.modelmbean.ModelMBeanInfoSupport;
-import javax.management.modelmbean.ModelMBeanOperationInfo;
-import javax.management.modelmbean.RequiredModelMBean;
-import static javax.management.StandardMBean.Options;
-
-public class DynamicWrapperMBeanTest {
- private static String failure;
-
- public static void main(String[] args) throws Exception {
- wrapTest();
- notifTest();
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static final Options wrappedVisOpts = new Options();
- private static final Options wrappedInvisOpts = new Options();
- static {
- wrappedVisOpts.setWrappedObjectVisible(true);
- wrappedInvisOpts.setWrappedObjectVisible(false);
- }
-
- public static interface WrappedMBean {
- public void sayHello();
- }
- public static class Wrapped implements WrappedMBean {
- public void sayHello() {
- System.out.println("Hello");
- }
- }
-
- private static void wrapTest() throws Exception {
- if (Wrapped.class.getClassLoader() ==
- StandardMBean.class.getClassLoader()) {
- throw new Exception(
- "TEST ERROR: Resource and StandardMBean have same ClassLoader");
- }
-
- assertEquals("Options withWrappedObjectVisible(false)",
- new Options(), wrappedInvisOpts);
-
- Wrapped resource = new Wrapped();
-
- StandardMBean visible =
- new StandardMBean(resource, WrappedMBean.class, wrappedVisOpts);
- StandardMBean invisible =
- new StandardMBean(resource, WrappedMBean.class, wrappedInvisOpts);
-
- assertEquals("getResource withWrappedObjectVisible(true)",
- resource, visible.getWrappedObject());
- assertEquals("getResource withWrappedObjectVisible(false)",
- invisible, invisible.getWrappedObject());
-
- System.out.println("===Testing StandardMBean===");
-
- ObjectName visibleName = new ObjectName("a:type=visible");
- ObjectName invisibleName = new ObjectName("a:type=invisible");
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- mbs.registerMBean(visible, visibleName);
- mbs.registerMBean(invisible, invisibleName);
-
- assertEquals("ClassLoader for visible resource",
- Wrapped.class.getClassLoader(),
- mbs.getClassLoaderFor(visibleName));
- assertEquals("ClassLoader for invisible resource",
- StandardMBean.class.getClassLoader(),
- mbs.getClassLoaderFor(invisibleName));
-
- assertEquals("isInstanceOf(WrappedMBean) for visible wrapped",
- true, mbs.isInstanceOf(visibleName, WrappedMBean.class.getName()));
- assertEquals("isInstanceOf(WrappedMBean) for invisible wrapped",
- false, mbs.isInstanceOf(invisibleName, WrappedMBean.class.getName()));
- assertEquals("isInstanceOf(StandardMBean) for visible wrapped",
- false, mbs.isInstanceOf(visibleName, StandardMBean.class.getName()));
- assertEquals("isInstanceOf(StandardMBean) for invisible wrapped",
- true, mbs.isInstanceOf(invisibleName, StandardMBean.class.getName()));
-
- mbs.unregisterMBean(visibleName);
- mbs.unregisterMBean(invisibleName);
-
- System.out.println("===Testing RequiredModelMBean===");
-
- // Godawful Model MBeans...
- ModelMBeanOperationInfo mmboi = new ModelMBeanOperationInfo(
- "say hello to the nice man", Wrapped.class.getMethod("sayHello"));
- ModelMBeanInfo visibleMmbi = new ModelMBeanInfoSupport(
- Wrapped.class.getName(), "Visible wrapped", null, null,
- new ModelMBeanOperationInfo[] {mmboi}, null);
- ModelMBeanInfo invisibleMmbi = new ModelMBeanInfoSupport(
- Wrapped.class.getName(), "Invisible wrapped", null, null,
- new ModelMBeanOperationInfo[] {mmboi}, null);
- RequiredModelMBean visibleRmmb = new RequiredModelMBean(visibleMmbi);
- RequiredModelMBean invisibleRmmb = new RequiredModelMBean(invisibleMmbi);
- visibleRmmb.setManagedResource(resource, "VisibleObjectReference");
- invisibleRmmb.setManagedResource(resource, "ObjectReference");
-
- mbs.registerMBean(visibleRmmb, visibleName);
- mbs.registerMBean(invisibleRmmb, invisibleName);
-
- assertEquals("ClassLoader for visible wrapped",
- Wrapped.class.getClassLoader(),
- mbs.getClassLoaderFor(visibleName));
- assertEquals("ClassLoader for invisible wrapped",
- StandardMBean.class.getClassLoader(),
- mbs.getClassLoaderFor(invisibleName));
-
- assertEquals("isInstanceOf(WrappedMBean) for visible resource",
- true, mbs.isInstanceOf(visibleName, WrappedMBean.class.getName()));
- assertEquals("isInstanceOf(WrappedMBean) for invisible resource",
- false, mbs.isInstanceOf(invisibleName, WrappedMBean.class.getName()));
- assertEquals("isInstanceOf(RequiredModelMBean) for visible resource",
- false, mbs.isInstanceOf(visibleName, RequiredModelMBean.class.getName()));
- assertEquals("isInstanceOf(RequiredModelMBean) for invisible resource",
- true, mbs.isInstanceOf(invisibleName, RequiredModelMBean.class.getName()));
-
- mbs.unregisterMBean(visibleName);
- mbs.unregisterMBean(invisibleName);
- }
-
- private static enum WrapType {
- NBS("NotificationBroadcasterSupport"),
- INJ("@Resource SendNotification"),
- STD_MBEAN_NBS("StandardMBean delegating to NotificationBroadcasterSupport"),
- STD_MBEAN_INJ("StandardMBean delegating to @Resource SendNotification"),
- STD_MBEAN_SUB_NBS("StandardMBean subclass implementing NotificationBroadcaster"),
- STD_MBEAN_SUB_INJ("StandardMBean subclass with @Resource SendNotification"),
- STD_EMIT_MBEAN_NBS("StandardEmitterMBean delegating to NotificationBroadcasterSupport"),
- STD_EMIT_MBEAN_INJ("StandardEmitterMBean delegating to @Resource SendNotification"),
- STD_EMIT_MBEAN_SUB("StandardEmitterMBean subclass"),
- STD_EMIT_MBEAN_SUB_INJ("StandardEmitterMBean subclass with @Resource SendNotification");
-
- WrapType(String s) {
- this.s = s;
- }
-
- @Override
- public String toString() {
- return s;
- }
-
- private final String s;
- }
-
- @NotificationInfo(
- types = {"foo", "bar"}
- )
- public static interface BroadcasterMBean {
- public void send(Notification n);
- }
-
- public static class Broadcaster
- extends NotificationBroadcasterSupport implements BroadcasterMBean {
- public void send(Notification n) {
- super.sendNotification(n);
- }
- }
-
- public static interface SendNotifMBean extends BroadcasterMBean {
- }
-
- public static class SendNotif implements SendNotifMBean {
- @Resource
- private volatile SendNotification sendNotif;
-
- public void send(Notification n) {
- sendNotif.sendNotification(n);
- }
- }
-
- public static class StdBroadcaster
- extends StandardMBean
- implements BroadcasterMBean, NotificationBroadcaster {
- private final NotificationBroadcasterSupport nbs =
- new NotificationBroadcasterSupport();
-
- public StdBroadcaster() throws Exception {
- super(BroadcasterMBean.class);
- }
-
- public void send(Notification n) {
- nbs.sendNotification(n);
- }
-
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback) {
- nbs.addNotificationListener(listener, filter, handback);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return null;
- }
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- nbs.removeNotificationListener(listener);
- }
- }
-
- public static class StdSendNotif
- extends StandardMBean implements SendNotifMBean {
- @Resource
- private volatile SendNotification sendNotif;
-
- public StdSendNotif() throws Exception {
- super(SendNotifMBean.class);
- }
-
- public void send(Notification n) {
- sendNotif.sendNotification(n);
- }
- }
-
- public static class StdEmitterBroadcaster // :-)
- extends StandardEmitterMBean
- implements BroadcasterMBean {
-
- public StdEmitterBroadcaster() throws Exception {
- super(BroadcasterMBean.class, null);
- }
-
- public void send(Notification n) {
- super.sendNotification(n);
- }
- }
-
- // This case is unlikely - if you're using @Resource SendNotification
- // then there's no point in using StandardEmitterMBean, since
- // StandardMBean would suffice.
- public static class StdEmitterSendNotif
- extends StandardEmitterMBean implements SendNotifMBean {
- @Resource
- private volatile SendNotification sendNotif;
-
- public StdEmitterSendNotif() {
- super(SendNotifMBean.class, null);
- }
-
- public void send(Notification n) {
- sendNotif.sendNotification(n);
- }
- }
-
- // Test that JMX.isNotificationSource and
- // mbs.isInstanceOf("NotificationBroadcaster") work correctly even when
- // the MBean is a broadcaster by virtue of its wrapped resource.
- // Test that we find the MBeanNotificationInfo[] from the @NotificationInfo
- // annotation on BroadcasterMBean. We cover a large number of different
- // MBean types, but all ultimately implement that interface.
- private static void notifTest() throws Exception {
- System.out.println("===Testing notification senders===");
-
- for (WrapType wrapType : WrapType.values()) {
- System.out.println("---" + wrapType);
-
- final Object mbean;
-
- switch (wrapType) {
- case NBS:
- // An MBean that extends NotificationBroadcasterSupport
- mbean = new Broadcaster();
- break;
- case INJ:
- // An MBean that injects SendNotification
- mbean = new SendNotif();
- break;
- case STD_MBEAN_NBS:
- // A StandardMBean that delegates to a NotificationBroadcasterSupport
- mbean = new StandardMBean(
- new Broadcaster(), BroadcasterMBean.class, wrappedVisOpts);
- break;
- case STD_MBEAN_INJ:
- // A StandardMBean that delegates to an object that injects
- // SendNotification
- mbean = new StandardMBean(
- new SendNotif(), BroadcasterMBean.class, wrappedVisOpts);
- break;
- case STD_EMIT_MBEAN_NBS: {
- // A StandardEmitterMBean that delegates to a NotificationBroadcasterSupport
- Broadcaster broadcaster = new Broadcaster();
- mbean = new StandardEmitterMBean(
- broadcaster, BroadcasterMBean.class, wrappedVisOpts,
- broadcaster);
- break;
- }
- case STD_EMIT_MBEAN_INJ: {
- // A StandardEmitterMBean that delegates to an object that injects
- // SendNotification
- SendNotif sendNotif = new SendNotif();
- mbean = new StandardEmitterMBean(
- sendNotif, BroadcasterMBean.class, wrappedVisOpts,
- null);
- break;
- }
- case STD_MBEAN_SUB_NBS:
- // A subclass of StandardMBean that implements NotificationBroadcaster
- mbean = new StdBroadcaster();
- break;
- case STD_MBEAN_SUB_INJ:
- // A subclass of StandardMBean that injects SendNotification
- mbean = new StdSendNotif();
- break;
- case STD_EMIT_MBEAN_SUB:
- // A subclass of StandardEmitterMBean
- mbean = new StdEmitterBroadcaster();
- break;
- case STD_EMIT_MBEAN_SUB_INJ:
- // A subclass of StandardEmitterMBean that injects SendNotification
- // (which is a rather strange thing to do and probably a user
- // misunderstanding but we should do the right thing anyway).
- mbean = new StdEmitterSendNotif();
- break;
- default:
- throw new AssertionError();
- }
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-
- final ObjectName name = new ObjectName("a:type=Sender");
- mbs.registerMBean(mbean, name);
- boolean isBroadcaster = mbs.isInstanceOf(
- name, NotificationBroadcaster.class.getName());
- assertEquals("JMX.isNotificationSource(mbean)",
- true, JMX.isNotificationSource(mbean));
- assertEquals("isInstanceOf(NotificationBroadcaster)",
- true, isBroadcaster);
- MBeanNotificationInfo[] mbnis =
- mbs.getMBeanInfo(name).getNotifications();
- assertEquals("MBeanNotificationInfo not empty",
- true, (mbnis.length > 0));
-
- mbs.unregisterMBean(name);
- }
- }
-
- private static void assertEquals(String what, Object expect, Object actual) {
- if (equal(expect, actual))
- System.out.println("OK: " + what + " = " + expect);
- else
- fail(what + " should be " + expect + ", is " + actual);
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- return x.equals(y);
- }
-
- private static void fail(String why) {
- failure = why;
- System.out.println("FAIL: " + why);
- }
-}
--- a/jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6669137
- * @summary Test the constructors of InstanceNotFoundExceptionTest.
- * @author Daniel Fuchs
- * @compile InstanceNotFoundExceptionTest.java
- * @run main InstanceNotFoundExceptionTest
- */
-
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-
-public class InstanceNotFoundExceptionTest {
- public static void main(String[] args) throws Exception {
- final InstanceNotFoundException x =
- new InstanceNotFoundException();
- System.out.println("InstanceNotFoundException(): "+x.getMessage());
-
- final String msg = "who is toto?";
- final InstanceNotFoundException x2 =
- new InstanceNotFoundException(msg);
- if (!msg.equals(x2.getMessage()))
- throw new Exception("Bad message: expected "+msg+
- ", got "+x2.getMessage());
- System.out.println("InstanceNotFoundException(" +
- msg+"): "+x2.getMessage());
-
- final InstanceNotFoundException x3 =
- new InstanceNotFoundException((String)null);
- if (x3.getMessage() != null)
- throw new Exception("Bad message: expected "+null+
- ", got "+x3.getMessage());
- System.out.println("InstanceNotFoundException((String)null): "+
- x3.getMessage());
-
- final ObjectName n = new ObjectName("who is toto?:type=msg");
- final InstanceNotFoundException x4 =
- new InstanceNotFoundException(n);
- if (!String.valueOf(n).equals(x4.getMessage()))
- throw new Exception("Bad message: expected "+n+
- ", got "+x4.getMessage());
- System.out.println("InstanceNotFoundException(" +
- n+"): "+x4.getMessage());
-
- final InstanceNotFoundException x5 =
- new InstanceNotFoundException((ObjectName)null);
- if (!String.valueOf((ObjectName)null).equals(x5.getMessage()))
- throw new Exception("Bad message: expected " +
- String.valueOf((ObjectName)null)+" got "+x5.getMessage());
- System.out.println("InstanceNotFoundException((ObjectName)null): "+
- x5.getMessage());
- }
-}
--- a/jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -34,8 +34,16 @@
import java.util.Collections;
import java.util.Set;
-import javax.management.*;
-import javax.management.namespace.MBeanServerSupport;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.RuntimeMBeanException;
+import javax.management.StandardMBean;
public class MBeanExceptionTest {
public static void main(String[] args) throws Exception {
@@ -62,46 +70,41 @@
final boolean[] booleans = {false, true};
- for (boolean mbss : booleans) {
- for (boolean runtimeX : booleans) {
- Class<? extends Exception> excC =
- runtimeX ? RuntimeMBeanException.class : MBeanException.class;
- String excS =
- runtimeX ? "a RuntimeMBeanException" : "an MBeanException";
- String mbsS =
- mbss ? "a conformant MBeanServerSupport" : "a plain MBeanServer";
- MBeanServer xmbs =
- mbss ? new CreateExceptionMBS() : mbs;
+ for (boolean runtimeX : booleans) {
+ Class<? extends Exception> excC =
+ runtimeX ? RuntimeMBeanException.class : MBeanException.class;
+ String excS =
+ runtimeX ? "a RuntimeMBeanException" : "an MBeanException";
+ String mbsS = "a plain MBeanServer";
+ System.out.println(
+ "Test that, with " + mbsS + ", " + excS + " is wrapped " +
+ "in " + excS);
+ // E.g. "Test that, with a plain MBeanServer, an MBeanException
+ // is wrapped in an MBeanException".
+ try {
+ mbs.createMBean(
+ Except.class.getName(), new ObjectName(":name=Oops"),
+ new Object[] {runtimeX},
+ new String[] {boolean.class.getName()});
System.out.println(
- "Test that, with " + mbsS + ", " + excS + " is wrapped " +
- "in " + excS);
- // E.g. "Test that, with a plain MBeanServer, an MBeanException
- // is wrapped in an MBeanException".
- try {
- mbs.createMBean(
- Except.class.getName(), new ObjectName(":name=Oops"),
- new Object[] {runtimeX},
- new String[] {boolean.class.getName()});
+ "FAIL: createMBean succeeded but should not have");
+ failures++;
+ } catch (Exception e) {
+ if (!excC.isInstance(e)) {
System.out.println(
- "FAIL: createMBean succeeded but should not have");
+ "FAIL: expected " + excC.getName() + " from " +
+ "createMBean, got " + e);
failures++;
- } catch (Exception e) {
- if (!excC.isInstance(e)) {
+ } else {
+ Throwable cause = e.getCause();
+ if (!excC.isInstance(cause)) {
System.out.println(
- "FAIL: expected " + excC.getName() + " from " +
- "createMBean, got " + e);
+ "FAIL: expected " + excC.getName() +
+ " as cause of " + excC.getName() +
+ ", got " + e);
failures++;
- } else {
- Throwable cause = e.getCause();
- if (!excC.isInstance(cause)) {
- System.out.println(
- "FAIL: expected " + excC.getName() +
- " as cause of " + excC.getName() +
- ", got " + e);
- failures++;
- } else
- System.out.println("...ok");
- }
+ } else
+ System.out.println("...ok");
}
}
}
@@ -280,28 +283,4 @@
private static final RuntimeException theUncheckedException =
new UnsupportedOperationException("The unchecked exception " +
"that should be seen");
-
- private static class CreateExceptionMBS extends MBeanServerSupport {
- @Override
- protected Set<ObjectName> getNames() {
- return Collections.emptySet();
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- public ObjectInstance createMBean(String className,
- ObjectName name, ObjectName loaderName, Object[] params,
- String[] signature, boolean useCLR)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- Exception wrapped = new MBeanException(new Exception(), "Bang");
- throw new MBeanException(wrapped, "Bang");
- }
- }
}
--- a/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,441 +0,0 @@
-/*
- * Copyright 2003-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.
- *
- * 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.
- */
-
-/*
- * @test
- * @summary Test named MBeanServers.
- * @author Daniel Fuchs
- * @bug 6299231
- * @run clean NamedMBeanServerTest
- * @run build NamedMBeanServerTest
- * @run main NamedMBeanServerTest
- */
-
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerBuilder;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerFactory;
-
-/**
- * This test can probably be leveraged in the JCK to test compatibilty
- * of MBeanServerFactory *Name* method implementation.
- * @author dfuchs
- */
-public class NamedMBeanServerTest {
-
- /**
- * One enum value for each way of creating an MBeanServer through the
- * MBeanServerFactory
- */
- public static enum Creator {
- newMBeanServer() {
- public MBeanServer create(String domain) {
- return MBeanServerFactory.newMBeanServer(domain);
- }
- public String test(MBeanServer server, String domain) {
- System.out.println(toString()+"("+domain+")");
- return test(server,
- MBeanServerFactory.DEFAULT_MBEANSERVER_NAME,
- domain);
- }
- public MBeanServer[] servers(Config config) {
- return config.ndServers;
- }
- public String[] strings(Config config) {
- return domains(config);
- }
- public String[] domains(Config config) {
- return config.newDomains;
- }
- public String[] names(Config config) {
- return null;
- }
- },
- createMBeanServer() {
- public MBeanServer create(String domain) {
- return MBeanServerFactory.createMBeanServer(domain);
- }
- public String test(MBeanServer server, String domain) {
- System.out.println(toString()+"("+domain+")");
- return test(server,MBeanServerFactory.DEFAULT_MBEANSERVER_NAME,
- domain);
- }
- public MBeanServer[] servers(Config config) {
- return config.cdServers;
- }
- public String[] strings(Config config) {
- return domains(config);
- }
- public String[] domains(Config config) {
- return config.createDomains;
- }
- public String[] names(Config config) {
- return null;
- }
- },
- newNamedMBeanServer() {
- public MBeanServer create(String name) {
- return MBeanServerFactory.newNamedMBeanServer(name,null);
- }
- public String test(MBeanServer server, String name) {
- System.out.println(toString()+"("+name+",null)");
- return test(server,name,"DefaultDomain");
- }
- public MBeanServer[] servers(Config config) {
- return config.nnServers;
- }
- public String[] strings(Config config) {
- return names(config);
- }
- public String[] domains(Config config) {
- return null;
- }
- public String[] names(Config config) {
- return config.newNames;
- }
- },
- createNamedMBeanServer() {
- public MBeanServer create(String name) {
- return MBeanServerFactory.createNamedMBeanServer(name,null);
- }
- public String test(MBeanServer server, String name) {
- System.out.println(toString()+"("+name+",null)");
- return test(server,name,"DefaultDomain");
- }
- public MBeanServer[] servers(Config config) {
- return config.cnServers;
- }
- public String[] strings(Config config) {
- return names(config);
- }
- public String[] domains(Config config) {
- return null;
- }
- public String[] names(Config config) {
- return config.createNames;
- }
- };
-
- // creates an MBeanServer using the specified input string.
- // either a domain, (for UNNAMED) or a mbeanServerName (for NAMED)
- public abstract MBeanServer create(String string);
-
- // test the created server against the string used as input to create
- // it.
- public abstract String test(MBeanServer server, String ref);
-
- public abstract MBeanServer[] servers(Config config);
- public abstract String[] strings(Config config);
- public abstract String[] names(Config config);
- public abstract String[] domains(Config config);
-
- public MBeanServer[] servers(Config config, String... refs) {
- final MBeanServer[] servers = servers(config);
- final String[] strings = strings(config);
- final MBeanServer[] res = new MBeanServer[refs.length];
- for (int i=0;i<refs.length;i++) {
- for (int j=0;j<strings.length;j++) {
- if (strings[j].equals(refs[i]))
- res[i]=servers[j];
- }
- if (res[i] == null)
- throw new IllegalArgumentException(refs[i]);
- }
- return res;
- }
-
- String test(MBeanServer server, String name, String domain) {
- // whether the MBeanServer was created throug a "create" method
- boolean registered = REFERENCED.contains(this);
- if (!server.getDefaultDomain().equals(domain)) {
- return "Unexpected default domain: " +
- server.getDefaultDomain() + ", should be: " + domain;
- }
- if (!MBeanServerFactory.getMBeanServerName(server).
- equals(name)) {
- return " Unexpected name: " +
- MBeanServerFactory.getMBeanServerName(server) +
- ", should be: " + name;
- }
- List<MBeanServer> found =
- MBeanServerFactory.findMBeanServerByName(name);
- if (!registered && found.contains(server))
- return " Server "+name+" found by name - " +
- "but should not be registered";
- if (!registered &&
- !name.equals(MBeanServerFactory.DEFAULT_MBEANSERVER_NAME) &&
- found.size()>0)
- return " Server "+name+" had too many matches: " + found.size();
- if (registered && !found.contains(server))
- return " Server "+name+" not found by name - " +
- "but is registered!";
- if (registered &&
- !name.equals(MBeanServerFactory.DEFAULT_MBEANSERVER_NAME) &&
- !(found.size()==1))
- return " Server "+name+" had too many matches: " + found.size();
- return null;
- }
-
- public static final EnumSet<Creator> NAMED =
- EnumSet.of(createNamedMBeanServer, newNamedMBeanServer);
- public static final EnumSet<Creator> UNNAMED =
- EnumSet.complementOf(NAMED);
- public static final EnumSet<Creator> REFERENCED =
- EnumSet.of(createMBeanServer, createNamedMBeanServer);
- public static final EnumSet<Creator> UNREFERENCED =
- EnumSet.complementOf(REFERENCED);
-
- }
-
- public static class Config {
- final String[] newDomains;
- final String[] createDomains;
- final String[] newNames;
- final String[] createNames;
- final MBeanServer[] ndServers;
- final MBeanServer[] cdServers;
- final MBeanServer[] nnServers;
- final MBeanServer[] cnServers;
- final Map<String,Set<MBeanServer>> queries;
- Config(String[][] data) {
- this(data[0],data[1],data[2],data[3]);
- }
- Config(String[] nd, String[] cd, String[] nn, String[] cn) {
- this.newDomains=nd.clone();
- this.createDomains=cd.clone();
- this.newNames=nn.clone();
- this.createNames=cn.clone();
- ndServers = new MBeanServer[nd.length];
- cdServers = new MBeanServer[cd.length];
- nnServers = new MBeanServer[nn.length];
- cnServers = new MBeanServer[cn.length];
- queries = new HashMap<String,Set<MBeanServer>>();
- init();
- }
- private void init() {
- for (Creator c : Creator.values()) fill(c);
- addQuery(null,Creator.createMBeanServer.servers(this));
- addQuery(null,Creator.createNamedMBeanServer.servers(this));
- addQuery("?*",Creator.createMBeanServer.servers(this));
- addQuery("?*",Creator.createNamedMBeanServer.servers(this));
- addQuery("*",Creator.createMBeanServer.servers(this));
- addQuery("*",Creator.createNamedMBeanServer.servers(this));
- addQuery(MBeanServerFactory.DEFAULT_MBEANSERVER_NAME,
- Creator.createMBeanServer.servers(this));
- }
- private void addQuery(String pattern, MBeanServer... servers) {
- final Set<MBeanServer> s = getQuery(pattern);
- s.addAll(Arrays.asList(servers));
- }
- public Set<MBeanServer> getQuery(String pattern) {
- final Set<MBeanServer> s = queries.get(pattern);
- if (s != null) return s;
- queries.put(pattern,new HashSet<MBeanServer>());
- return queries.get(pattern);
- }
- public Set<String> getPatterns() {
- return queries.keySet();
- }
- private void fill(Creator creator) {
- fill(creator.servers(this),creator.strings(this),creator);
- }
- private void fill(MBeanServer[] dest, String[] src, Creator creator) {
- for(int i=0;i<src.length;i++) dest[i]=creator.create(src[i]);
- }
-
- }
-
- static String[] domains(String... str) {
- return str;
- }
- static String[] names(String... str) {
- return str;
- }
- final static Config test1 = new Config(domains("foo1","foo2","foo3"),
- domains("foobar1","foobar2","foobar3","foobar4"),
- names("bar1","bar2"),
- names("barfoo1","barfoo2","barfoo3","batfox1","catfog2","foofoo3"));
- static {
- test1.addQuery("b*",Creator.createNamedMBeanServer.servers(test1,
- "barfoo1","barfoo2","barfoo3","batfox1"));
- test1.addQuery("*arf*",Creator.createNamedMBeanServer.servers(test1,
- "barfoo1","barfoo2","barfoo3"));
- test1.addQuery("*a?f*",Creator.createNamedMBeanServer.servers(test1,
- "barfoo1","barfoo2","barfoo3","batfox1","catfog2"));
- test1.addQuery("",new MBeanServer[0]);
- test1.addQuery("-",new MBeanServer[0]);
- test1.addQuery("def*",Creator.createMBeanServer.servers(test1));
- }
-
- public static void test(Config config) throws Exception {
- for (Creator c : Creator.values()) {
- final MBeanServer[] s = c.servers(config);
- final String[] ref = c.strings(config);
- for (int i=0;i<s.length;i++) {
- final String msg = c.test(s[i], ref[i]);
- if (msg != null)
- throw new Exception(String.valueOf(c)+"["+i+"]: "+msg);
- }
- }
- for (String pat : config.getPatterns()) {
- System.out.print("findMBeanServerByName(\""+pat+"\"): [");
- final List<MBeanServer> found =
- MBeanServerFactory.findMBeanServerByName(pat);
- String sep=" ";
- for (MBeanServer m : found) {
- System.out.print(sep+MBeanServerFactory.getMBeanServerName(m));
- sep=", ";
- }
- System.out.println(" ]");
- final Set<MBeanServer> founds = new HashSet<MBeanServer>();
- founds.addAll(found);
- if (!founds.equals(config.getQuery(pat))) {
- final String msg =
- "bad result for findMBeanServerByName(\""+
- pat+"\"): expected "+config.getQuery(pat).size()+", "+
- "got "+founds.size();
- throw new Exception(msg);
- }
- }
- }
-
- public static void testexception(Creator c, String name,
- Class<? extends Exception> error) throws Exception {
- Exception failed = null;
- MBeanServer server = null;
- try {
- server = c.create(name);
- } catch (Exception x) {
- failed = x;
- } finally {
- if (Creator.REFERENCED.contains(c) && server!=null) {
- MBeanServerFactory.releaseMBeanServer(server);
- }
- }
- if (failed == null && error != null) {
- throw new Exception("Expected "+error.getName()+
- " for "+c+"("+name+")");
- }
- if (error != null && !error.isInstance(failed))
- throw new Exception("Expected "+error.getName()+
- " for "+c+"("+name+"), caught "+failed);
- System.out.println(""+c+"("+name+") PASSED: "+
- (failed==null?"no exception":String.valueOf(failed)));
- }
-
- private static final Map<String,Class<? extends Exception>> failures =
- new LinkedHashMap<String,Class<? extends Exception>>();
- private static final Map<String,Class<? extends Exception>> legacy =
- new LinkedHashMap<String,Class<? extends Exception>>();
- private static final String[] illegalnames = {
- "", "-", ":", ";", "?", "*", "wom?bat", "ran:tan.plan",
- "rin;tin.tin", "tab*mow"
-
- };
- private static final String[] legalnames = {
- "wombat", "top.tip", "ran.tan.plan", "rin.tin.tin!"
- };
- private static final String[] nofailures = {
- MBeanServerFactory.DEFAULT_MBEANSERVER_NAME, "default", null
- };
- static {
- for (String s:illegalnames)
- failures.put(s, IllegalArgumentException.class);
- for (String s:nofailures)
- failures.put(s, null);
- legacy.putAll(failures);
- for (String s:legalnames)
- legacy.put(s, UnsupportedOperationException.class);
-
- }
-
- public static void test2(Map<String,Class<? extends Exception>> config)
- throws Exception {
- for (Creator c:Creator.NAMED) {
- for (String s:config.keySet()) testexception(c, s, config.get(s));
- }
- }
-
- public static class LegacyBuilder extends MBeanServerBuilder {
-
- @Override
- public MBeanServerDelegate newMBeanServerDelegate() {
- return new MBeanServerDelegate() {
- @Override
- public synchronized String getMBeanServerId() {
- return "gloups";
- }
- };
- }
-
- }
- public static class LegacyBuilder2 extends MBeanServerBuilder {
-
- @Override
- public MBeanServerDelegate newMBeanServerDelegate() {
- return new MBeanServerDelegate() {
- @Override
- public synchronized String getMBeanServerId() {
- return "c'est la vie...";
- }
- @Override
- public synchronized void setMBeanServerName(String name) {
- }
-
- };
- }
-
- }
-
- public static void test3(Map<String,Class<? extends Exception>> config,
- String builderClassName)
- throws Exception {
- final String builder =
- System.getProperty("javax.management.builder.initial");
- System.setProperty("javax.management.builder.initial",
- builderClassName);
- try {
- test2(config);
- } finally {
- if (builder != null)
- System.setProperty("javax.management.builder.initial", builder);
- else
- System.clearProperty("javax.management.builder.initial");
- }
- }
-
- public static void main(String[] args) throws Exception {
- test(test1);
- test2(failures);
- test3(legacy,LegacyBuilder.class.getName());
- test3(legacy,LegacyBuilder2.class.getName());
- }
-}
--- a/jdk/test/javax/management/ObjectName/ApplyWildcardTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/ObjectName/ApplyWildcardTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005 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
@@ -28,13 +28,10 @@
* with wildcards in the key properties value part.
* @author Luis-Miguel Alventosa
* @run clean ApplyWildcardTest
- * @compile -XDignore.symbol.file=true ApplyWildcardTest.java
* @run build ApplyWildcardTest
* @run main ApplyWildcardTest
*/
-import com.sun.jmx.mbeanserver.Repository;
-import com.sun.jmx.mbeanserver.Util;
import javax.management.ObjectName;
public class ApplyWildcardTest {
@@ -77,75 +74,6 @@
{ "d:k1=\"a?b\",k2=\"c*d\"", "d:k1=\"axb\",k2=\"cyzd\"" },
{ "d:k1=\"a?b\",k2=\"c*d\",*", "d:k1=\"axb\",k2=\"cyzd\",k3=\"v3\"" },
{ "d:*,k1=\"a?b\",k2=\"c*d\"", "d:k1=\"axb\",k2=\"cyzd\",k3=\"v3\"" },
-
- // with namespaces
-
- { "*//:*", "d//:k=v" },
- { "//?:*", "///:k=v" },
- { "z*x//:*", "zaxcx//:k=v" },
- { "*//:*", "d/xx/q//:k=v" },
- { "z*x//:*", "z/a/x/c/x//:k=v" },
- { "*x?//:*", "dbdbdxk//:k=v" },
- { "z*x?x//:*", "zaxcx//:k=v" },
- { "*x?f//:*", "d/xxf/qxbf//:k=v" },
- { "z*x?c*x//:*", "z/a/x/c/x//:k=v" },
-
- { "*//*:*", "d/c/v//x/vgh/:k=v" },
- { "z*x//z*x:*", "zaxcx//zaxcxcx:k=v" },
- { "//*//:*", "//d/xx/q//:k=v" },
- { "z*//*//:*", "z/x/x/z//z/a/x/c/x//:k=v" },
- { "*x?//blur?g*:*", "dbdbdxk//blurhgblurgh/x/:k=v" },
- { "z*x??x//??:*", "zaxcxccx///.:k=v" },
- { "*x?f//?:*", "d/xxf/qxbf///:k=v" },
- { "z*x?c*x//*//z????//g:*", "z/a/x/c/x//gloubs/././/zargh//g:k=v" },
- { "z*x?c*x//*//:*", "z/a/x/c/x//gloubs/././/:k=v"},
- { "*//*//:*", "aza//bzb//:k=v" },
- { "*//:*", "aza//:k=v" },
-
- // with or without namespaces, * can also match nothing
- { "x*z:*", "xz:k=v"},
-
- { "*//:*", "//:k=v" },
- { "z*x//:*", "zx//:k=v" },
- { "*x?//:*", "xk//:k=v" },
- { "z*x?x//:*", "zxcx//:k=v" },
- { "*x?f//:*", "xbf//:k=v" },
- { "z*x?c*x//:*", "zx/cx//:k=v" },
-
- { "*//*:*", "//:k=v" },
- { "z*x//z*x:*", "zx//zx:k=v" },
- { "//*//:*", "////:k=v" },
- { "z*//*//:*", "z////:k=v" },
- { "*x?//blur?g*:*", "xk//blurhg:k=v" },
- { "z*x??x//??:*", "zxccx///.:k=v" },
- { "*x?f//?:*", "xbf///:k=v" },
- { "z*x?c*x//*//z????//g:*", "zx/cx////zargh//g:k=v" },
- { "z*x?c*x//*//:*", "zx/cx////:k=v"},
- { "*//*//:*", "////:k=v" },
- { "*//:*", "//:k=v" },
-
- // recursive namespace meta-wildcard
- {"**//D:k=v", "a//D:k=v"},
- {"**//D:k=v", "a//b//c//D:k=v"},
- {"a//**//D:k=v", "a//b//c//D:k=v"},
- {"a//**//d//D:k=v", "a//b//c//d//D:k=v"},
- {"a//**//d//D:k=v", "a//b//c//d//d//D:k=v"},
- {"a//**//d//D:k=v", "a//a//b//c//d//d//D:k=v"},
- {"a//**//d//**//e//D:k=v", "a//a//b//d//c//d//e//D:k=v"},
-
- // special cases for names ending with //
- { "*:*", "d//:k=v" },
- { "z*x*:*", "zaxcx//:k=v" },
- { "*:*", "d/xx/q//:k=v" },
- { "z*x??:*", "z/a/x/c/x//:k=v" },
- { "*x???:*", "dbdbdxk//:k=v" },
- { "z*x?c*x*:*", "z/a/x/c/x//:k=v" },
- { "?/*/?:*", "d/xx/q//:k=v" },
- { "**//*:*", "a//b//jmx.rmi:k=v"},
- { "**//*:*", "a//b//jmx.rmi//:k=v"},
- { "*//*:*", "wombat//:type=Wombat" },
- { "**//*:*", "jmx.rmi//:k=v"},
-
};
private static final String negativeTests[][] = {
@@ -186,33 +114,6 @@
{ "d:k1=\"a?b\",k2=\"c*d\"", "d:k1=\"ab\",k2=\"cd\"" },
{ "d:k1=\"a?b\",k2=\"c*d\",*", "d:k1=\"ab\",k2=\"cd\",k3=\"v3\"" },
{ "d:*,k1=\"a?b\",k2=\"c*d\"", "d:k1=\"ab\",k2=\"cd\",k3=\"v3\"" },
-
- // with namespaces
-
- { "z*x?x*:*", "zaxcx//blougs:k=v" },
- { "*x?f??rata:*", "d/xxf/qxbf//rata:k=v" },
- { "z*x?c*x*b*:*", "z/a/x/c/x//b//:k=v" },
-
- { "*:*", "d/c/v//x/vgh/:k=v" },
- { "z*x??z*x:*", "zaxcx//zaxcxcx:k=v" },
- { "?/*/?:*", "//d/xx/q//:k=v" },
- { "z*/?*/?:*", "z/x/x/z//z/a/x/c/x//:k=v" },
- { "*x?/?blur?g*:*", "dbdbdxk//blurhgblurgh/x/:k=v" },
- { "z*x??x/???:*", "zaxcxccx///.:k=v" },
- { "*x?f?/?:*", "d/xxf/qxbf///:k=v" },
- { "z*x?c*x/?*z????*g:*", "z/a/x/c/x//gloubs/././/zargh//g:k=v" },
-
- // recursive namespace meta-wildcard
- {"**//D:k=v", "D:k=v"},
- {"b//**//D:k=v", "a//b//c//D:k=v"},
- {"a//**//D:k=v", "a//D:k=v"},
- {"a//**//d//D:k=v", "a//b//c//d//e//D:k=v"},
- {"a//**//d//D:k=v", "a//b//c//D:k=v"},
- {"a//**//d//D:k=v", "a//b//c//d//d//e//D:k=v"},
- {"a//**//d//**//e//D:k=v", "a//a//b//c//d//e//D:k=v"},
- {"a//**//d//**//e//D:k=v", "a//a//b//c//e//D:k=v"},
- { "**//*:*", "jmx.rmi:k=v"},
-
};
private static int runPositiveTests() {
@@ -228,8 +129,6 @@
if (result == false) {
error++;
System.out.println("Test failed!");
- throw new Error("test failed for "+
- "\"" + on1 + "\".apply(\"" + on2 + "\")");
} else {
System.out.println("Test passed!");
}
@@ -269,85 +168,10 @@
return error;
}
- private static int runRepositoryPositiveTests() {
- int error = 0;
- for (int i = 0; i < positiveTests.length; i++) {
- try {
- ObjectName on1 = ObjectName.getInstance(positiveTests[i][0]);
- ObjectName on2 = ObjectName.getInstance(positiveTests[i][1]);
- if (on1.isPropertyPattern()) {
- if (!on1.getKeyPropertyListString().equals("")) continue;
- } else if (!on1.getCanonicalKeyPropertyListString()
- .equals(on2.getCanonicalKeyPropertyListString())) {
- continue;
- }
- System.out.println("Repository Positive Match Test ---------------");
- final String dom1 = on1.getDomain();
- final String dom2 = on2.getDomain();
- System.out.println("Util.wildpathmatch(\"" + dom2 + "\",\"" + dom1 + "\")");
- boolean result =
- Util.wildpathmatch(dom2,dom1);
- System.out.println("Result = " + result);
- if (result == false) {
- error++;
- System.out.println("Test failed!");
- } else {
- System.out.println("Test passed!");
- }
- } catch (Exception e) {
- error++;
- System.out.println("Got Unexpected Exception = " + e.toString());
- System.out.println("Test failed!");
- }
- System.out.println("----------------------------------------------");
- }
- return error;
- }
-
- private static int runRepositoryNegativeTests() {
- int error = 0;
- for (int i = 0; i < negativeTests.length; i++) {
- try {
- ObjectName on1 = ObjectName.getInstance(negativeTests[i][0]);
- ObjectName on2 = ObjectName.getInstance(negativeTests[i][1]);
- if (on1.isPropertyPattern()) {
- if (!on1.getKeyPropertyListString().equals("")) continue;
- } else if (!on1.getCanonicalKeyPropertyListString()
- .equals(on2.getCanonicalKeyPropertyListString())) {
- continue;
- }
- System.out.println("Repository Negative Match Test ---------------");
- final String dom1 = on1.getDomain();
- final String dom2 = on2.getDomain();
- System.out.println("Util.wildpathmatch(\"" + dom2 + "\",\"" + dom1 + "\")");
- boolean result =
- Util.wildpathmatch(dom2,dom1);
- System.out.println("Result = " + result);
- if (result == true) {
- error++;
- System.out.println("Test failed!");
- } else {
- System.out.println("Test passed!");
- }
- } catch (Exception e) {
- error++;
- System.out.println("Got Unexpected Exception = " + e.toString());
- System.out.println("Test failed!");
- }
- System.out.println("----------------------------------------------");
- }
- return error;
- }
-
public static void main(String[] args) throws Exception {
-
int error = 0;
- if (!(new ObjectName("z*x*:*").apply(new ObjectName("zaxcx//:k=v"))))
- throw new Exception();
-
-
// Check null values
//
System.out.println("----------------------------------------------");
@@ -429,10 +253,6 @@
error += runPositiveTests();
error += runNegativeTests();
- System.out.println("----------------------------------------------");
- error += runRepositoryPositiveTests();
- System.out.println("----------------------------------------------");
- error += runRepositoryNegativeTests();
if (error > 0) {
final String msg = "Test FAILED! Got " + error + " error(s)";
--- a/jdk/test/javax/management/ObjectName/ValueOfTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6734813
- * @summary Test the ObjectName.valueOf methods
- * @author Eamonn McManus
- */
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Hashtable;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-public class ValueOfTest {
- public static void main(String[] args) throws Exception {
- // Calls that should work
- testPositive("d:foo=bar,baz=buh");
- testPositive("foo", "bar", "baz");
- Hashtable<String, String> h = new Hashtable<String, String>();
- h.put("foo", "bar");
- h.put("baz", "buh");
- testPositive("domain", h);
-
- // Calls that should not work
- testNegative("d");
- testNegative("d:");
- testNegative("d::foo=bar");
- testNegative("d:", "foo", "bar");
- testNegative("d", "foo=", "bar");
- testNegative("d:", h);
- testNegative("d", new Hashtable<String, String>());
- }
-
- private static void testPositive(Object... args) throws Exception {
- Method valueOf = valueOfMethod(args);
- Method getInstance = getInstanceMethod(args);
- Constructor<?> constructor = constructor(args);
-
- Object valueOfValue = valueOf.invoke(null, args);
- Object getInstanceValue = getInstance.invoke(null, args);
- Object constructorValue = constructor.newInstance(args);
-
- String argString =
- Arrays.toString(args).replace('[', '(').replace(']', ')');
-
- if (!valueOfValue.equals(getInstanceValue)) {
- throw new Exception(
- "valueOf" + argString + " differs from getInstance" +
- argString);
- }
-
- if (!valueOfValue.equals(constructorValue)) {
- throw new Exception(
- "valueOf" + argString + " differs from new ObjectName " +
- argString);
- }
-
- System.out.println("OK: valueOf" + argString);
- }
-
- private static void testNegative(Object... args) throws Exception {
- Method valueOf = valueOfMethod(args);
- Method getInstance = getInstanceMethod(args);
-
- String argString =
- Arrays.toString(args).replace('[', '(').replace(']', ')');
-
- final Throwable valueOfException;
- try {
- valueOf.invoke(null, args);
- throw new Exception("valueOf" + argString + " did not fail but should");
- } catch (InvocationTargetException e) {
- valueOfException = e.getCause();
- }
- if (!(valueOfException instanceof IllegalArgumentException)) {
- throw new Exception(
- "valueOf" + argString + " threw " +
- valueOfException.getClass().getName() + " instead of " +
- "IllegalArgumentException", valueOfException);
- }
-
- final Throwable valueOfCause = valueOfException.getCause();
- if (!(valueOfCause instanceof MalformedObjectNameException)) {
- throw new Exception(
- "valueOf" + argString + " threw exception with wrong " +
- "type of cause", valueOfCause);
- }
-
- if (!valueOfException.getMessage().equals(valueOfCause.getMessage())) {
- // The IllegalArgumentException should have the same message as
- // the MalformedObjectNameException it wraps.
- // This isn't specified but is desirable.
- throw new Exception(
- "valueOf" + argString + ": message in wrapping " +
- "IllegalArgumentException (" + valueOfException.getMessage() +
- ") differs from message in wrapped " +
- "MalformedObjectNameException (" + valueOfCause.getMessage() +
- ")");
- }
-
- final Throwable getInstanceException;
- try {
- getInstance.invoke(null, args);
- throw new Exception("getInstance" + argString + " did not fail but should");
- } catch (InvocationTargetException e) {
- getInstanceException = e.getCause();
- }
- if (!(getInstanceException instanceof MalformedObjectNameException)) {
- throw new Exception(
- "getInstance" + argString + " threw wrong exception",
- getInstanceException);
- }
-
- if (!valueOfException.getMessage().equals(getInstanceException.getMessage())) {
- // Again this is not specified.
- throw new Exception(
- "Exception message from valueOf" + argString + " (" +
- valueOfException.getMessage() + ") differs from message " +
- "from getInstance" + argString + " (" +
- getInstanceException.getMessage() + ")");
- }
-
- System.out.println("OK (correct exception): valueOf" + argString);
- }
-
- private static Method valueOfMethod(Object[] args) throws Exception {
- return method("valueOf", args);
- }
-
- private static Method getInstanceMethod(Object[] args) throws Exception {
- return method("getInstance", args);
- }
-
- private static Method method(String name, Object[] args) throws Exception {
- Class<?>[] argTypes = argTypes(args);
- return ObjectName.class.getMethod(name, argTypes);
- }
-
- private static Constructor<?> constructor(Object[] args) throws Exception {
- Class<?>[] argTypes = argTypes(args);
- return ObjectName.class.getConstructor(argTypes);
- }
-
- private static Class<?>[] argTypes(Object[] args) {
- Class<?>[] argTypes = new Class<?>[args.length];
- for (int i = 0; i < args.length; i++)
- argTypes[i] = args[i].getClass();
- return argTypes;
- }
-}
--- a/jdk/test/javax/management/context/ContextForwarderTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5072267
- * @summary Test that a context forwarder can be created and then installed.
- * @author Eamonn McManus
- */
-
-/* The specific thing we're testing for is that the forwarder can be created
- * with a null "next", and then installed with a real "next". An earlier
- * defect meant that in this case the simulated jmx.context// namespace had a
- * null handler that never changed.
- */
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.management.ClientContext;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-
-public class ContextForwarderTest {
- private static String failure;
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
- Map<String, String> env = new HashMap<String, String>();
- env.put(JMXConnectorServer.CONTEXT_FORWARDER, "false");
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
- url, env, mbs);
- MBeanServerForwarder sysMBSF = cs.getSystemMBeanServerForwarder();
- MBeanServerForwarder mbsf = ClientContext.newContextForwarder(mbs, sysMBSF);
- sysMBSF.setMBeanServer(mbsf);
-
- int localCount = mbs.getMBeanCount();
-
- cs.start();
- try {
- JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress());
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
- mbsc = ClientContext.withContext(mbsc, "foo", "bar");
- int contextCount = mbsc.getMBeanCount();
- if (localCount + 1 != contextCount) {
- fail("Local MBean count %d, context MBean count %d",
- localCount, contextCount);
- }
- Set<ObjectName> localNames =
- new TreeSet<ObjectName>(mbs.queryNames(null, null));
- ObjectName contextNamespaceObjectName =
- new ObjectName(ClientContext.NAMESPACE + "//:type=JMXNamespace");
- if (!localNames.add(contextNamespaceObjectName))
- fail("Local names already contained context namespace handler");
- Set<ObjectName> contextNames = mbsc.queryNames(null, null);
- if (!localNames.equals(contextNames)) {
- fail("Name set differs locally and in context: " +
- "local: %s; context: %s", localNames, contextNames);
- }
- } finally {
- cs.stop();
- }
- if (failure != null)
- throw new Exception("TEST FAILED: " + failure);
- else
- System.out.println("TEST PASSED");
- }
-
- private static void fail(String msg, Object... params) {
- failure = String.format(msg, params);
- System.out.println("FAIL: " + failure);
- }
-}
--- a/jdk/test/javax/management/context/ContextTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,534 +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.
- *
- * 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.
- */
-
-/*
- * @test ContextTest
- * @bug 5072267
- * @summary Test client contexts.
- * @author Eamonn McManus
- * TODO: Try registering with a null name replaced by preRegister (for example
- * from the MLet class) and see if it now works.
- */
-
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.ClientContext;
-import javax.management.DynamicMBean;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerDelegate;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-import javax.management.loading.MLet;
-import javax.management.namespace.JMXNamespace;
-
-import javax.management.remote.MBeanServerForwarder;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
-public class ContextTest {
- private static String failure;
- private static final Map<String, String> emptyContext = emptyMap();
-
- public static interface ShowContextMBean {
- public Map<String, String> getContext();
- public Map<String, String> getCreationContext();
- public Set<String> getCalledOps();
- public String getThing();
- public void setThing(String x);
- public int add(int x, int y);
- }
-
- public static class ShowContext
- extends NotificationBroadcasterSupport
- implements ShowContextMBean, MBeanRegistration {
- private final Map<String, String> creationContext;
- private final Set<String> calledOps = new HashSet<String>();
-
- public ShowContext() {
- creationContext = getContext();
- }
-
- public Map<String, String> getContext() {
- return ClientContext.getContext();
- }
-
- public Map<String, String> getCreationContext() {
- return creationContext;
- }
-
- public Set<String> getCalledOps() {
- return calledOps;
- }
-
- public String getThing() {
- return "x";
- }
-
- public void setThing(String x) {
- }
-
- public int add(int x, int y) {
- return x + y;
- }
-
- public ObjectName preRegister(MBeanServer server, ObjectName name) {
- assertEquals("preRegister context", creationContext, getContext());
- calledOps.add("preRegister");
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- assertEquals("postRegister context", creationContext, getContext());
- calledOps.add("postRegister");
- }
-
- // The condition checked here is not guaranteed universally true,
- // but is true every time we unregister an instance of this MBean
- // in this test.
- public void preDeregister() throws Exception {
- assertEquals("preDeregister context", creationContext, getContext());
- }
-
- public void postDeregister() {
- assertEquals("postDeregister context", creationContext, getContext());
- }
-
- // Same remark as for preDeregister
- @Override
- public MBeanNotificationInfo[] getNotificationInfo() {
- calledOps.add("getNotificationInfo");
- return super.getNotificationInfo();
- }
-
- @Override
- public void addNotificationListener(
- NotificationListener listener, NotificationFilter filter, Object handback) {
- calledOps.add("addNotificationListener");
- super.addNotificationListener(listener, filter, handback);
- }
-
- @Override
- public void removeNotificationListener(
- NotificationListener listener)
- throws ListenerNotFoundException {
- calledOps.add("removeNL1");
- super.removeNotificationListener(listener);
- }
-
- @Override
- public void removeNotificationListener(
- NotificationListener listener, NotificationFilter filter, Object handback)
- throws ListenerNotFoundException {
- calledOps.add("removeNL3");
- super.removeNotificationListener(listener, filter, handback);
- }
- }
-
- private static class LogRecord {
- final String op;
- final Object[] params;
- final Map<String, String> context;
- LogRecord(String op, Object[] params, Map<String, String> context) {
- this.op = op;
- this.params = params;
- this.context = context;
- }
-
- @Override
- public String toString() {
- return op + Arrays.deepToString(params) + " " + context;
- }
- }
-
- /*
- * InvocationHandler that forwards all methods to a contained object
- * but also records each forwarded method. This allows us to check
- * that the appropriate methods were called with the appropriate
- * parameters. It's similar to what's typically available in
- * Mock Object frameworks.
- */
- private static class LogIH implements InvocationHandler {
- private final Object wrapped;
- Queue<LogRecord> log = new LinkedList<LogRecord>();
-
- LogIH(Object wrapped) {
- this.wrapped = wrapped;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (method.getDeclaringClass() != Object.class) {
- LogRecord lr =
- new LogRecord(
- method.getName(), args, ClientContext.getContext());
- log.add(lr);
- }
- try {
- return method.invoke(wrapped, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- }
-
- private static <T> T newSnoop(Class<T> wrappedClass, LogIH logIH) {
- return wrappedClass.cast(Proxy.newProxyInstance(
- wrappedClass.getClassLoader(),
- new Class<?>[] {wrappedClass},
- logIH));
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- System.out.println(mbs.queryNames(null, null));
- ObjectName name = new ObjectName("a:b=c");
- mbs.registerMBean(new ShowContext(), name);
- final ShowContextMBean show =
- JMX.newMBeanProxy(mbs, name, ShowContextMBean.class);
-
- // Test local setting and getting within the MBeanServer
-
- assertEquals("initial context", emptyContext, show.getContext());
- ClientContext.doWithContext(singletonMap("foo", "bar"), new Callable<Void>() {
- public Void call() {
- assertEquals("context in doWithContext",
- singletonMap("foo", "bar"), show.getContext());
- return null;
- }
- });
- assertEquals("initial context after doWithContext",
- emptyContext, show.getContext());
- String got = ClientContext.doWithContext(
- singletonMap("foo", "baz"), new Callable<String>() {
- public String call() {
- return ClientContext.getContext().get("foo");
- }
- });
- assertEquals("value extracted from context", "baz", got);
-
- Map<String, String> combined = ClientContext.doWithContext(
- singletonMap("foo", "baz"), new Callable<Map<String, String>>() {
- public Map<String, String> call() throws Exception {
- return ClientContext.doWithContext(
- singletonMap("fred", "jim"),
- new Callable<Map<String, String>>() {
- public Map<String, String> call() {
- return ClientContext.getContext();
- }
- });
- }
- });
- assertEquals("nested doWithContext context",
- singletonMap("fred", "jim"), combined);
-
- final String ugh = "a!\u00c9//*=:\"% ";
- ClientContext.doWithContext(singletonMap(ugh, ugh), new Callable<Void>() {
- public Void call() {
- assertEquals("context with tricky encoding",
- singletonMap(ugh, ugh), show.getContext());
- return null;
- }
- });
- Map<String, String> ughMap = new TreeMap<String, String>();
- ughMap.put(ugh, ugh);
- ughMap.put("fred", "jim");
- // Since this is a TreeMap and "fred" is greater than ugh (which begins
- // with "a"), we will see the encoding of ugh first in the output string.
- String encoded = ClientContext.encode(ughMap);
- String expectedUghCoding = "a%21%C3%89%2F%2F%2A%3D%3A%22%25+";
- String expectedUghMapCoding =
- ClientContext.NAMESPACE + "//" + expectedUghCoding + "=" +
- expectedUghCoding + ";fred=jim";
- assertEquals("hairy context encoded as string",
- expectedUghMapCoding, encoded);
-
- // Wrap the MBeanServer with a context MBSF so we can test withContext.
- // Also check the simulated namespace directly.
-
- LogIH mbsIH = new LogIH(mbs);
- MBeanServer snoopMBS = newSnoop(MBeanServer.class, mbsIH);
- MBeanServerForwarder ctxMBS =
- ClientContext.newContextForwarder(snoopMBS, null);
-
- // The MBSF returned by ClientContext is actually a compound of two
- // forwarders, but that is supposed to be hidden by changing the
- // behaviour of get/setMBeanServer. Check that it is indeed so.
- assertEquals("next MBS of context forwarder",
- snoopMBS, ctxMBS.getMBeanServer());
- // If the above assertion fails you may get a confusing message
- // because the toString() of the two objects is likely to be the same
- // so it will look as if they should be equal.
- ctxMBS.setMBeanServer(null);
- assertEquals("next MBS of context forwarder after setting it null",
- null, ctxMBS.getMBeanServer());
- ctxMBS.setMBeanServer(snoopMBS);
-
- // The MBSF should look the same as the original MBeanServer except
- // that it has the JMXNamespace for the simulated namespace.
-
- Set<ObjectName> origNames = mbs.queryNames(null, null);
- Set<ObjectName> mbsfNames = ctxMBS.queryNames(null, null);
- assertEquals("number of MBeans returned by queryNames within forwarder",
- origNames.size() + 1, mbsfNames.size());
- assertEquals("MBeanCount within forwarder",
- mbsfNames.size(), ctxMBS.getMBeanCount());
- assertCalled(mbsIH, "queryNames", emptyContext);
- assertCalled(mbsIH, "getMBeanCount", emptyContext);
-
- ObjectName ctxNamespaceName = new ObjectName(
- ClientContext.NAMESPACE + "//:" + JMXNamespace.TYPE_ASSIGNMENT);
- origNames.add(ctxNamespaceName);
- assertEquals("MBeans within forwarder", origNames, mbsfNames);
- Set<String> domains = new HashSet<String>(Arrays.asList(ctxMBS.getDomains()));
- assertEquals("domains include context namespace MBean",
- true, domains.contains(ClientContext.NAMESPACE + "//"));
- assertCalled(mbsIH, "getDomains", emptyContext);
-
- // Now test ClientContext.withContext.
-
- MBeanServer ughMBS = ClientContext.withContext(ctxMBS, ugh, ugh);
-
- ShowContextMBean ughshow =
- JMX.newMBeanProxy(ughMBS, name, ShowContextMBean.class);
- Map<String, String> ughCtx = ughshow.getContext();
- Map<String, String> ughExpect = singletonMap(ugh, ugh);
- assertEquals("context seen by MBean accessed within namespace",
- ughExpect, ughCtx);
- assertCalled(mbsIH, "getAttribute", ughExpect, name, "Context");
-
- MBeanServer cmbs = ClientContext.withContext(
- ctxMBS, "mickey", "mouse");
- ShowContextMBean cshow =
- JMX.newMBeanProxy(cmbs, name, ShowContextMBean.class);
- assertEquals("context seen by MBean accessed within namespace",
- singletonMap("mickey", "mouse"), cshow.getContext());
-
- MBeanServer ccmbs = ClientContext.withContext(
- cmbs, "donald", "duck");
- ShowContextMBean ccshow =
- JMX.newMBeanProxy(ccmbs, name, ShowContextMBean.class);
- Map<String, String> disney = new HashMap<String, String>();
- disney.put("mickey", "mouse");
- disney.put("donald", "duck");
- assertEquals("context seen by MBean in nested namespace",
- disney, ccshow.getContext());
-
- // Test that all MBS ops produce reasonable results
-
- ObjectName logger = new ObjectName("a:type=Logger");
- DynamicMBean showMBean =
- new StandardMBean(new ShowContext(), ShowContextMBean.class);
- LogIH mbeanLogIH = new LogIH(showMBean);
- DynamicMBean logMBean = newSnoop(DynamicMBean.class, mbeanLogIH);
- ObjectInstance loggerOI = ccmbs.registerMBean(logMBean, logger);
- assertEquals("ObjectName returned by createMBean",
- logger, loggerOI.getObjectName());
-
- // We get an getMBeanInfo call to determine the className in the
- // ObjectInstance to return from registerMBean.
- assertCalled(mbeanLogIH, "getMBeanInfo", disney);
-
- ccmbs.getAttribute(logger, "Thing");
- assertCalled(mbeanLogIH, "getAttribute", disney);
-
- ccmbs.getAttributes(logger, new String[] {"Thing", "Context"});
- assertCalled(mbeanLogIH, "getAttributes", disney);
-
- ccmbs.setAttribute(logger, new Attribute("Thing", "bar"));
- assertCalled(mbeanLogIH, "setAttribute", disney);
-
- ccmbs.setAttributes(logger, new AttributeList(
- Arrays.asList(new Attribute("Thing", "baz"))));
- assertCalled(mbeanLogIH, "setAttributes", disney);
-
- ccmbs.getMBeanInfo(logger);
- assertCalled(mbeanLogIH, "getMBeanInfo", disney);
-
- Set<ObjectName> names = ccmbs.queryNames(null, null);
- Set<ObjectName> expectedNames = new HashSet<ObjectName>(
- Collections.singleton(MBeanServerDelegate.DELEGATE_NAME));
- assertEquals("context namespace query includes expected names",
- true, names.containsAll(expectedNames));
-
- Set<ObjectName> nsNames = ccmbs.queryNames(new ObjectName("*//:*"), null);
- Set<ObjectName> expectedNsNames = new HashSet<ObjectName>(
- Arrays.asList(
- new ObjectName(ClientContext.NAMESPACE +
- ObjectName.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT)));
- assertEquals("context namespace query includes namespace MBean",
- true, nsNames.containsAll(expectedNsNames));
-
-
-
- Set<ObjectInstance> insts = ccmbs.queryMBeans(
- MBeanServerDelegate.DELEGATE_NAME, null);
- assertEquals("size of set from MBeanServerDelegate query", 1, insts.size());
- assertEquals("ObjectName from MBeanServerDelegate query",
- MBeanServerDelegate.DELEGATE_NAME,
- insts.iterator().next().getObjectName());
-
- ObjectName createdName = new ObjectName("a:type=Created");
- ObjectInstance createdOI =
- ccmbs.createMBean(ShowContext.class.getName(), createdName);
- assertEquals("class name from createMBean",
- ShowContext.class.getName(), createdOI.getClassName());
- assertEquals("ObjectName from createMBean",
- createdName, createdOI.getObjectName());
- assertEquals("context within createMBean",
- disney, ccmbs.getAttribute(createdName, "CreationContext"));
-
- NotificationListener nothingListener = new NotificationListener() {
- public void handleNotification(Notification n, Object h) {}
- };
- ccmbs.addNotificationListener(createdName, nothingListener, null, null);
- ccmbs.removeNotificationListener(createdName, nothingListener, null, null);
- ccmbs.addNotificationListener(createdName, nothingListener, null, null);
- ccmbs.removeNotificationListener(createdName, nothingListener);
- Set<String> expectedOps = new HashSet<String>(Arrays.asList(
- "preRegister", "postRegister", "addNotificationListener",
- "removeNL1", "removeNL3", "getNotificationInfo"));
- assertEquals("operations called on MBean",
- expectedOps, ccmbs.getAttribute(createdName, "CalledOps"));
-
- assertEquals("ClassLoader for MBean",
- ShowContext.class.getClassLoader(),
- ccmbs.getClassLoaderFor(createdName));
-
- assertEquals("isRegistered", true, ccmbs.isRegistered(createdName));
- assertEquals("isInstanceOf", true, ccmbs.isInstanceOf(createdName,
- ShowContext.class.getName()));
- assertEquals("isInstanceOf", false, ccmbs.isInstanceOf(createdName,
- DynamicMBean.class.getName()));
- ccmbs.unregisterMBean(createdName);
- assertEquals("isRegistered after unregister",
- false, ccmbs.isRegistered(createdName));
-
- MLet mlet = new MLet();
- ObjectName defaultMLetName = new ObjectName("DefaultDomain:type=MLet");
-
- ccmbs.registerMBean(mlet, defaultMLetName);
-
- assertEquals("getClassLoader", mlet, ccmbs.getClassLoader(defaultMLetName));
-
- assertEquals("number of MBean operations", 0, mbeanLogIH.log.size());
-
- // Test that contexts still work when we can't combine two encoded contexts.
- // Here, we wrap cmbs (mickey=mouse) so that ccmbs2 (donald=duck) cannot
- // see that it already contains a context and therefore cannot combine
- // into mickey=mouse;donald=duck. We don't actually use the snoop
- // capabilities of the returned object -- we just want an opaque
- // MBeanServer wrapper
- MBeanServer cmbs2 = newSnoop(MBeanServer.class, new LogIH(cmbs));
- MBeanServer ccmbs2 = ClientContext.withContext(cmbs2, "donald", "duck");
- assertEquals("context when combination is impossible",
- disney, ccmbs2.getAttribute(name, "Context"));
-
- // Test failure cases of ClientContext.encode
- final List<Map<String, String>> badEncodeArgs =
- Arrays.asList(
- null,
- Collections.<String,String>singletonMap(null, "foo"),
- Collections.<String,String>singletonMap("foo", null));
- for (Map<String, String> bad : badEncodeArgs) {
- try {
- String oops = ClientContext.encode(bad);
- failed("ClientContext.encode(" + bad + ") should have failed: "
- + oops);
- } catch (Exception e) {
- assertEquals("Exception for ClientContext.encode(" + bad + ")",
- IllegalArgumentException.class, e.getClass());
- }
- }
-
- // ADD NEW TESTS HERE ^^^
-
- if (failure != null)
- throw new Exception(failure);
- }
-
- private static void assertEquals(String what, Object x, Object y) {
- if (!equal(x, y))
- failed(what + ": expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
- private static void assertCalled(
- LogIH logIH, String op, Map<String, String> expectedContext) {
- assertCalled(logIH, op, expectedContext, (Object[]) null);
- }
-
- private static void assertCalled(
- LogIH logIH, String op, Map<String, String> expectedContext,
- Object... params) {
- LogRecord lr = logIH.log.remove();
- assertEquals("called operation", op, lr.op);
- if (params != null)
- assertEquals("operation parameters", params, lr.params);
- assertEquals("operation context", expectedContext, lr.context);
- }
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-}
--- a/jdk/test/javax/management/context/LocaleAwareBroadcasterTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,328 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5072267
- * @summary Test that an MBean can handle localized Notification messages.
- * @author Eamonn McManus
- */
-
-import java.util.Collections;
-import java.util.ListResourceBundle;
-import java.util.Locale;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-import javax.management.ClientContext;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.SendNotification;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class LocaleAwareBroadcasterTest {
- static final ObjectName mbeanName = ObjectName.valueOf("d:type=LocaleAware");
-
- static final String
- messageKey = "broken.window",
- defaultMessage = "broken window",
- frenchMessage = "fen\u00eatre bris\u00e9e",
- irishMessage = "fuinneog briste";
-
- public static class Bundle extends ListResourceBundle {
- @Override
- protected Object[][] getContents() {
- return new Object[][] {
- {messageKey, defaultMessage},
- };
- }
- }
-
- public static class Bundle_fr extends ListResourceBundle {
- @Override
- protected Object[][] getContents() {
- return new Object[][] {
- {messageKey, frenchMessage},
- };
- }
- }
-
- public static class Bundle_ga extends ListResourceBundle {
- @Override
- protected Object[][] getContents() {
- return new Object[][] {
- {messageKey, irishMessage},
- };
- }
- }
-
- static volatile String failure;
-
- public static interface LocaleAwareMBean {
- public void sendNotification(Notification n);
- }
-
- public static class LocaleAware
- implements LocaleAwareMBean, NotificationEmitter, SendNotification {
-
- private final ConcurrentMap<Locale, NotificationBroadcasterSupport>
- localeToEmitter = newConcurrentMap();
-
- public void sendNotification(Notification n) {
- for (Map.Entry<Locale, NotificationBroadcasterSupport> entry :
- localeToEmitter.entrySet()) {
- Notification localizedNotif =
- localizeNotification(n, entry.getKey());
- entry.getValue().sendNotification(localizedNotif);
- }
- }
-
- public void addNotificationListener(
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws IllegalArgumentException {
- Locale locale = ClientContext.getLocale();
- NotificationBroadcasterSupport broadcaster;
- broadcaster = localeToEmitter.get(locale);
- if (broadcaster == null) {
- broadcaster = new NotificationBroadcasterSupport();
- NotificationBroadcasterSupport old =
- localeToEmitter.putIfAbsent(locale, broadcaster);
- if (old != null)
- broadcaster = old;
- }
- broadcaster.addNotificationListener(listener, filter, handback);
- }
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- Locale locale = ClientContext.getLocale();
- NotificationBroadcasterSupport broadcaster =
- localeToEmitter.get(locale);
- if (broadcaster == null)
- throw new ListenerNotFoundException();
- broadcaster.removeNotificationListener(listener);
- }
-
- public void removeNotificationListener(
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws ListenerNotFoundException {
- Locale locale = ClientContext.getLocale();
- NotificationBroadcasterSupport broadcaster =
- localeToEmitter.get(locale);
- if (broadcaster == null)
- throw new ListenerNotFoundException();
- broadcaster.removeNotificationListener(listener, filter, handback);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return new MBeanNotificationInfo[0];
- }
- }
-
- // Localize notif using the convention that the message looks like
- // [resourcebundlename:resourcekey]defaultmessage
- // for example [foo.bar.Resources:unknown.problem]
- static Notification localizeNotification(Notification n, Locale locale) {
- String msg = n.getMessage();
- if (!msg.startsWith("["))
- return n;
- int close = msg.indexOf(']');
- if (close < 0)
- throw new IllegalArgumentException("Bad notification message: " + msg);
- int colon = msg.indexOf(':');
- if (colon < 0 || colon > close)
- throw new IllegalArgumentException("Bad notification message: " + msg);
- String bundleName = msg.substring(1, colon);
- String key = msg.substring(colon + 1, close);
- ClassLoader loader = LocaleAwareBroadcasterTest.class.getClassLoader();
- ResourceBundle bundle =
- ResourceBundle.getBundle(bundleName, locale, loader);
- try {
- msg = bundle.getString(key);
- } catch (MissingResourceException e) {
- msg = msg.substring(close + 1);
- }
- n = (Notification) n.clone();
- n.setMessage(msg);
- return n;
- }
-
- public static void main(String[] args) throws Exception {
- Locale.setDefault(new Locale("en"));
- testLocal();
- testRemote();
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- static interface AddListenerInLocale {
- public void addListenerInLocale(
- MBeanServerConnection mbsc,
- NotificationListener listener,
- Locale locale) throws Exception;
- }
-
- private static void testLocal() throws Exception {
- System.out.println("Test local MBeanServer using doWithContext");
- MBeanServer mbs = makeMBS();
- AddListenerInLocale addListener = new AddListenerInLocale() {
- public void addListenerInLocale(
- final MBeanServerConnection mbsc,
- final NotificationListener listener,
- Locale locale) throws Exception {
- Map<String, String> localeContext = Collections.singletonMap(
- ClientContext.LOCALE_KEY, locale.toString());
- ClientContext.doWithContext(
- localeContext, new Callable<Void>() {
- public Void call() throws Exception {
- mbsc.addNotificationListener(
- mbeanName, listener, null, null);
- return null;
- }
- });
- }
- };
- test(mbs, addListener);
- }
-
- private static void testRemote() throws Exception {
- System.out.println("Test remote MBeanServer using withLocale");
- MBeanServer mbs = makeMBS();
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
- JMXConnectorServer cs =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
- cs.start();
- JMXServiceURL addr = cs.getAddress();
- JMXConnector cc = JMXConnectorFactory.connect(addr);
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
- AddListenerInLocale addListenerInLocale = new AddListenerInLocale() {
- public void addListenerInLocale(
- MBeanServerConnection mbsc,
- NotificationListener listener,
- Locale locale) throws Exception {
- mbsc = ClientContext.withLocale(mbsc, locale);
- mbsc.addNotificationListener(mbeanName, listener, null, null);
- }
- };
- try {
- test(mbsc, addListenerInLocale);
- } finally {
- try {
- cc.close();
- } catch (Exception e) {}
- cs.stop();
- }
- }
-
- static class QueueListener implements NotificationListener {
- final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue<Notification>(10);
-
- public void handleNotification(Notification notification,
- Object handback) {
- queue.add(notification);
- }
- }
-
- private static void test(
- MBeanServerConnection mbsc, AddListenerInLocale addListener)
- throws Exception {
- QueueListener defaultListener = new QueueListener();
- QueueListener frenchListener = new QueueListener();
- QueueListener irishListener = new QueueListener();
- mbsc.addNotificationListener(mbeanName, defaultListener, null, null);
- addListener.addListenerInLocale(mbsc, frenchListener, new Locale("fr"));
- addListener.addListenerInLocale(mbsc, irishListener, new Locale("ga"));
-
- LocaleAwareMBean proxy =
- JMX.newMBeanProxy(mbsc, mbeanName, LocaleAwareMBean.class);
- String notifMsg = "[" + Bundle.class.getName() + ":" + messageKey + "]" +
- "broken window (default message that should never be seen)";
- Notification notif = new Notification(
- "notif.type", mbeanName, 0L, notifMsg);
- proxy.sendNotification(notif);
-
- final Object[][] expected = {
- {defaultListener, defaultMessage},
- {frenchListener, frenchMessage},
- {irishListener, irishMessage},
- };
- for (Object[] exp : expected) {
- QueueListener ql = (QueueListener) exp[0];
- String msg = (String) exp[1];
- System.out.println("Checking: " + msg);
- Notification n = ql.queue.poll(1, TimeUnit.SECONDS);
- if (n == null)
- fail("Did not receive expected notif: " + msg);
- if (!n.getMessage().equals(msg)) {
- fail("Received notif with wrong message: got " +
- n.getMessage() + ", expected " + msg);
- }
- n = ql.queue.poll(2, TimeUnit.MILLISECONDS);
- if (n != null)
- fail("Received unexpected extra notif: " + n);
- }
- }
-
- private static MBeanServer makeMBS() throws Exception {
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- LocaleAware aware = new LocaleAware();
- mbs.registerMBean(aware, mbeanName);
- return mbs;
- }
-
- static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
- return new ConcurrentHashMap<K, V>();
- }
-
- static void fail(String why) {
- System.out.println("FAIL: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/context/LocaleTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +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.
- *
- * 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.
- */
-
-/*
- * @test LocaleTest.java
- * @bug 5072267
- * @summary Test client locales.
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import java.util.Collections;
-import java.util.ListResourceBundle;
-import java.util.Locale;
-import java.util.Map;
-import java.util.ResourceBundle;
-import java.util.concurrent.Callable;
-import javax.management.ClientContext;
-import java.util.Arrays;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-public class LocaleTest {
- private static String failure;
-
- public static void main(String[] args) throws Exception {
-
- // Test the translation String -> Locale
-
- Locale[] locales = Locale.getAvailableLocales();
- System.out.println("Testing String->Locale for " + locales.length +
- " locales");
- for (Locale loc : locales) {
- Map<String, String> ctx = Collections.singletonMap(
- ClientContext.LOCALE_KEY, loc.toString());
- Locale loc2 = ClientContext.doWithContext(
- ctx, new Callable<Locale>() {
- public Locale call() {
- return ClientContext.getLocale();
- }
- });
- assertEquals(loc, loc2);
- }
-
- // Test that a locale-sensitive attribute works
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- mbs = ClientContext.newContextForwarder(mbs, null);
- ObjectName name = new ObjectName("a:type=LocaleSensitive");
- mbs.registerMBean(new LocaleSensitive(), name);
- Locale.setDefault(Locale.US);
-
- assertEquals("spectacular failure",
- mbs.getAttribute(name, "LastProblemDescription"));
-
- MBeanServer frmbs = ClientContext.withContext(
- mbs, ClientContext.LOCALE_KEY, Locale.FRANCE.toString());
- assertEquals("\u00e9chec r\u00e9tentissant",
- frmbs.getAttribute(name, "LastProblemDescription"));
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- public static interface LocaleSensitiveMBean {
- public String getLastProblemDescription();
- }
-
- public static class LocaleSensitive implements LocaleSensitiveMBean {
- public String getLastProblemDescription() {
- Locale loc = ClientContext.getLocale();
- ResourceBundle rb = ResourceBundle.getBundle(
- MyResources.class.getName(), loc);
- return rb.getString("spectacular");
- }
- }
-
- public static class MyResources extends ListResourceBundle {
- protected Object[][] getContents() {
- return new Object[][] {
- {"spectacular", "spectacular failure"},
- };
- }
- }
-
- public static class MyResources_fr extends ListResourceBundle {
- protected Object[][] getContents() {
- return new Object[][] {
- {"spectacular", "\u00e9chec r\u00e9tentissant"},
- };
- }
- }
-
- private static void assertEquals(Object x, Object y) {
- if (!equal(x, y))
- failed("expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-}
--- a/jdk/test/javax/management/context/LocalizableTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +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.
- *
- * 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.
- */
-
-/*
- * @test LocalizableTest
- * @bug 5072267 6635499
- * @summary Test localizable MBeanInfo using LocalizableMBeanFactory.
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import javax.management.ClientContext;
-import javax.management.Description;
-import javax.management.JMX;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanConstructorInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import localizable.MBeanDescriptions_fr;
-import localizable.Whatsit;
-
-import static localizable.WhatsitMBean.*;
-
-public class LocalizableTest {
- // If you change the order of the array elements or their number then
- // you must also change these constants.
- private static final int
- MBEAN = 0, ATTR = 1, OPER = 2, PARAM = 3, CONSTR = 4,
- CONSTR_PARAM = 5;
- private static final String[] englishDescriptions = {
- englishMBeanDescription, englishAttrDescription, englishOperDescription,
- englishParamDescription, englishConstrDescription,
- englishConstrParamDescription,
- };
- private static final String[] defaultDescriptions = englishDescriptions.clone();
- static {
- defaultDescriptions[MBEAN] = defaultMBeanDescription;
- }
- private static final String[] frenchDescriptions = {
- frenchMBeanDescription, frenchAttrDescription, frenchOperDescription,
- frenchParamDescription, frenchConstrDescription,
- frenchConstrParamDescription,
- };
-
- private static String failure;
-
- @Description(unlocalizedMBeanDescription)
- public static interface UnlocalizedMBean {}
- public static class Unlocalized implements UnlocalizedMBean {}
-
- public static void main(String[] args) throws Exception {
- ResourceBundle frenchBundle = new MBeanDescriptions_fr();
- // The purpose of the previous line is to force that class to be compiled
- // when the test is run so it will be available for reflection.
- // Yes, we could do this with a @build tag.
-
- MBeanServer plainMBS = ManagementFactory.getPlatformMBeanServer();
- MBeanServer unlocalizedMBS =
- ClientContext.newContextForwarder(plainMBS, null);
- MBeanServer localizedMBS =
- ClientContext.newLocalizeMBeanInfoForwarder(plainMBS);
- localizedMBS = ClientContext.newContextForwarder(localizedMBS, null);
- ObjectName name = new ObjectName("a:b=c");
-
- Whatsit whatsit = new Whatsit();
- Object[][] locales = {
- {null, englishDescriptions},
- {"en", englishDescriptions},
- {"fr", frenchDescriptions},
- };
-
- for (Object[] localePair : locales) {
- String locale = (String) localePair[0];
- String[] localizedDescriptions = (String[]) localePair[1];
- System.out.println("===Testing locale " + locale + "===");
- for (boolean localized : new boolean[] {false, true}) {
- String[] descriptions = localized ?
- localizedDescriptions : defaultDescriptions;
- MBeanServer mbs = localized ? localizedMBS : unlocalizedMBS;
- System.out.println("Testing MBean " + whatsit + " with " +
- "localized=" + localized);
- mbs.registerMBean(whatsit, name);
- System.out.println(mbs.getMBeanInfo(name));
- try {
- test(mbs, name, locale, descriptions);
- } catch (Exception e) {
- fail("Caught exception: " + e);
- } finally {
- mbs.unregisterMBean(name);
- }
- }
- }
-
- System.out.println("===Testing unlocalizable MBean===");
- Object mbean = new Unlocalized();
- localizedMBS.registerMBean(mbean, name);
- try {
- MBeanInfo mbi = localizedMBS.getMBeanInfo(name);
- assertEquals("MBean description", unlocalizedMBeanDescription,
- mbi.getDescription());
- } finally {
- localizedMBS.unregisterMBean(name);
- }
-
- System.out.println("===Testing MBeanInfo.localizeDescriptions===");
- plainMBS.registerMBean(whatsit, name);
- MBeanInfo mbi = plainMBS.getMBeanInfo(name);
- Locale french = new Locale("fr");
- mbi = mbi.localizeDescriptions(french, whatsit.getClass().getClassLoader());
- checkDescriptions(mbi, frenchDescriptions);
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: Last failure: " + failure);
- }
-
- private static void test(MBeanServer mbs, ObjectName name, String locale,
- String[] expectedDescriptions)
- throws Exception {
- if (locale != null)
- mbs = ClientContext.withLocale(mbs, new Locale(locale));
- MBeanInfo mbi = mbs.getMBeanInfo(name);
- checkDescriptions(mbi, expectedDescriptions);
- }
-
- private static void checkDescriptions(MBeanInfo mbi,
- String[] expectedDescriptions) {
- assertEquals("MBean description",
- expectedDescriptions[MBEAN], mbi.getDescription());
- MBeanAttributeInfo mbai = mbi.getAttributes()[0];
- assertEquals("Attribute description",
- expectedDescriptions[ATTR], mbai.getDescription());
- MBeanOperationInfo mboi = mbi.getOperations()[0];
- assertEquals("Operation description",
- expectedDescriptions[OPER], mboi.getDescription());
- MBeanParameterInfo mbpi = mboi.getSignature()[0];
- assertEquals("Parameter description",
- expectedDescriptions[PARAM], mbpi.getDescription());
- MBeanConstructorInfo[] mbcis = mbi.getConstructors();
- assertEquals("Number of constructors", 2, mbcis.length);
- for (MBeanConstructorInfo mbci : mbcis) {
- MBeanParameterInfo[] mbcpis = mbci.getSignature();
- String constrName = mbcpis.length + "-arg constructor";
- assertEquals(constrName + " description",
- expectedDescriptions[CONSTR], mbci.getDescription());
- if (mbcpis.length > 0) {
- assertEquals(constrName + " parameter description",
- expectedDescriptions[CONSTR_PARAM],
- mbcpis[0].getDescription());
- }
- }
- }
-
- private static void assertEquals(String what, Object expect, Object actual) {
- if (expect.equals(actual))
- System.out.println("...OK: " + what + " = " + expect);
- else
- fail(what + " should be " + expect + ", was " + actual);
- }
-
- private static void fail(String why) {
- System.out.println("FAIL: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/context/RemoteContextTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,496 +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.
- *
- * 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.
- */
-
-/*
- * @test RemoteContextTest.java
- * @bug 5072267
- * @summary Test client contexts with namespaces.
- * @author Eamonn McManus, Daniel Fuchs
- */
-
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.URLEncoder;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.ClientContext;
-import javax.management.DynamicMBean;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-import javax.management.loading.MLet;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXRemoteNamespace;
-import javax.management.namespace.JMXNamespace;
-
-import static java.util.Collections.singletonMap;
-import javax.management.MBeanServerFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class RemoteContextTest {
- private static String failure;
-
- public static interface ShowContextMBean {
- public Map<String, String> getContext();
- public Map<String, String> getCreationContext();
- public Set<String> getCalledOps();
- public String getThing();
- public void setThing(String x);
- public int add(int x, int y);
- }
-
- public static class ShowContext
- extends NotificationBroadcasterSupport
- implements ShowContextMBean, MBeanRegistration {
- private final Map<String, String> creationContext;
- private final Set<String> calledOps = new HashSet<String>();
-
- public ShowContext() {
- creationContext = getContext();
- }
-
- public Map<String, String> getContext() {
- return ClientContext.getContext();
- }
-
- public Map<String, String> getCreationContext() {
- return creationContext;
- }
-
- public Set<String> getCalledOps() {
- return calledOps;
- }
-
- public String getThing() {
- return "x";
- }
-
- public void setThing(String x) {
- }
-
- public int add(int x, int y) {
- return x + y;
- }
-
- public ObjectName preRegister(MBeanServer server, ObjectName name) {
- assertEquals(creationContext, getContext());
- calledOps.add("preRegister");
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- assertEquals(creationContext, getContext());
- calledOps.add("postRegister");
- }
-
- // The condition checked here is not guaranteed universally true,
- // but is true every time we unregister an instance of this MBean
- // in this test.
- public void preDeregister() throws Exception {
- assertEquals(creationContext, getContext());
- }
-
- public void postDeregister() {
- assertEquals(creationContext, getContext());
- }
-
- // Same remark as for preDeregister
- @Override
- public MBeanNotificationInfo[] getNotificationInfo() {
- calledOps.add("getNotificationInfo");
- return super.getNotificationInfo();
- }
-
- @Override
- public void addNotificationListener(
- NotificationListener listener, NotificationFilter filter, Object handback) {
- calledOps.add("addNotificationListener");
- super.addNotificationListener(listener, filter, handback);
- }
-
- @Override
- public void removeNotificationListener(
- NotificationListener listener)
- throws ListenerNotFoundException {
- calledOps.add("removeNL1");
- super.removeNotificationListener(listener);
- }
-
- @Override
- public void removeNotificationListener(
- NotificationListener listener, NotificationFilter filter, Object handback)
- throws ListenerNotFoundException {
- calledOps.add("removeNL3");
- super.removeNotificationListener(listener, filter, handback);
- }
- }
-
- private static class LogRecord {
- final String op;
- final Object[] params;
- final Map<String, String> context;
- LogRecord(String op, Object[] params, Map<String, String> context) {
- this.op = op;
- this.params = params;
- this.context = context;
- }
-
- @Override
- public String toString() {
- return op + Arrays.deepToString(params) + " " + context;
- }
- }
-
- private static class LogIH implements InvocationHandler {
- private final Object wrapped;
- Queue<LogRecord> log = new LinkedList<LogRecord>();
-
- LogIH(Object wrapped) {
- this.wrapped = wrapped;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (method.getDeclaringClass() != Object.class) {
- LogRecord lr =
- new LogRecord(
- method.getName(), args, ClientContext.getContext());
- log.add(lr);
- }
- try {
- return method.invoke(wrapped, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- }
-
- private static <T> T newSnoop(Class<T> wrappedClass, LogIH logIH) {
- return wrappedClass.cast(Proxy.newProxyInstance(
- wrappedClass.getClassLoader(),
- new Class<?>[] {wrappedClass},
- logIH));
- }
-
- public static void main(String[] args) throws Exception {
- final String subnamespace = "sub";
- final ObjectName locname = new ObjectName("a:b=c");
- final ObjectName name = JMXNamespaces.insertPath(subnamespace,locname);
- final MBeanServer mbs = ClientContext.newContextForwarder(
- ManagementFactory.getPlatformMBeanServer(), null);
- final MBeanServer sub = ClientContext.newContextForwarder(
- MBeanServerFactory.newMBeanServer(), null);
- final JMXServiceURL anonym = new JMXServiceURL("rmi",null,0);
- final Map<String, Object> env = Collections.emptyMap();
- final Map<String, String> emptyContext = Collections.emptyMap();
- final JMXConnectorServer srv =
- JMXConnectorServerFactory.newJMXConnectorServer(anonym,env,sub);
- sub.registerMBean(new ShowContext(), locname);
-
- srv.start();
-
- try {
- JMXRemoteNamespace subns = JMXRemoteNamespace.
- newJMXRemoteNamespace(srv.getAddress(),null);
- mbs.registerMBean(subns, JMXNamespaces.getNamespaceObjectName("sub"));
- mbs.invoke(JMXNamespaces.getNamespaceObjectName("sub"),
- "connect", null,null);
- final ShowContextMBean show =
- JMX.newMBeanProxy(mbs, name, ShowContextMBean.class);
-
- assertEquals(emptyContext, show.getContext());
- ClientContext.doWithContext(singletonMap("foo", "bar"), new Callable<Void>() {
- public Void call() {
- assertEquals(singletonMap("foo", "bar"), show.getContext());
- return null;
- }
- });
- assertEquals(emptyContext, show.getContext());
- String got = ClientContext.doWithContext(
- singletonMap("foo", "baz"), new Callable<String>() {
- public String call() {
- return ClientContext.getContext().get("foo");
- }
- });
- assertEquals("baz", got);
-
- Map<String, String> combined = ClientContext.doWithContext(
- singletonMap("foo", "baz"), new Callable<Map<String, String>>() {
- public Map<String, String> call() throws Exception {
- return ClientContext.doWithContext(
- singletonMap("fred", "jim"),
- new Callable<Map<String, String>>() {
- public Map<String, String> call() {
- return ClientContext.getContext();
- }
- });
- }
- });
- assertEquals(singletonMap("fred", "jim"), combined);
-
- final String ugh = "a!?//*=:\"% ";
- ClientContext.doWithContext(singletonMap(ugh, ugh), new Callable<Void>() {
- public Void call() {
- assertEquals(Collections.singletonMap(ugh, ugh),
- ClientContext.getContext());
- return null;
- }
- });
-
- // Basic withContext tests
-
- LogIH mbsIH = new LogIH(mbs);
- MBeanServer snoopMBS = newSnoop(MBeanServer.class, mbsIH);
- MBeanServer ughMBS = ClientContext.withContext(snoopMBS, ugh, ugh);
- // ughMBS is never referenced but we check that the withContext call
- // included a call to snoopMBS.isRegistered.
- String encodedUgh = URLEncoder.encode(ugh, "UTF-8").replace("*", "%2A");
- ObjectName expectedName = new ObjectName(
- ClientContext.NAMESPACE + ObjectName.NAMESPACE_SEPARATOR +
- encodedUgh + "=" + encodedUgh +
- ObjectName.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- assertCalled(mbsIH, "isRegistered", new Object[] {expectedName},
- emptyContext);
-
- // Test withDynamicContext
-
- MBeanServerConnection dynamicSnoop =
- ClientContext.withDynamicContext(snoopMBS);
- assertCalled(mbsIH, "isRegistered",
- new Object[] {
- JMXNamespaces.getNamespaceObjectName(ClientContext.NAMESPACE)
- },
- emptyContext);
- final ShowContextMBean dynamicShow =
- JMX.newMBeanProxy(dynamicSnoop, name, ShowContextMBean.class);
- assertEquals(Collections.emptyMap(), dynamicShow.getContext());
- assertCalled(mbsIH, "getAttribute", new Object[] {name, "Context"},
- emptyContext);
-
- Map<String, String> expectedDynamic =
- Collections.singletonMap("gladstone", "gander");
- Map<String, String> dynamic = ClientContext.doWithContext(
- expectedDynamic,
- new Callable<Map<String, String>>() {
- public Map<String, String> call() throws Exception {
- return dynamicShow.getContext();
- }
- });
- assertEquals(expectedDynamic, dynamic);
- ObjectName expectedDynamicName = new ObjectName(
- ClientContext.encode(expectedDynamic) +
- ObjectName.NAMESPACE_SEPARATOR + name);
- assertCalled(mbsIH, "getAttribute",
- new Object[] {expectedDynamicName, "Context"}, dynamic);
-
- MBeanServer cmbs = ClientContext.withContext(
- mbs, "mickey", "mouse");
- ShowContextMBean cshow =
- JMX.newMBeanProxy(cmbs, name, ShowContextMBean.class);
- assertEquals(Collections.singletonMap("mickey", "mouse"), cshow.getContext());
-
- MBeanServer ccmbs = ClientContext.withContext(
- cmbs, "donald", "duck");
- ShowContextMBean ccshow =
- JMX.newMBeanProxy(ccmbs, name, ShowContextMBean.class);
- Map<String, String> disney = new HashMap<String, String>();
- disney.put("mickey", "mouse");
- disney.put("donald", "duck");
- assertEquals(disney, ccshow.getContext());
-
- // Test that all MBS ops produce reasonable results
-
- ObjectName logger = new ObjectName("a:type=Logger");
- DynamicMBean showMBean =
- new StandardMBean(new ShowContext(), ShowContextMBean.class);
- LogIH mbeanLogIH = new LogIH(showMBean);
- DynamicMBean logMBean = newSnoop(DynamicMBean.class, mbeanLogIH);
- ObjectInstance loggerOI = ccmbs.registerMBean(logMBean, logger);
- assertEquals(logger, loggerOI.getObjectName());
-
- // We get a getMBeanInfo call to determine the className in the
- // ObjectInstance to return from registerMBean.
- assertCalled(mbeanLogIH, "getMBeanInfo", disney);
-
- ccmbs.getAttribute(logger, "Thing");
- assertCalled(mbeanLogIH, "getAttribute", disney);
-
- ccmbs.getAttributes(logger, new String[] {"Thing", "Context"});
- assertCalled(mbeanLogIH, "getAttributes", disney);
-
- ccmbs.setAttribute(logger, new Attribute("Thing", "bar"));
- assertCalled(mbeanLogIH, "setAttribute", disney);
-
- ccmbs.setAttributes(logger, new AttributeList(
- Arrays.asList(new Attribute("Thing", "baz"))));
- assertCalled(mbeanLogIH, "setAttributes", disney);
-
- ccmbs.getMBeanInfo(logger);
- assertCalled(mbeanLogIH, "getMBeanInfo", disney);
-
- Set<ObjectName> names = ccmbs.queryNames(null, null);
- Set<ObjectName> expectedNames = new HashSet<ObjectName>(
- Collections.singleton(MBeanServerDelegate.DELEGATE_NAME));
- expectedNames.removeAll(names);
- assertEquals(0, expectedNames.size());
-
- Set<ObjectName> nsNames =
- ccmbs.queryNames(new ObjectName("**?*?//:*"), null);
- Set<ObjectName> expectedNsNames = new HashSet<ObjectName>(
- Arrays.asList(
- new ObjectName(ClientContext.NAMESPACE +
- ObjectName.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT)));
- expectedNsNames.removeAll(nsNames);
- assertEquals(0, expectedNsNames.size());
-
- Set<ObjectInstance> insts = ccmbs.queryMBeans(
- MBeanServerDelegate.DELEGATE_NAME, null);
- assertEquals(1, insts.size());
- assertEquals(MBeanServerDelegate.DELEGATE_NAME,
- insts.iterator().next().getObjectName());
-
- ObjectName createdName = new ObjectName("a:type=Created");
- ObjectInstance createdOI =
- ccmbs.createMBean(ShowContext.class.getName(), createdName);
- assertEquals(ShowContext.class.getName(), createdOI.getClassName());
- assertEquals(createdName, createdOI.getObjectName());
- assertEquals(disney, ccmbs.getAttribute(createdName, "CreationContext"));
-
- NotificationListener nothingListener = new NotificationListener() {
- public void handleNotification(Notification n, Object h) {}
- };
- ccmbs.addNotificationListener(createdName, nothingListener, null, null);
- ccmbs.removeNotificationListener(createdName, nothingListener, null, null);
- ccmbs.addNotificationListener(createdName, nothingListener, null, null);
- ccmbs.removeNotificationListener(createdName, nothingListener);
- Set<String> expectedOps = new HashSet<String>(Arrays.asList(
- "preRegister", "postRegister", "addNotificationListener",
- "removeNL1", "removeNL3", "getNotificationInfo"));
- assertEquals(expectedOps, ccmbs.getAttribute(createdName, "CalledOps"));
-
- assertEquals(ShowContext.class.getClassLoader(),
- ccmbs.getClassLoaderFor(createdName));
-
- assertEquals(true, ccmbs.isRegistered(createdName));
- assertEquals(true, ccmbs.isInstanceOf(createdName,
- ShowContext.class.getName()));
- assertEquals(false, ccmbs.isInstanceOf(createdName,
- DynamicMBean.class.getName()));
- ccmbs.unregisterMBean(createdName);
- assertEquals(false, ccmbs.isRegistered(createdName));
-
- MLet mlet = new MLet();
- ObjectName defaultMLetName = new ObjectName("DefaultDomain:type=MLet");
-
- ccmbs.registerMBean(mlet, defaultMLetName);
-
- assertEquals(mlet, ccmbs.getClassLoader(defaultMLetName));
-
- assertEquals(0, mbeanLogIH.log.size());
-
- // Test that contexts still work when we can't combine two encoded contexts.
- // Here, we wrap cmbs (mickey=mouse) so that ccmbs2 (donald=duck) cannot
- // see that it already contains a context and therefore cannot combine
- // into mickey=mouse;donald=duck. We don't actually use the snoop
- // capabilities of the returned object -- we just want an opaque
- // MBeanServer wrapper
- MBeanServer cmbs2 = newSnoop(MBeanServer.class, new LogIH(cmbs));
- MBeanServer ccmbs2 = ClientContext.withContext(cmbs2, "donald", "duck");
- assertEquals(disney, ccmbs2.getAttribute(name, "Context"));
-
- // ADD NEW TESTS HERE ^^^
-
- if (failure != null)
- throw new Exception(failure);
- } finally {
- srv.stop();
- }
- }
-
- private static void assertEquals(Object x, Object y) {
- if (!equal(x, y))
- failed("expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
- private static void assertCalled(
- LogIH logIH, String op, Map<String, String> expectedContext) {
- assertCalled(logIH, op, null, expectedContext);
- }
-
- private static void assertCalled(
- LogIH logIH, String op, Object[] params,
- Map<String, String> expectedContext) {
- LogRecord lr = logIH.log.remove();
- assertEquals(op, lr.op);
- if (params != null)
- assertEquals(params, lr.params);
- assertEquals(expectedContext, lr.context);
- }
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-}
--- a/jdk/test/javax/management/context/localizable/MBeanDescriptions.properties Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-# This is the default description ResourceBundle for MBeans in this package.
-# Resources here override the descriptions specified with @Description
-# but only when localization is happening and when there is not a more
-# specific resource for the description (for example from MBeanDescriptions_fr).
-
-WhatsitMBean.mbean = A whatsit
-# This must be the same as WhatsitMBean.englishMBeanDescription for the
-# purposes of this test.
-
--- a/jdk/test/javax/management/context/localizable/MBeanDescriptions_fr.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +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.
- *
- * 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 localizable;
-
-import java.util.ListResourceBundle;
-import static localizable.WhatsitMBean.*;
-
-public class MBeanDescriptions_fr extends ListResourceBundle {
- @Override
- protected Object[][] getContents() {
- String constrProp = "WhatsitMBean.constructor." + Whatsit.class.getName();
- return new Object[][] {
- {"WhatsitMBean.mbean", frenchMBeanDescription},
- {"WhatsitMBean.attribute.Whatsit", frenchAttrDescription},
- {"WhatsitMBean.operation.frob", frenchOperDescription},
- {"WhatsitMBean.operation.frob.p1", frenchParamDescription},
- {constrProp, frenchConstrDescription},
- {constrProp + ".p1", frenchConstrParamDescription},
- };
- }
-}
--- a/jdk/test/javax/management/context/localizable/Whatsit.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.
- *
- * 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 localizable;
-
-import javax.management.Description;
-
-public class Whatsit implements WhatsitMBean {
- /**
- * Attribute : NewAttribute0
- */
- private String newAttribute0;
- @Description(englishConstrDescription)
- public Whatsit() {}
-
- @Description(englishConstrDescription)
- public Whatsit(@Description(englishConstrParamDescription) int type) {}
-
- public String getWhatsit() {
- return "whatsit";
- }
-
- public void frob(String whatsit) {
- }
-
- /**
- * Get Tiddly
- */
- public String getNewAttribute0() {
- return newAttribute0;
- }
-
- /**
- * Set Tiddly
- */
- public void setNewAttribute0(String value) {
- newAttribute0 = value;
- }
-}
--- a/jdk/test/javax/management/context/localizable/WhatsitMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.
- *
- * 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 localizable;
-
-import javax.management.Description;
-
-@Description(WhatsitMBean.defaultMBeanDescription)
-public interface WhatsitMBean {
- public static final String
- defaultMBeanDescription = "Default whatsit MBean description",
- englishMBeanDescription = "A whatsit",
- // Previous description appears in MBeanDescriptions.properties
- // so it overrides the @Description when that file is used.
- frenchMBeanDescription = "Un bidule",
- englishAttrDescription = "The whatsit",
- frenchAttrDescription = "Le bidule",
- englishOperDescription = "Frob the whatsit",
- frenchOperDescription = "Frober le bidule",
- englishParamDescription = "The whatsit to frob",
- frenchParamDescription = "Le bidule \u00e0 frober",
- englishConstrDescription = "Make a whatsit",
- frenchConstrDescription = "Fabriquer un bidule",
- englishConstrParamDescription = "Type of whatsit to make",
- frenchConstrParamDescription = "Type de bidule \u00e0 fabriquer",
- unlocalizedMBeanDescription = "Unlocalized MBean";
-
- @Description(englishAttrDescription)
- public String getWhatsit();
-
- @Description(englishOperDescription)
- public void frob(@Description(englishParamDescription) String whatsit);
-}
--- a/jdk/test/javax/management/descriptor/DescriptorConstructorTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright 2004-2005 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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6501362
- * @summary DescriptorSupport(String) could recognize "name=value" as well as XML format
- * @author Jean-Francois Denise
- * @run clean DescriptorConstructorTest
- * @run build DescriptorConstructorTest
- * @run main DescriptorConstructorTest
- */
-
-import javax.management.modelmbean.DescriptorSupport;
-
-public class DescriptorConstructorTest {
- public static void main(String[] args) throws Exception {
- DescriptorSupport d1 = new DescriptorSupport("MyName1=MyValue1");
- if(!d1.getFieldValue("MyName1").equals("MyValue1"))
- throw new Exception("Invalid parsing");
- DescriptorSupport d2 = new DescriptorSupport("<Descriptor>" +
- "<field name=\"MyName2\" value=\"MyValue2\"></field></Descriptor>");
- if(!d2.getFieldValue("MyName2").equals("MyValue2"))
- throw new Exception("Invalid parsing");
- }
-}
--- a/jdk/test/javax/management/eventService/AddRemoveListenerTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +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.
- *
- * 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.
- */
-
-/*
- * @test AddRemoveListenerTest.java
- * @bug 5108776
- * @summary Basic test for EventClient to see internal thread management.
- * @author Shanliang JIANG
- * @run clean AddRemoveListenerTest
- * @run build AddRemoveListenerTest
- * @run main AddRemoveListenerTest
- */
-
-import java.io.IOException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.FetchingEventRelay;
-import javax.management.event.RMIPushEventRelay;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-
-// This thread creates a single MBean that emits a number of parallel
-// sequences of notifications. Each sequence is distinguished by an id
-// and each id corresponds to a thread that is filtering the notifications
-// so it only sees its own ones. The notifications for a given id have
-// contiguous sequence numbers and each thread checks that the notifications
-// it receives do indeed have these numbers. If notifications are lost or
-// if the different sequences interfere with each other then the test will
-// fail. As an added tweak, a "noise" thread periodically causes notifications
-// to be emitted that do not correspond to any sequence and do not have any id.
-public class AddRemoveListenerTest {
-
- private static MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
- private static ObjectName emitter;
- private static NotificationSender emitterImpl;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
-
- private static int toSend = 100;
- private static final long bigWaiting = 10000;
- private static int counter = 0;
- private static int jobs = 10;
- private static int endedJobs = 0;
-
- private static volatile String failure;
-
- public static void main(String[] args) throws Exception {
- System.out.println(">>> Test on multiple adding/removing listeners.");
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- emitter = new ObjectName("Default:name=NotificationSender");
- emitterImpl = new NotificationSender();
- mbeanServer.registerMBean(emitterImpl, emitter);
-
- String[] types = new String[]{"PushEventRelay", "FetchingEventRelay"};
- String[] protos = new String[]{"rmi", "iiop", "jmxmp"};
- for (String prot : protos) {
- url = new JMXServiceURL(prot, null, 0);
-
- try {
- server =
- JMXConnectorServerFactory.newJMXConnectorServer(url,
- null, mbeanServer);
- server.start();
- } catch (Exception e) {
- System.out.println(">>> Skip "+prot+", not supported.");
- continue;
- }
-
- url = server.getAddress();
-
- // noise
- Thread noise = new Thread(new Runnable() {
- public void run() {
- while (true) {
- emitterImpl.sendNotif(1, null);
- try {
- Thread.sleep(10);
- } catch (Exception e) {
- // OK
- }
- }
- }
- });
- noise.setDaemon(true);
- noise.start();
-
- try {
- for (String type: types) {
- System.out.println("\n\n>>> Testing "+type+" on "+url+" ...");
- JMXConnector conn = newConn();
- try {
- testType(type, conn);
- } finally {
- conn.close();
- System.out.println(">>> Testing "+type+" on "+url+" ... done");
- }
- }
- } finally {
- server.stop();
- }
- }
- }
-
- private static void testType(String type, JMXConnector conn) throws Exception {
- Thread[] threads = new Thread[jobs];
- for (int i=0; i<jobs; i++) {
- threads[i] = new Thread(new Job(type, conn));
- threads[i].setDaemon(true);
- threads[i].start();
- }
-
- // to wait
- long toWait = bigWaiting*jobs;
- long stopTime = System.currentTimeMillis() + toWait;
-
- synchronized(AddRemoveListenerTest.class) {
- while (endedJobs < jobs && toWait > 0 && failure == null) {
- AddRemoveListenerTest.class.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- if (endedJobs != jobs && failure == null) {
- throw new RuntimeException("Need to set bigger waiting timeout?");
- }
-
- endedJobs = 0;
- }
-
- public static class Job implements Runnable {
- public Job(String type, JMXConnector conn) {
- this.type = type;
- this.conn = conn;
- }
- public void run() {
- try {
- test(type, conn);
-
- synchronized(AddRemoveListenerTest.class) {
- endedJobs++;
- if (endedJobs>=jobs) {
- AddRemoveListenerTest.class.notify();
- }
- }
- } catch (RuntimeException re) {
- throw re;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private final String type;
- private final JMXConnector conn;
- }
-
- private static void test(String type, JMXConnector conn) throws Exception {
- EventClient ec = newEventClient(type, conn);
- try {
- test(type, conn, ec);
- } finally {
- ec.close();
- }
- }
-
- private static void test(String type, JMXConnector conn, EventClient ec)
- throws Exception {
- String id = getId();
-
- Listener listener = new Listener(id);
- Filter filter = new Filter(id);
-
- System.out.println(">>> ("+id+") To receive notifications "+toSend);
- ec.addNotificationListener(emitter,
- listener, filter, null);
-
- emitterImpl.sendNotif(toSend, id);
- listener.waitNotifs(bigWaiting, toSend);
- if (listener.received != toSend) {
- throw new RuntimeException(">>> ("+id+") Expected to receive: "
- +toSend+", but got: "+listener.received);
- }
-
- listener.clear();
- ec.removeNotificationListener(emitter, listener, filter, null);
-
- System.out.println(">>> ("+id+") Repeat adding and removing ...");
- for (int j=0; j<10; j++) {
- ec.addNotificationListener(emitter, dummyListener, null, id);
- Thread.yield(); // allow to start listening
- ec.removeNotificationListener(emitter, dummyListener, null, id);
- }
-
- System.out.println(">>> ("+id+") To receive again notifications "+toSend);
- ec.addNotificationListener(emitter,
- listener, filter, null);
-
- emitterImpl.sendNotif(toSend, id);
- listener.waitNotifs(bigWaiting, toSend);
- Thread.yield(); //any duplicated?
- if (listener.received != toSend) {
- throw new RuntimeException("("+id+") Expected to receive: "
- +toSend+", but got: "+listener.received);
- }
- }
-
-//--------------------------
-// private classes
-//--------------------------
-
- private static class Listener implements NotificationListener {
- public Listener(String id) {
- this.id = id;
- }
- public void handleNotification(Notification notif, Object handback) {
- if (!id.equals(notif.getUserData())) {
- System.out.println("("+id+") Filter error, my id is: "+id+
- ", but got "+notif.getUserData());
- System.exit(1);
- }
-
- synchronized (this) {
- received++;
-
- if(++sequenceNB != notif.getSequenceNumber()) {
- fail("(" + id + ") Wrong sequence number, expected: "
- +sequenceNB+", but got: "+notif.getSequenceNumber());
- }
- if (received >= toSend || failure != null) {
- this.notify();
- }
- }
- }
-
- public void waitNotifs(long timeout, int nb) throws Exception {
- long toWait = timeout;
- long stopTime = System.currentTimeMillis() + timeout;
- synchronized(this) {
- while (received < nb && toWait > 0 && failure == null) {
- this.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
- }
-
- public void clear() {
- synchronized(this) {
- received = 0;
- sequenceNB = -1;
- }
- }
-
- private String id;
- private int received = 0;
-
- private long sequenceNB = -1;
- }
-
- private static class Filter implements NotificationFilter {
- public Filter(String id) {
- this.id = id;
- }
-
- public boolean isNotificationEnabled(Notification n) {
- return id.equals(n.getUserData());
- }
- private String id;
- }
-
- private static NotificationListener dummyListener = new NotificationListener() {
- public void handleNotification(Notification notif, Object handback) {
- }
- };
-
- public static class NotificationSender extends NotificationBroadcasterSupport
- implements NotificationSenderMBean {
-
- /**
- * Send Notification objects.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotif(int nb, String userData) {
- long sequenceNumber = 0;
- for (int i = 0; i<nb; i++) {
- Notification notif = new Notification(myType, this, sequenceNumber++);
- notif.setUserData(userData);
- sendNotification(notif);
- }
- }
-
-
- private final String myType = "notification.my_notification";
- }
-
- public interface NotificationSenderMBean {
- public void sendNotif(int nb, String userData);
- }
-
- private static JMXConnector newConn() throws IOException {
- return JMXConnectorFactory.connect(url);
- }
-
- private static EventClient newEventClient(String type, JMXConnector conn)
- throws Exception {
- EventClientDelegateMBean proxy =
- EventClientDelegate.getProxy(conn.getMBeanServerConnection());
- if (type.equals("PushEventRelay")) {
- return new EventClient(proxy,
- new RMIPushEventRelay(proxy), null, null, 60000);
- } else if (type.equals("FetchingEventRelay")) {
- return new EventClient(proxy,
- new FetchingEventRelay(proxy), null, null, 60000);
- } else {
- throw new RuntimeException("Wrong event client type: "+type);
- }
- }
-
- private static String getId() {
- synchronized(AddRemoveListenerTest.class) {
- return String.valueOf(counter++);
- }
- }
-
- private static void fail(String msg) {
- System.out.println("FAIL: " + msg);
- failure = msg;
- }
-}
--- a/jdk/test/javax/management/eventService/CustomForwarderTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +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.
- *
- * 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.
- */
-
-/*
- * @test CustomForwarderTest
- * @bug 5108776 6759619
- * @summary Test that a custom EventForwarder can be added
- * @author Eamonn McManus
- */
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.management.ManagementFactory;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.SocketAddress;
-import java.util.Map;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.EventForwarder;
-import javax.management.event.EventReceiver;
-import javax.management.event.EventRelay;
-import javax.management.remote.MBeanServerForwarder;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
-
-public class CustomForwarderTest {
- public static class UdpEventRelay implements EventRelay {
- private final EventClientDelegateMBean delegate;
- private final DatagramSocket socket;
- private final AtomicBoolean closed = new AtomicBoolean();
- private final String clientId;
- private EventReceiver receiver;
-
- public UdpEventRelay(EventClientDelegateMBean delegate)
- throws IOException {
- this.delegate = delegate;
- this.socket = new DatagramSocket();
- try {
- clientId = delegate.addClient(
- UdpEventForwarder.class.getName(),
- new Object[] {socket.getLocalSocketAddress()},
- new String[] {SocketAddress.class.getName()});
- } catch (IOException e) {
- throw e;
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- final IOException ioe =
- new IOException("Exception creating EventForwarder");
- ioe.initCause(e);
- throw ioe;
- }
- Thread t = new Thread(new Receiver());
- t.setDaemon(true);
- t.start();
- }
-
- public String getClientId() throws IOException {
- return clientId;
- }
-
- public void setEventReceiver(EventReceiver eventReceiver) {
- this.receiver = eventReceiver;
- }
-
- public void stop() throws IOException {
- closed.set(true);
- socket.close();
- }
-
- void simulateNonFatal() {
- receiver.nonFatal(new Exception("NonFatal"));
- }
-
- void simulateFailed() {
- receiver.failed(new Error("Failed"));
- }
-
- private class Receiver implements Runnable {
- public void run() {
- byte[] buf = new byte[1024];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
- while (true) {
- try {
- socket.receive(packet);
- } catch (IOException e) {
- if (closed.get()) {
- System.out.println("Receiver got exception: " + e);
- System.out.println("Normal because it has been closed");
- return;
- } else {
- System.err.println("UNEXPECTED EXCEPTION IN RECEIVER:");
- e.printStackTrace();
- System.exit(1);
- }
- }
- try {
- ByteArrayInputStream bin = new ByteArrayInputStream(buf);
- ObjectInputStream oin = new ObjectInputStream(bin);
- NotificationResult nr = (NotificationResult)
- oin.readObject();
- receiver.receive(nr);
- } catch (Exception e) {
- System.err.println("UNEXPECTED EXCEPTION IN RECEIVER:");
- e.printStackTrace();
- System.exit(1);
- }
- }
- }
- }
- }
-
- public static class UdpEventForwarder implements EventForwarder {
- private final DatagramSocket socket;
- private final AtomicLong seqNo = new AtomicLong(0);
- private static volatile boolean drop;
-
- public UdpEventForwarder(SocketAddress addr) throws IOException {
- this.socket = new DatagramSocket();
- socket.connect(addr);
- }
-
- public static void setDrop(boolean drop) {
- UdpEventForwarder.drop = drop;
- }
-
- public void forward(Notification n, Integer listenerId) throws IOException {
- long nextSeqNo = seqNo.incrementAndGet();
- long thisSeqNo = nextSeqNo - 1;
- TargetedNotification tn = new TargetedNotification(n, listenerId);
- NotificationResult nr = new NotificationResult(
- thisSeqNo, nextSeqNo, new TargetedNotification[] {tn});
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(nr);
- oout.close();
- byte[] bytes = bout.toByteArray();
- DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
- if (!drop)
- socket.send(packet);
- }
-
- public void close() throws IOException {
- socket.close();
- }
-
- public void setClientId(String clientId) throws IOException {
- // Nothing to do.
- }
- }
-
- public static interface EmptyMBean {}
-
- public static class Empty
- extends NotificationBroadcasterSupport implements EmptyMBean {
- public void send(Notification n) {
- super.sendNotification(n);
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- MBeanServerForwarder mbsf = EventClientDelegate.newForwarder(mbs, null);
- mbs = mbsf;
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbs.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbs.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbs),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- ObjectName name = new ObjectName("a:b=c");
- Empty mbean = new Empty();
- mbs.registerMBean(mbean, name);
-
- EventClientDelegateMBean delegate = (EventClientDelegateMBean)
- MBeanServerInvocationHandler.newProxyInstance(
- mbs,
- EventClientDelegateMBean.OBJECT_NAME,
- EventClientDelegateMBean.class,
- false);
- UdpEventRelay relay = new UdpEventRelay(delegate);
- EventClient client = new EventClient(delegate, relay, null, null, 0L);
-
- final Semaphore lostCountSema = new Semaphore(0);
- final BlockingQueue<Notification> nonFatalNotifs =
- new ArrayBlockingQueue<Notification>(1);
- final BlockingQueue<Notification> failedNotifs =
- new ArrayBlockingQueue<Notification>(1);
- NotificationListener lostListener = new NotificationListener() {
- public void handleNotification(Notification notification, Object handback) {
- if (notification.getType().equals(EventClient.NOTIFS_LOST)) {
- System.out.println("Got lost-notifs notif: count=" +
- notification.getUserData());
- lostCountSema.release(((Long) notification.getUserData()).intValue());
- } else if (notification.getType().equals(EventClient.NONFATAL)) {
- System.out.println("Got nonFatal notif");
- nonFatalNotifs.add(notification);
- } else if (notification.getType().equals(EventClient.FAILED)) {
- System.out.println("Got failed notif");
- failedNotifs.add(notification);
- } else
- System.out.println("Mysterious EventClient notif: " + notification);
- }
- };
- client.addEventClientListener(lostListener, null, null);
-
- final BlockingQueue<Notification> notifQueue =
- new ArrayBlockingQueue<Notification>(10);
- NotificationListener countListener = new NotificationListener() {
- public void handleNotification(Notification notification, Object handback) {
- System.out.println("Received: " + notification);
- notifQueue.add(notification);
- if (!"tiddly".equals(handback)) {
- System.err.println("TEST FAILED: bad handback: " + handback);
- System.exit(1);
- }
- }
- };
-
- final AtomicInteger filterCount = new AtomicInteger(0);
- NotificationFilter countFilter = new NotificationFilter() {
- private static final long serialVersionUID = 1234L;
-
- public boolean isNotificationEnabled(Notification notification) {
- System.out.println("Filter called for: " + notification);
- filterCount.incrementAndGet();
- return true;
- }
- };
-
- client.addNotificationListener(name, countListener, countFilter, "tiddly");
-
- assertEquals("Initial notif count", 0, notifQueue.size());
- assertEquals("Initial filter count", 0, filterCount.get());
-
- Notification n = nextNotif(name);
- mbean.send(n);
-
- System.out.println("Waiting for notification to arrive...");
-
- Notification n1 = notifQueue.poll(10, TimeUnit.SECONDS);
-
- assertEquals("Received notif", n, n1);
- assertEquals("Notif queue size after receive", 0, notifQueue.size());
- assertEquals("Filter count after notif", 1, filterCount.get());
- assertEquals("Lost notif count", 0, lostCountSema.availablePermits());
-
- System.out.println("Dropping notifs");
-
- UdpEventForwarder.setDrop(true);
- for (int i = 0; i < 3; i++)
- mbean.send(nextNotif(name));
- UdpEventForwarder.setDrop(false);
-
- Thread.sleep(2);
- assertEquals("Notif queue size after drops", 0, notifQueue.size());
-
- System.out.println("Turning off dropping and sending a notif");
- n = nextNotif(name);
- mbean.send(n);
-
- System.out.println("Waiting for dropped notifications to be detected...");
- boolean acquired = lostCountSema.tryAcquire(3, 5, TimeUnit.SECONDS);
- assertEquals("Correct count of lost notifs", true, acquired);
-
- n1 = notifQueue.poll(10, TimeUnit.SECONDS);
- assertEquals("Received non-dropped notif", n, n1);
-
- assertEquals("Notif queue size", 0, notifQueue.size());
- assertEquals("Filter count after drops", 5, filterCount.get());
-
- Thread.sleep(10);
- assertEquals("Further lost-notifs", 0, lostCountSema.availablePermits());
-
- System.out.println("Testing error notifs");
- relay.simulateNonFatal();
- n = nonFatalNotifs.poll(10, TimeUnit.SECONDS);
- assertEquals("Exception message for non-fatal exception", "NonFatal",
- ((Throwable) n.getSource()).getMessage());
- relay.simulateFailed();
- n = failedNotifs.poll(10, TimeUnit.SECONDS);
- assertEquals("Exception message for failed exception", "Failed",
- ((Throwable) n.getSource()).getMessage());
-
- // 6759619
- System.out.println("Test EventClient.getEventClientNotificationInfo");
- MBeanNotificationInfo[] mbnis = client.getEventClientNotificationInfo();
- final String[] expectedTypes = {
- EventClient.NOTIFS_LOST, EventClient.NONFATAL, EventClient.FAILED
- };
- check:
- for (String type : expectedTypes) {
- for (MBeanNotificationInfo mbni : mbnis) {
- for (String t : mbni.getNotifTypes()) {
- if (type.equals(t)) {
- System.out.println("...found " + type);
- continue check;
- }
- }
- }
- throw new Exception("TEST FAILED: Did not find notif type " + type);
- }
-
- client.close();
-
- System.out.println("TEST PASSED");
- }
-
- private static AtomicLong nextSeqNo = new AtomicLong(0);
- private static Notification nextNotif(ObjectName name) {
- long n = nextSeqNo.incrementAndGet();
- return new Notification("type", name, n, "" + n);
- }
-
- private static void assertEquals(String what, Object expected, Object got) {
- if (equals(expected, got))
- System.out.println(what + " = " + expected + ", as expected");
- else {
- Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
- for (Thread t : traces.keySet()) {
- System.out.println(t.getName());
- for (StackTraceElement elmt : traces.get(t)) {
- System.out.println(" " + elmt);
- }
- }
- throw new RuntimeException(
- "TEST FAILED: " + what + " is " + got + "; should be " +
- expected);
- }
- }
-
- private static boolean equals(Object expected, Object got) {
- if (!(expected instanceof Notification))
- return expected.equals(got);
- if (expected.getClass() != got.getClass())
- return false;
- // Notification doesn't override Object.equals so two distinct
- // notifs are never equal even if they have the same contents.
- // Although the test doesn't serialize the notifs, if at some
- // stage it did then it would fail because the deserialized notif
- // was not equal to the original one. Therefore we compare enough
- // notif fields to detect when notifs really are different.
- Notification en = (Notification) expected;
- Notification gn = (Notification) got;
- return (en.getType().equals(gn.getType()) &&
- en.getSource().equals(gn.getSource()) &&
- en.getSequenceNumber() == gn.getSequenceNumber());
- }
-}
--- a/jdk/test/javax/management/eventService/EventClientExecutorTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5108776
- * @summary Test that the various Executor parameters in an EventClient do
- * what they are supposed to.
- * @author Eamonn McManus
- */
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.FetchingEventRelay;
-import javax.management.remote.MBeanServerForwarder;
-
-public class EventClientExecutorTest {
- private static volatile String failure;
- private static final Set testedPrefixes = new HashSet();
-
- public static void main(String[] args) throws Exception {
- Executor fetchExecutor = Executors.newSingleThreadExecutor(
- new NamedThreadFactory("FETCH"));
- Executor listenerExecutor = Executors.newSingleThreadExecutor(
- new NamedThreadFactory("LISTENER"));
- ScheduledExecutorService leaseScheduler =
- Executors.newSingleThreadScheduledExecutor(
- new NamedThreadFactory("LEASE"));
-
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- MBeanServerForwarder mbsf = EventClientDelegate.newForwarder(mbs, null);
- mbs = mbsf;
-
- EventClientDelegateMBean ecd = EventClientDelegate.getProxy(mbs);
- ecd = (EventClientDelegateMBean) Proxy.newProxyInstance(
- EventClientDelegateMBean.class.getClassLoader(),
- new Class<?>[] {EventClientDelegateMBean.class},
- new DelegateCheckIH(ecd));
-
- ObjectName mbeanName = new ObjectName("d:type=Notifier");
- Notifier notifier = new Notifier();
- mbs.registerMBean(notifier, mbeanName);
-
- FetchingEventRelay eventRelay = new FetchingEventRelay(
- ecd, fetchExecutor);
- EventClient ec = new EventClient(
- ecd, eventRelay, listenerExecutor, leaseScheduler, 1000L);
- NotificationListener checkListener = new NotificationListener() {
- public void handleNotification(Notification notification,
- Object handback) {
- assertThreadName("listener dispatch", "LISTENER");
- }
- };
- ec.addNotificationListener(mbeanName, checkListener, null, null);
-
- mbs.invoke(mbeanName, "send", null, null);
-
- // Now wait until we have seen all three thread types.
- long deadline = System.currentTimeMillis() + 5000;
- synchronized (testedPrefixes) {
- while (testedPrefixes.size() < 3 && failure == null) {
- long remain = deadline - System.currentTimeMillis();
- if (remain <= 0) {
- fail("Timed out waiting for all three thread types to show, " +
- "saw only " + testedPrefixes);
- break;
- }
- try {
- testedPrefixes.wait(remain);
- } catch (InterruptedException e) {
- fail("Unexpected InterruptedException");
- break;
- }
- }
- }
-
- // We deliberately don't close the EventClient to check that it has
- // not created any non-daemon threads.
-
- if (failure != null)
- throw new Exception("TEST FAILED: " + failure);
- else
- System.out.println("TEST PASSED");
- }
-
- public static interface NotifierMBean {
- public void send();
- }
-
- public static class Notifier extends NotificationBroadcasterSupport
- implements NotifierMBean {
- public void send() {
- Notification n = new Notification("a.b.c", this, 0L);
- sendNotification(n);
- }
- }
-
- static void fail(String why) {
- System.out.println("FAIL: " + why);
- failure = why;
- }
-
- static void assertThreadName(String what, String prefix) {
- String name = Thread.currentThread().getName();
- if (!name.startsWith(prefix)) {
- fail("Wrong thread for " + what + ": " + name);
- return;
- }
-
- synchronized (testedPrefixes) {
- if (testedPrefixes.add(prefix))
- testedPrefixes.notify();
- }
- }
-
- private static class DelegateCheckIH implements InvocationHandler {
- private final EventClientDelegateMBean ecd;
-
- public DelegateCheckIH(EventClientDelegateMBean ecd) {
- this.ecd = ecd;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- String methodName = method.getName();
- if (methodName.equals("fetchNotifications"))
- assertThreadName("fetchNotifications", "FETCH");
- else if (methodName.equals("lease"))
- assertThreadName("lease renewal", "LEASE");
- try {
- return method.invoke(ecd, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- }
-
- private static class NamedThreadFactory implements ThreadFactory {
- private final String namePrefix;
- private int count;
-
- NamedThreadFactory(String namePrefix) {
- this.namePrefix = namePrefix;
- }
-
- public synchronized Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setName(namePrefix + " " + ++count);
- t.setDaemon(true);
- return t;
- }
- }
-}
--- a/jdk/test/javax/management/eventService/EventClientThreadTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6747411
- * @summary Check that EventClient instances don't leak threads.
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerNotification;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class EventClientThreadTest {
- private static final int MAX_TIME_SECONDS = 20;
-
- private static final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue(100);
-
- private static final NotificationListener queueListener =
- new NotificationListener() {
- public void handleNotification(Notification notification,
- Object handback) {
- queue.add(notification);
- }
- };
-
- private static final NotificationFilter dummyFilter =
- new NotificationFilter() {
- public boolean isNotificationEnabled(Notification notification) {
- return true;
- }
- };
-
- public static void main(String[] args) throws Exception {
- long start = System.currentTimeMillis();
- long deadline = start + MAX_TIME_SECONDS * 1000;
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
- url, null, mbs);
- cs.start();
- JMXServiceURL addr = cs.getAddress();
- JMXConnector cc = JMXConnectorFactory.connect(addr);
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
-
- ThreadMXBean threads = ManagementFactory.getThreadMXBean();
-
- System.out.println("Opening and closing some EventClients...");
- // If we create a connection, then create and destroy EventClients
- // over it, then close it, there should be no "JMX *" threads left.
- for (int i = 0; i < 5; i++)
- test(mbsc);
-
- cc.close();
-
- showTime("opening and closing initial EventClients", start);
-
- Set<String> jmxThreads = threadsMatching("JMX .*");
- while (!jmxThreads.isEmpty() && System.currentTimeMillis() < deadline) {
- Set<String> jmxThreadsNow = threadsMatching("JMX .*");
- Set<String> gone = new TreeSet<String>(jmxThreads);
- gone.removeAll(jmxThreadsNow);
- for (String s : gone)
- showTime("expiry of \"" + s + "\"", start);
- jmxThreads = jmxThreadsNow;
- Thread.sleep(10);
- }
- if (System.currentTimeMillis() >= deadline) {
- showThreads(threads);
- throw new Exception("Timed out waiting for JMX threads to expire");
- }
-
- showTime("waiting for JMX threads to expire", start);
-
- System.out.println("TEST PASSED");
- }
-
- static void showThreads(ThreadMXBean threads) throws Exception {
- long[] ids = threads.getAllThreadIds();
- for (long id : ids) {
- ThreadInfo ti = threads.getThreadInfo(id);
- String name = (ti == null) ? "(defunct)" : ti.getThreadName();
- System.out.printf("%4d %s\n", id, name);
- }
- }
-
- static void showTime(String what, long start) {
- long elapsed = System.currentTimeMillis() - start;
- System.out.printf("Time after %s: %.3f s\n", what, elapsed / 1000.0);
- }
-
- static Set<String> threadsMatching(String pattern) {
- Set<String> matching = new TreeSet<String>();
- ThreadMXBean threads = ManagementFactory.getThreadMXBean();
- long[] ids = threads.getAllThreadIds();
- for (long id : ids) {
- ThreadInfo ti = threads.getThreadInfo(id);
- String name = (ti == null) ? "(defunct)" : ti.getThreadName();
- if (name.matches(pattern))
- matching.add(name);
- }
- return matching;
- }
-
- static void test(MBeanServerConnection mbsc) throws Exception {
- final ObjectName delegateName = MBeanServerDelegate.DELEGATE_NAME;
- final ObjectName testName = new ObjectName("test:type=Test");
- EventClient ec = new EventClient(mbsc);
- ec.addNotificationListener(delegateName, queueListener, null, null);
- mbsc.createMBean(MBeanServerDelegate.class.getName(), testName);
- mbsc.unregisterMBean(testName);
- final String[] expectedTypes = {
- MBeanServerNotification.REGISTRATION_NOTIFICATION,
- MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
- };
- for (String s : expectedTypes) {
- Notification n = queue.poll(3, TimeUnit.SECONDS);
- if (n == null)
- throw new Exception("Timed out waiting for notif: " + s);
- if (!(n instanceof MBeanServerNotification))
- throw new Exception("Got notif of wrong class: " + n.getClass());
- if (!n.getType().equals(s)) {
- throw new Exception("Got notif of wrong type: " + n.getType() +
- " (expecting " + s + ")");
- }
- }
- ec.removeNotificationListener(delegateName, queueListener);
-
- ec.addNotificationListener(delegateName, queueListener, dummyFilter, "foo");
- ec.removeNotificationListener(delegateName, queueListener, dummyFilter, "foo");
-
- ec.close();
- }
-}
\ No newline at end of file
--- a/jdk/test/javax/management/eventService/EventDelegateSecurityTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5108776
- * @summary Test that the EventClientDelegate MBean does not require extra
- * permissions compared with plain addNotificationListener.
- * @author Eamonn McManus
- * @run main/othervm -Dxjava.security.debug=policy,access,failure EventDelegateSecurityTest
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.AllPermission;
-import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.TimeUnit;
-import javax.management.MBeanPermission;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXPrincipal;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-import javax.security.auth.Subject;
-
-public class EventDelegateSecurityTest {
- private static final BlockingQueue<Notification> notifQ =
- new SynchronousQueue<Notification>();
-
- private static volatile long seqNo;
- private static volatile long expectSeqNo;
-
- private static class QueueListener implements NotificationListener {
- public void handleNotification(Notification notification,
- Object handback) {
- try {
- notifQ.put(notification);
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- }
- }
- }
- private static final NotificationListener queueListener = new QueueListener();
-
- public static interface SenderMBean {
- public void send();
- }
-
- public static class Sender
- extends NotificationBroadcasterSupport implements SenderMBean {
- public void send() {
- Notification n = new Notification("x", this, seqNo++);
- sendNotification(n);
- }
- }
-
- private static class LimitInvocationHandler implements InvocationHandler {
- private MBeanServer nextMBS;
- private final Set<String> allowedMethods = new HashSet<String>();
-
- void allow(String... names) {
- synchronized (allowedMethods) {
- allowedMethods.addAll(Arrays.asList(names));
- }
- }
-
- public Object invoke(Object proxy, Method m, Object[] args)
- throws Throwable {
- System.out.println(
- "filter: " + m.getName() +
- ((args == null) ? "[]" : Arrays.deepToString(args)));
- String name = m.getName();
-
- if (name.equals("getMBeanServer"))
- return nextMBS;
-
- if (name.equals("setMBeanServer")) {
- nextMBS = (MBeanServer) args[0];
- return null;
- }
-
- if (m.getDeclaringClass() == Object.class ||
- allowedMethods.contains(name)) {
- try {
- return m.invoke(nextMBS, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- } else {
- System.out.println("...refused");
- throw new SecurityException(
- "Method refused: " + m.getDeclaringClass().getName() +
- "." + m.getName() +
- ((args == null) ? "[]" : Arrays.deepToString(args)));
- }
- }
-
- }
-
- private static interface MakeConnectorServer {
- public JMXConnectorServer make(JMXServiceURL url) throws IOException;
- }
-
-
- public static void main(String[] args) throws Exception {
- JMXPrincipal rootPrincipal = new JMXPrincipal("root");
- Subject rootSubject = new Subject();
- rootSubject.getPrincipals().add(rootPrincipal);
- Subject.doAsPrivileged(rootSubject, new PrivilegedExceptionAction<Void>() {
- public Void run() throws Exception {
- mainAsRoot();
- return null;
- }
- }, null);
- }
-
- private static void mainAsRoot() throws Exception {
- AccessControlContext acc = AccessController.getContext();
- Subject subject = Subject.getSubject(acc);
- System.out.println("Subject: " + subject);
- final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = new ObjectName("a:b=c");
- mbs.registerMBean(new Sender(), name);
-
- System.out.println("Test with no installed security");
- test(mbs, name, new MakeConnectorServer() {
- public JMXConnectorServer make(JMXServiceURL url) throws IOException {
- return
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, null);
- }
- });
-
- System.out.println("Test with filtering MBeanServerForwarder");
- LimitInvocationHandler limitIH = new LimitInvocationHandler();
- // We allow getClassLoaderRepository because the ConnectorServer
- // calls it so any real checking MBeanServerForwarder must accept it.
- limitIH.allow(
- "addNotificationListener", "removeNotificationListener",
- "getClassLoaderRepository"
- );
- final MBeanServerForwarder limitMBSF = (MBeanServerForwarder)
- Proxy.newProxyInstance(
- MBeanServerForwarder.class.getClassLoader(),
- new Class<?>[] {MBeanServerForwarder.class},
- limitIH);
- // We go to considerable lengths to ensure that the ConnectorServer has
- // no MBeanServer when the EventClientDelegate forwarder is activated,
- // so that the calls it makes when it is later linked to an MBeanServer
- // go through the limitMBSF.
- test(mbs, name, new MakeConnectorServer() {
- public JMXConnectorServer make(JMXServiceURL url) throws IOException {
- JMXConnectorServer cs =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, null);
- limitMBSF.setMBeanServer(mbs);
- cs.setMBeanServerForwarder(limitMBSF);
- return cs;
- }
- });
-
- final File policyFile =
- File.createTempFile("EventDelegateSecurityTest", ".policy");
- PrintWriter pw = new PrintWriter(policyFile);
- String JMXPrincipal = JMXPrincipal.class.getName();
- String AllPermission = AllPermission.class.getName();
- String MBeanPermission = MBeanPermission.class.getName();
- pw.println("grant principal " + JMXPrincipal + " \"root\" {");
- pw.println(" permission " + AllPermission + ";");
- pw.println("};");
- pw.println("grant principal " + JMXPrincipal + " \"user\" {");
- pw.println(" permission " + MBeanPermission + " \"*\", " +
- " \"addNotificationListener\";");
- pw.println(" permission " + MBeanPermission + " \"*\", " +
- " \"removeNotificationListener\";");
- pw.println("};");
- pw.close();
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- policyFile.delete();
- }
- });
- System.setProperty("java.security.policy", policyFile.getAbsolutePath());
- System.setSecurityManager(new SecurityManager());
- test(mbs, name, new MakeConnectorServer() {
- public JMXConnectorServer make(JMXServiceURL url) throws IOException {
- Map<String, Object> env = new HashMap<String, Object>();
- env.put(JMXConnectorServer.AUTHENTICATOR, new JMXAuthenticator() {
- public Subject authenticate(Object credentials) {
- Subject s = new Subject();
- s.getPrincipals().add(new JMXPrincipal("user"));
- return s;
- }
- });
- return
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, null);
- }
- });
- }
-
- private static void test(MBeanServer mbs, ObjectName name) throws Exception {
- test(mbs, name, null);
- }
-
- private static void test(
- MBeanServer mbs, ObjectName name, MakeConnectorServer make)
- throws Exception {
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
- JMXConnectorServer cs = make.make(url);
- ObjectName csName = new ObjectName("a:type=ConnectorServer");
- mbs.registerMBean(cs, csName);
- cs.start();
- try {
- JMXServiceURL addr = cs.getAddress();
- JMXConnector cc = JMXConnectorFactory.connect(addr);
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
- test(mbs, mbsc, name);
- cc.close();
- mbs.unregisterMBean(csName);
- } finally {
- cs.stop();
- }
- }
-
- private static void test(
- MBeanServer mbs, MBeanServerConnection mbsc, ObjectName name)
- throws Exception {
- EventClient ec = new EventClient(mbsc);
- ec.addNotificationListener(name, queueListener, null, null);
- mbs.invoke(name, "send", null, null);
-
- Notification n = notifQ.poll(5, TimeUnit.SECONDS);
- if (n == null)
- throw new Exception("FAILED: notif not delivered");
- if (n.getSequenceNumber() != expectSeqNo) {
- throw new Exception(
- "FAILED: notif seqno " + n.getSequenceNumber() +
- " should be " + expectSeqNo);
- }
- expectSeqNo++;
-
- ec.removeNotificationListener(name, queueListener);
- ec.close();
- }
-}
--- a/jdk/test/javax/management/eventService/EventManagerTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +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.
- *
- * 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.
- */
-
-/*
- * @test EventManagerTest.java 1.8 08/01/22
- * @bug 5108776
- * @summary Basic test for EventManager.
- * @author Shanliang JIANG
- * @run clean EventManagerTest
- * @run build EventManagerTest
- * @run main EventManagerTest
- */
-
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.*;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- *
- */
-public class EventManagerTest {
- private static MBeanServer mbeanServer;
- private static ObjectName emitter;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
- private static JMXConnector conn;
- private static MBeanServerConnection client;
-
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) throws Exception {
- System.out.println(">>> EventManagerTest-main basic tests ...");
- mbeanServer = MBeanServerFactory.createMBeanServer();
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- emitter = new ObjectName("Default:name=NotificationEmitter");
-
- url = new JMXServiceURL("rmi", null, 0) ;
- server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
- server.start();
-
- url = server.getAddress();
- conn = JMXConnectorFactory.connect(url, null);
- client = conn.getMBeanServerConnection();
-
- mbeanServer.registerMBean(new NotificationEmitter(), emitter);
-
- boolean succeed;
-
- System.out.println(">>> EventManagerTest-main: using the fetching EventRelay...");
- succeed = test(new EventClient(client));
-
- System.out.println(">>> EventManagerTest-main: using the pushing EventRelay...");
- EventClientDelegateMBean ecd = EventClientDelegate.getProxy(client);
- succeed &= test(new EventClient(ecd,
- new RMIPushEventRelay(ecd),
- null, null,
- EventClient.DEFAULT_REQUESTED_LEASE_TIME));
-
- conn.close();
- server.stop();
-
- if (succeed) {
- System.out.println(">>> EventManagerTest-main: PASSE!");
- } else {
- System.out.println("\n>>> EventManagerTest-main: FAILED!");
- System.exit(1);
- }
- }
-
- public static boolean test(EventClient efClient) throws Exception {
- // add listener from the client side
- Listener listener = new Listener();
- efClient.subscribe(emitter, listener, null, null);
-
- // ask to send notifs
- Object[] params = new Object[] {new Integer(sendNB)};
- String[] signatures = new String[] {"java.lang.Integer"};
- client.invoke(emitter, "sendNotifications", params, signatures);
-
- // waiting
- long toWait = 6000;
- long stopTime = System.currentTimeMillis() + toWait;
-
- synchronized(listener) {
- while(listener.received < sendNB && toWait > 0) {
- listener.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- // clean
- System.out.println(">>> EventManagerTest-test: cleaning...");
- efClient.unsubscribe(emitter, listener);
- efClient.close();
-
- if (listener.received != sendNB) {
- System.out.println(">>> EventManagerTest-test: FAILED! Expected to receive "+sendNB+", but got "+listener.received);
-
- return false;
- } else if (listener.seqErr > 0) {
- System.out.println(">>> EventManagerTest-test: FAILED! The receiving sequence is not correct.");
-
- return false;
- } else {
- System.out.println(">>> EventManagerTest-test: got all expected "+listener.received);
- return true;
- }
- }
-
- private static class Listener implements NotificationListener {
- public int received = 0;
- public int seqErr = 0;
-
- private long lastSeq = -1;
-
- public void handleNotification(Notification notif, Object handback) {
- if (!myType.equals(notif.getType())) {
- System.out.println(">>> EventManagerTest-Listener: got unexpected notif: "+notif);
- System.exit(1);
- }
-
- if (lastSeq == -1) {
- lastSeq = notif.getSequenceNumber();
- } else if (notif.getSequenceNumber() - lastSeq++ != 1) {
- seqErr++;
- }
-
- //System.out.println(">>> EventManagerTest-Listener: got notif "+notif.getSequenceNumber());
-
- synchronized(this) {
- if (++received >= sendNB) {
- this.notify();
- }
- }
- }
- }
-
- public static class NotificationEmitter extends NotificationBroadcasterSupport
- implements NotificationEmitterMBean {
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- final String[] ntfTypes = {myType};
-
- final MBeanNotificationInfo[] ntfInfoArray = {
- new MBeanNotificationInfo(ntfTypes,
- "javax.management.Notification",
- "Notifications sent by the NotificationEmitter")};
-
- return ntfInfoArray;
- }
-
- /**
- * Send Notification objects.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotifications(Integer nb) {
- Notification notif;
- for (int i=1; i<=nb.intValue(); i++) {
- notif = new Notification(myType, this, count++);
- notif.setUserData("jsl");
- //System.out.println(">>> EventManagerService-NotificationEmitter-sendNotifications: "+i);
-
- sendNotification(notif);
- }
- }
- }
-
- public interface NotificationEmitterMBean {
- public void sendNotifications(Integer nb);
- }
-
- private static int sendNB = 120;
- private static long count = 0;
-
- private static final String myType = "notification.my_notification";
-}
--- a/jdk/test/javax/management/eventService/FetchingTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5108776
- * @summary Basic test for EventClient.
- * @author Shanliang JIANG
- * @run clean FetchingTest MyFetchingEventForwarder
- * @run build FetchingTest MyFetchingEventForwarder
- * @run main FetchingTest MyFetchingEventForwarder
- */
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.FetchingEventRelay;
-import javax.management.event.RMIPushEventForwarder;
-import javax.management.event.RMIPushServer;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class FetchingTest {
- private static MBeanServer mbeanServer;
- private static ObjectName emitter;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
- private static JMXConnector conn;
- private static MBeanServerConnection client;
- private static long WAITING_TIME = 6000;
-
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) throws Exception {
-
- System.out.println(">>> FetchingTest-main basic tests ...");
- mbeanServer = MBeanServerFactory.createMBeanServer();
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- emitter = new ObjectName("Default:name=NotificationEmitter");
- mbeanServer.registerMBean(new NotificationEmitter(), emitter);
- boolean succeed = true;
-
- final String[] protos = new String[] {"rmi", "iiop", "jmxmp"};
- for (String proto : protos) {
- System.out.println(">>> FetchingTest-main: testing on "+proto);
-
- try {
- url = new JMXServiceURL(proto, null, 0) ;
- server = JMXConnectorServerFactory.
- newJMXConnectorServer(url, null, mbeanServer);
- server.start();
- } catch (Exception e) {
- // OK
- System.out.println(">>> FetchingTest-main: skip the proto "+proto);
- continue;
- }
-
- url = server.getAddress();
- conn = JMXConnectorFactory.connect(url, null);
- client = conn.getMBeanServerConnection();
-
- succeed &= test();
-
- conn.close();
- server.stop();
-
- System.out.println(
- ">>> FetchingTest-main: testing on "+proto+" done.");
- }
-
- if (succeed) {
- System.out.println(">>> FetchingTest-main: PASSED!");
- } else {
- System.out.println("\n>>> FetchingTest-main: FAILED!");
- System.exit(1);
- }
- }
-
- public static boolean test() throws Exception {
- System.out.println(">>> FetchingTest-test: " +
- "using the default fetching forwarder ...");
- EventClient eventClient =
- new EventClient(client);
-
- Listener listener = new Listener();
- eventClient.addNotificationListener(emitter, listener, null, null);
-
- // ask to send notifs
- Object[] params = new Object[] {new Integer(sendNB)};
- String[] signatures = new String[] {"java.lang.Integer"};
- conn.getMBeanServerConnection().invoke(emitter,
- "sendNotifications", params, signatures);
-
- if (listener.waitNotif(WAITING_TIME) != sendNB) {
- System.out.println(
- ">>> FetchingTest-test: FAILED! Expected to receive "+
- sendNB+", but got "+listener.received);
-
- return false;
- }
-
- System.out.println(
- ">>> ListenerTest-test: got all expected "+listener.received);
- //eventClient.removeNotificationListener(emitter, listener);
- eventClient.close();
-
- System.out.println(">>> FetchingTest-test: " +
- "using a user specific List ...");
-
- FetchingEventRelay fer = new FetchingEventRelay(
- EventClientDelegate.getProxy(client),
- 1000, 1000L, 1000, null,
- MyFetchingEventForwarder.class.getName(),
- null, null);
-
- eventClient = new EventClient(
- EventClientDelegate.getProxy(client), fer, null, null, 10000);
-
- eventClient.addNotificationListener(emitter, listener, null, null);
- listener.received = 0;
-
- conn.getMBeanServerConnection().invoke(emitter,
- "sendNotifications", params, signatures);
-
- if (listener.waitNotif(WAITING_TIME) != sendNB) {
- System.out.println(
- ">>> FetchingTest-test: FAILED! Expected to receive "+
- sendNB+", but got "+listener.received);
-
- return false;
- }
-
- System.out.println(
- ">>> FetchingTest-test: got all expected "+listener.received);
-
- if (!MyFetchingEventForwarder.shared.isUsed()) {
- System.out.println(
- ">>> FetchingTest-test: FAILED! The user specific list" +
- "is not used!");
-
- return false;
- }
-
- System.out.println(">>> Negative test to add an EventClient" +
- " with a non EventForwarder object.");
- try {
- MyFetchingEventForwarder.shared.setAgain();
-
- System.out.println(
- ">>> FetchingTest-test: FAILED! No expected exception" +
- "when setting the list after the forwarder started.");
-
- return false;
- } catch (IllegalStateException ise) {
- // OK
- System.out.println(
- ">>> FetchingTest-test: Got expected exception: " + ise);
- }
-
- eventClient.close();
-
- try {
- fer = new FetchingEventRelay(
- EventClientDelegate.getProxy(client),
- 1000, 1000L, 1000, null,
- Object.class.getName(),
- null, null);
-
- eventClient = new EventClient(
- EventClientDelegate.getProxy(client), fer, null, null, 10000);
-
- System.out.println(
- ">>> FetchingTest-test: FAILED! No expected exception" +
- "when creating an illegal EventForwarder");
- } catch (IllegalArgumentException iae) {
- // OK
- // iae.printStackTrace();
- }
-
- return true;
- }
-
- private static class Listener implements NotificationListener {
- public void handleNotification(Notification notif, Object handback) {
- synchronized(this) {
- if (++received >= sendNB) {
- this.notify();
- }
- }
-
- //System.out.println(">>> FetchingTest-Listener: received = "+received);
- }
-
- public int waitNotif(long timeout) throws Exception {
- synchronized(this) {
- long stopTime = System.currentTimeMillis() + timeout;
- long toWait = timeout;
- while (toWait > 0 && received < sendNB) {
- this.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- return received;
- }
-
- public static int received = 0;
- }
-
- public static class NotificationEmitter extends NotificationBroadcasterSupport
- implements NotificationEmitterMBean {
-
- public void sendNotifications(Integer nb) {
- System.out.println(
- ">>> FetchingTest-NotificationEmitter-sendNotifications: "+nb);
- Notification notif;
- for (int i=1; i<=nb.intValue(); i++) {
- notif = new Notification(myType, this, count++);
- sendNotification(notif);
- }
- }
- }
-
- public interface NotificationEmitterMBean {
- public void sendNotifications(Integer nb);
- }
-
-
-
- private static int sendNB = 20;
- private static int count = 0;
-
- private static final String myType = "notification.my_notification";
-}
--- a/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6717789
- * @summary Check that a lock is not held when a LeaseManager expires.
- * @author Eamonn McManus
- * @compile -XDignore.symbol.file=true LeaseManagerDeadlockTest.java
- * @run main LeaseManagerDeadlockTest
- */
-
-import com.sun.jmx.event.LeaseManager;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadMXBean;
-import java.util.Arrays;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-public class LeaseManagerDeadlockTest {
- public static String failure;
- public static LeaseManager leaseManager;
- public static Semaphore callbackThreadCompleted = new Semaphore(0);
- public static Object lock = new Object();
-
- public static Runnable triggerDeadlock = new Runnable() {
- public void run() {
- Runnable pingLeaseManager = new Runnable() {
- public void run() {
- System.out.println("Ping thread starts");
- synchronized (lock) {
- leaseManager.lease(1);
- }
- System.out.println("Ping thread completes");
- }
- };
- Thread t = new Thread(pingLeaseManager);
- t.start();
- try {
- Thread.sleep(10); // enough time for ping thread to grab lock
- synchronized (lock) {
- t.join();
- }
- } catch (InterruptedException e) {
- fail(e.toString());
- }
- System.out.println("Callback thread completes");
- callbackThreadCompleted.release();
- }
- };
-
- public static void main(String[] args) throws Exception {
- // Also test that we can shorten the lease from its initial value.
- leaseManager = new LeaseManager(triggerDeadlock, 1000000);
- leaseManager.lease(1L);
-
- boolean callbackRan =
- callbackThreadCompleted.tryAcquire(3, TimeUnit.SECONDS);
-
- if (!callbackRan) {
- fail("Callback did not complete - probable deadlock");
- ThreadMXBean threads = ManagementFactory.getThreadMXBean();
- System.out.println(Arrays.toString(threads.findDeadlockedThreads()));
- System.out.println("PRESS RETURN");
- System.in.read();
- }
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- public static void fail(String why) {
- System.out.println("TEST FAILS: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/eventService/LeaseTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,361 +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.
- *
- * 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.
- */
-
-/*
- * @test LeaseTest.java 1.6 08/01/22
- * @bug 5108776
- * @summary Basic test for Event service leasing.
- * @author Shanliang JIANG
- * @run clean LeaseTest
- * @run build LeaseTest
- * @run main LeaseTest
- */
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.EventClientNotFoundException;
-import javax.management.event.FetchingEventRelay;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class LeaseTest {
-
- private static MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
- private static List<Notification> notifList = new ArrayList<Notification>();
- private static ObjectName emitter;
- private static NotificationEmitter emitterImpl;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
- private static JMXConnector conn;
- private static Listener listener = new Listener();
-
- private static long leaseTime = 100;
- private static final int multiple = 5;
- private static final long bigWaiting = 6000;
-
- public static void main(String[] args) throws Exception {
- System.out.println(">>> Test the event service lease");
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- System.setProperty("com.sun.event.lease.time",
- String.valueOf(leaseTime));
- emitter = new ObjectName("Default:name=NotificationEmitter");
- emitterImpl = new NotificationEmitter();
- mbeanServer.registerMBean(emitterImpl, emitter);
-
- String[] types = new String[]{"PushingEventRelay", "FetchingEventRelay"};
- String[] protos = new String[]{"rmi", "iiop", "jmxmp"};
- for (String prot : protos) {
- url = new JMXServiceURL(prot, null, 0);
-
- try {
- server =
- JMXConnectorServerFactory.newJMXConnectorServer(url,
- null, mbeanServer);
- server.start();
- } catch (Exception e) {
- System.out.println(">>> Skip "+prot+", not support.");
- continue;
- }
-
- url = server.getAddress();
-
- try {
- for (String type: types) {
- test(type);
- }
- } finally {
- server.stop();
- }
- }
- }
-
- private static void test(String type) throws Exception {
- System.out.println("\n\n>>> Testing "+type+" on "+url+" ...");
- newConn();
- EventClient ec = newEventClient(type);
-
- ec.addNotificationListener(emitter,
- listener, null, null);
-
- System.out.println(">>> Send a notification and should receive it.");
- emitterImpl.sendNotif(++counter);
-
- if (!waitNotif(bigWaiting, counter)) {
- throw new RuntimeException(">>> Failed to receive notif.");
- }
-
- System.out.println(">>> Sleep 3 times of requested lease time.");
- Thread.sleep(leaseTime*3);
- System.out.println(">>> Send again a notification and should receive it.");
- emitterImpl.sendNotif(++counter);
-
- if (!waitNotif(bigWaiting, counter)) {
- throw new RuntimeException(">>> Failed to receive notif.");
- }
-
- System.out.println(">>> Close the client connection: "+
- conn.getConnectionId());
- conn.close();
-
- System.out.println(">>> Waiting lease timeout to do clean.");
-
- if (!emitterImpl.waitingClean(leaseTime*multiple)) {
- throw new RuntimeException(
- ">>> The event lease failed to do clean: "+
- emitterImpl.listenerSize);
- } else {
- System.out.println(">>> The listener has been removed.");
- }
-
- // Check that the client id has indeed been removed, by trying to
- // remove it again, which should fail.
- newConn();
- try {
- EventClientDelegateMBean proxy =
- EventClientDelegate.getProxy(conn.getMBeanServerConnection());
- proxy.removeClient(ec.getEventRelay().getClientId());
-
- throw new RuntimeException(
- ">>> The client id is not removed.");
- } catch (EventClientNotFoundException ecnfe) {
- // OK
- System.out.println(">>> The client id has been removed.");
- }
- conn.close();
-
- System.out.println(">>> Reconnect to the server.");
- newConn();
-
- System.out.println(">>> Create a new EventClient and add the listeners" +
- " in the failed EventClient into new EventClient");
- EventClient newEC = newEventClient(type);
- newEC.addListeners(ec.getListeners());
- // We expect ec.close() to get IOException because we closed the
- // underlying connection.
- try {
- ec.close();
- throw new RuntimeException(">>> EventClient.close did not throw " +
- "expected IOException");
- } catch (IOException e) {
- System.out.println(">>> EventClient.close threw expected exception: " + e);
- }
-
- emitterImpl.sendNotif(++counter);
-
- if (!waitNotif(bigWaiting, counter)) {
- throw new RuntimeException(">>> The event client failed to add " +
- "all old registered listeners after re-connection.");
- } else {
- System.out.println(">>> Successfully received notification from" +
- " new EventClient.");
- }
-
- System.out.println(">>> Clean the failed EventClient.");
- ec.close();
- if (ec.getListeners().size() != 0) {
- throw new RuntimeException(">>> The event client fails to do clean.");
- }
-
- System.out.println(">>> Clean the new EventClient.");
- newEC.close();
- if (newEC.getListeners().size() != 0) {
- throw new RuntimeException(">>> The event client fails to do clean.");
- }
-
- conn.close();
- System.out.println(">>> Testing "+type+" on "+url+" ... done");
- }
-
- private static boolean waitNotif(long time, int sequenceNumber)
- throws Exception {
- synchronized(notifList) {
- if (search(sequenceNumber)) {
- return true;
- }
-
- long stopTime = System.currentTimeMillis() + time;
- long toWait = time;
- while (toWait > 0) {
- notifList.wait(toWait);
-
- if (search(sequenceNumber)) {
- return true;
- }
-
- toWait = stopTime - System.currentTimeMillis();
- }
-
- return false;
- }
- }
-
- private static boolean search(int sequenceNumber) {
- while(notifList.size() > 0) {
- Notification n = notifList.remove(0);
- if (n.getSequenceNumber() == sequenceNumber) {
- return true;
- }
- }
-
- return false;
- }
-
-//--------------------------
-// private classes
-//--------------------------
-
- private static class Listener implements NotificationListener {
- public void handleNotification(Notification notif, Object handback) {
- synchronized (notifList) {
- notifList.add(notif);
- notifList.notify();
- }
- }
- }
-
- public static class NotificationEmitter extends NotificationBroadcasterSupport
- implements NotificationEmitterMBean {
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- final String[] ntfTypes = {myType};
-
- final MBeanNotificationInfo[] ntfInfoArray = {
- new MBeanNotificationInfo(ntfTypes,
- "javax.management.Notification",
- "Notifications sent by the NotificationEmitter")};
-
- return ntfInfoArray;
- }
-
- /**
- * Send Notification objects.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotif(int sequenceNumber) {
- Notification notif = new Notification(myType, this, sequenceNumber);
- sendNotification(notif);
- }
-
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback) {
- super.addNotificationListener(listener, filter, handback);
-
- listenerSize++;
- }
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- super.removeNotificationListener(listener);
- listenerSize--;
-
- synchronized(this) {
- if (listenerSize == 0) {
- this.notifyAll();
- }
- }
- }
-
- public void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback)
- throws ListenerNotFoundException {
- super.removeNotificationListener(listener, filter, handback);
- listenerSize--;
-
- synchronized(this) {
- if (listenerSize == 0) {
- this.notifyAll();
- }
- }
- }
-
- public boolean waitingClean(long timeout) throws Exception {
- synchronized(this) {
- long stopTime = System.currentTimeMillis() + timeout;
- long toWait = timeout;
- while (listenerSize != 0 && toWait > 0) {
- this.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- return listenerSize == 0;
- }
-
- public int listenerSize = 0;
-
- private final String myType = "notification.my_notification";
- }
-
- public interface NotificationEmitterMBean {
- public void sendNotif(int sequenceNumber);
- }
-
- private static void newConn() throws IOException {
- conn = JMXConnectorFactory.connect(url);
- }
-
- private static EventClient newEventClient(String type) throws Exception {
- EventClientDelegateMBean proxy =
- EventClientDelegate.getProxy(conn.getMBeanServerConnection());
- if (type.equals("PushingEventRelay")) {
- return new EventClient(proxy,
- new FetchingEventRelay(proxy), null, null, leaseTime);
- } else if (type.equals("FetchingEventRelay")) {
- return new EventClient(proxy,
- new FetchingEventRelay(proxy), null, null, leaseTime);
- } else {
- throw new RuntimeException("Wrong event client type: "+type);
- }
- }
-
- private static int counter = 0;
-}
--- a/jdk/test/javax/management/eventService/ListenerTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +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.
- *
- * 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.
- */
-
-/*
- * @test ListenerTest.java 1.7 08/01/22
- * @bug 5108776
- * @summary Basic test for EventClient.
- * @author Shanliang JIANG
- * @run clean ListenerTest
- * @run build ListenerTest
- * @run main ListenerTest
- */
-
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.*;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- *
- */
-public class ListenerTest {
- private static MBeanServer mbeanServer;
- private static ObjectName emitter;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
- private static JMXConnector conn;
- private static MBeanServerConnection client;
-
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) throws Exception {
-
- System.out.println(">>> ListenerTest-main basic tests ...");
- mbeanServer = MBeanServerFactory.createMBeanServer();
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- emitter = new ObjectName("Default:name=NotificationEmitter");
-
- url = new JMXServiceURL("rmi", null, 0) ;
- server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
- server.start();
-
- url = server.getAddress();
- conn = JMXConnectorFactory.connect(url, null);
- client = conn.getMBeanServerConnection();
-
- mbeanServer.registerMBean(new NotificationEmitter(), emitter);
-
- boolean succeed;
-
- System.out.println(">>> ListenerTest-main: using the fetching EventRelay...");
- succeed = test(new EventClient(client));
-
- System.out.println(">>> ListenerTest-main: using the pushing EventRelay...");
- EventClientDelegateMBean ecd = EventClientDelegate.getProxy(client);
- succeed &= test(new EventClient(ecd,
- new RMIPushEventRelay(ecd),
- null, null,
- EventClient.DEFAULT_REQUESTED_LEASE_TIME));
-
- conn.close();
- server.stop();
-
- if (succeed) {
- System.out.println(">>> ListenerTest-main: PASSED!");
- } else {
- System.out.println("\n>>> ListenerTest-main: FAILED!");
- System.exit(1);
- }
- }
-
- public static boolean test(EventClient efClient) throws Exception {
- // add listener from the client side
- Listener listener = new Listener();
- efClient.addNotificationListener(emitter, listener, null, null);
-
- // ask to send notifs
- Object[] params = new Object[] {new Integer(sendNB)};
- String[] signatures = new String[] {"java.lang.Integer"};
- client.invoke(emitter, "sendNotifications", params, signatures);
-
- // waiting
- long toWait = 6000;
- long stopTime = System.currentTimeMillis() + toWait;
-
- synchronized(listener) {
- while(listener.received < sendNB && toWait > 0) {
- listener.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- // clean
- efClient.removeNotificationListener(emitter, listener, null, null);
- efClient.close();
-
- if (listener.received != sendNB) {
- System.out.println(">>> ListenerTest-test: FAILED! Expected to receive "+sendNB+", but got "+listener.received);
-
- return false;
- } else if (listener.seqErr > 0) {
- System.out.println(">>> ListenerTest-test: FAILED! The receiving sequence is not correct.");
-
- return false;
- } else {
- System.out.println(">>> ListenerTest-test: got all expected "+listener.received);
- return true;
- }
- }
-
- private static class Listener implements NotificationListener {
- public int received = 0;
- public int seqErr = 0;
-
- private long lastSeq = -1;
-
- public void handleNotification(Notification notif, Object handback) {
- if (!myType.equals(notif.getType())) {
- System.out.println(">>> EventManagerTest-Listener: got unexpected notif: "+notif);
- System.exit(1);
- }
-
- if (lastSeq == -1) {
- lastSeq = notif.getSequenceNumber();
- } else if (notif.getSequenceNumber() - lastSeq++ != 1) {
- seqErr++;
- }
-
- System.out.println(">>> ListenerTest-Listener: got notif "+notif.getSequenceNumber());
-
- synchronized(this) {
- if (++received >= sendNB) {
- this.notify();
- }
- }
-
- System.out.println(">>> ListenerTest-Listener: received = "+received);
- }
- }
-
- public static class NotificationEmitter extends NotificationBroadcasterSupport
- implements NotificationEmitterMBean {
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- final String[] ntfTypes = {myType};
-
- final MBeanNotificationInfo[] ntfInfoArray = {
- new MBeanNotificationInfo(ntfTypes,
- "javax.management.Notification",
- "Notifications sent by the NotificationEmitter")};
-
- return ntfInfoArray;
- }
-
- /**
- * Send Notification objects.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotifications(Integer nb) {
- Notification notif;
- for (int i=1; i<=nb.intValue(); i++) {
- notif = new Notification(myType, this, count++);
- //System.out.println(">>> ListenerTest-NotificationEmitter-sendNotifications: "+i);
-
- sendNotification(notif);
- }
- }
-
-
- }
-
- public interface NotificationEmitterMBean {
- public void sendNotifications(Integer nb);
- }
-
- private static int sendNB = 20;
- private static int count = 0;
-
- private static final String myType = "notification.my_notification";
-}
--- a/jdk/test/javax/management/eventService/MyFetchingEventForwarder.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * MyList.java
- *
- * Created on Oct 23, 2007, 2:45:57 PM
- *
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-/**
- *
- * @author sjiang
- */
-
-import java.io.IOException;
-import java.util.ArrayList;
-import javax.management.event.FetchingEventForwarder;
-
-public class MyFetchingEventForwarder extends FetchingEventForwarder {
-
- public MyFetchingEventForwarder() {
- super(1000);
- shared = this;
- setList(myList);
- }
-
- public void setAgain() {
- setList(myList);
- }
-
- public void setClientId(String clientId) throws IOException {
- used = true;
- super.setClientId(clientId);
- }
-
- public boolean isUsed() {
- return used;
- }
-
- private class MyList<TargetedNotification>
- extends ArrayList<TargetedNotification> {
-
- public boolean add(TargetedNotification e) {
- used = true;
-
- return super.add(e);
- }
- }
-
- public MyList myList = new MyList();
- public static MyFetchingEventForwarder shared;
- private boolean used = false;
-}
--- a/jdk/test/javax/management/eventService/NotSerializableNotifTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +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.
- *
- * 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.
- */
-
-
-/*
- * @test NotSerializableNotifTest.java 1.5 08/01/22
- * @bug 5108776
- * @summary Basic test for EventClient.
- * @author Shanliang JIANG
- * @run clean NotSerializableNotifTest
- * @run build NotSerializableNotifTest
- * @run main NotSerializableNotifTest
- */
-
-
-// JMX imports
-//
-import javax.management.* ;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.EventRelay;
-import javax.management.event.FetchingEventRelay;
-
-import javax.management.remote.*;
-import javax.management.remote.JMXServiceURL;
-
-public class NotSerializableNotifTest {
- private static MBeanServer mbeanServer =
- MBeanServerFactory.createMBeanServer();
- private static ObjectName emitter;
- private static int port = 2468;
-
- private static String[] protocols;
-
- private static final int sentNotifs = 50;
-
- public static void main(String[] args) throws Exception {
- System.out.println(">>> Test to send a not serializable notification");
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- NotificationEmitter nm = new NotificationEmitter();
- emitter = new ObjectName("Default:name=NotificationEmitter");
- mbeanServer.registerMBean(nm, emitter);
- String proto = "rmi";
-
- System.out.println(">>> Test for protocol " + proto);
-
- JMXServiceURL url = new JMXServiceURL(proto, null, 0);
-
- JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
-
- server.start();
-
- url = server.getAddress();
- JMXConnector conn = JMXConnectorFactory.connect(url, null);
- MBeanServerConnection client = conn.getMBeanServerConnection();
-
- EventClientDelegateMBean ecd = EventClientDelegate.getProxy(client);
- EventRelay eventRelay = new FetchingEventRelay(
- ecd,
- FetchingEventRelay.DEFAULT_BUFFER_SIZE,
- 10,
- FetchingEventRelay.DEFAULT_MAX_NOTIFICATIONS,
- null);
- EventClient ec = new EventClient(ecd, eventRelay, null, null,
- EventClient.DEFAULT_REQUESTED_LEASE_TIME);
-
- // add listener from the client side
- Listener listener = new Listener();
- ec.addNotificationListener(emitter, listener, null, null);
-
- LostListener lostListener = new LostListener();
- ec.addEventClientListener(lostListener, null, null);
-
- // ask to send one not serializable notif
- System.out.println(">>> sending not serializable notifs ...");
-
- Object[] params = new Object[] {new Integer(sentNotifs)};
- String[] signatures = new String[] {"java.lang.Integer"};
- client.invoke(emitter, "sendNotserializableNotifs", params, signatures);
-
-// nm.sendNotserializableNotifs(sentNotifs);
-// nm.sendNotifications(1);
-
- // waiting
- synchronized(lostListener) {
- if (lostListener.lostCount != sentNotifs) {
- lostListener.wait(6000);
- }
- }
-
- Thread.sleep(100);
-
- if (lostListener.lostCount != sentNotifs) {
- System.out.println(">>> FAILED. Expected "+sentNotifs+", but got "+lostListener.lostCount);
- System.exit(1);
- }
-
- System.out.println(">>> Passed.");
-
- ec.close();
- conn.close();
- server.stop();
- }
-
-
-//--------------------------
-// private classes
-//--------------------------
- private static class Listener implements NotificationListener {
- public void handleNotification(Notification n, Object handback) {
- System.out.println(">>> Listener: receive: "+n);
- }
- }
-
-
- private static class LostListener implements NotificationListener {
- public void handleNotification(Notification n, Object handback) {
- if (!EventClient.NOTIFS_LOST.equals(n.getType())) {
- return;
- }
-
- if (!(n.getUserData() instanceof Long)) {
- System.out.println(">>> Listener: JMXConnectionNotification userData " +
- "not a Long: " + n.getUserData());
- System.exit(1);
- } else {
- int lost = ((Long) n.getUserData()).intValue();
- lostCount += lost;
- if (lostCount >= sentNotifs) {
- synchronized(this) {
- this.notifyAll();
- }
- }
- }
-
- }
-
-
- private int lostCount = 0;
- }
-
- public static class NotificationEmitter extends NotificationBroadcasterSupport
- implements NotificationEmitterMBean {
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- final String[] ntfTypes = {myType};
-
- final MBeanNotificationInfo[] ntfInfoArray = {
- new MBeanNotificationInfo(ntfTypes,
- "javax.management.Notification",
- "Notifications sent by the NotificationEmitter")};
-
- return ntfInfoArray;
- }
-
- /**
- * Send not serializable Notifications.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotserializableNotifs(Integer nb) {
-
- Notification notif;
- for (int i=1; i<=nb.intValue(); i++) {
- notif = new Notification(myType, this, i);
-
- notif.setUserData(new Object());
- sendNotification(notif);
- }
- }
-
- /**
- * Send Notification objects.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotifications(Integer nb) {
- Notification notif;
- for (int i=1; i<=nb.intValue(); i++) {
- notif = new Notification(myType, this, i);
-
- sendNotification(notif);
- }
- }
-
- private final String myType = "notification.my_notification";
- }
-
- public interface NotificationEmitterMBean {
- public void sendNotifications(Integer nb);
-
- public void sendNotserializableNotifs(Integer nb);
- }
-}
--- a/jdk/test/javax/management/eventService/PublishTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +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.
- *
- * 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.
- */
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.*;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- *
- */
-public class PublishTest {
- private static MBeanServer mbeanServer;
- private static EventManager eventManager;
- private static ObjectName emitter;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
- private static JMXConnector conn;
- private static MBeanServerConnection client;
-
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) throws Exception {
- System.out.println(">>> PublishTest-main basic tests ...");
- mbeanServer = MBeanServerFactory.createMBeanServer();
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
- }
-
- eventManager = EventManager.getEventManager(mbeanServer);
-
- emitter = new ObjectName("Default:name=NotificationEmitter");
-
- url = new JMXServiceURL("rmi", null, 0) ;
- server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
- server.start();
-
- url = server.getAddress();
- conn = JMXConnectorFactory.connect(url, null);
- client = conn.getMBeanServerConnection();
-
- boolean succeed;
-
- System.out.println(">>> PublishTest-main: using the fetching EventRelay...");
- succeed = test(new EventClient(client));
-
- System.out.println(">>> PublishTest-main: using the pushing EventRelay...");
- succeed &= test(new EventClient(client,
- new RMIPushEventRelay(EventClientDelegate.getProxy(client)),
- null,
- EventClient.DEFAULT_LEASE_TIMEOUT));
-
- conn.close();
- server.stop();
-
- if (succeed) {
- System.out.println(">>> PublishTest-main: PASSE!");
- } else {
- System.out.println("\n>>> PublishTest-main: FAILED!");
- System.exit(1);
- }
- }
-
- public static boolean test(EventClient efClient) throws Exception {
- // add listener from the client side
- Listener listener = new Listener();
- efClient.subscribe(emitter, listener, null, null);
-
- ObjectName other = new ObjectName("Default:name=other");
- // publish notifs
- for (int i=0; i<sendNB; i++) {
- Notification notif = new Notification(myType, emitter, count++);
- Notification notif2 = new Notification(myType, other, 0);
- //System.out.println(">>> EventManagerService-NotificationEmitter-sendNotifications: "+i);
-
- eventManager.publish(emitter, notif);
- eventManager.publish(other, notif2); // should not received
- }
-
- // waiting
- long toWait = 6000;
- long stopTime = System.currentTimeMillis() + toWait;
-
- synchronized(listener) {
- while(listener.received < sendNB && toWait > 0) {
- listener.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- // clean
- efClient.unsubscribe(emitter, listener);
- efClient.close();
-
- if (listener.received != sendNB) {
- System.out.println(">>> PublishTest-test: FAILED! Expected to receive "+sendNB+", but got "+listener.received);
-
- return false;
- } else if (listener.seqErr > 0) {
- System.out.println(">>> PublishTest-test: FAILED! The receiving sequence is not correct.");
-
- return false;
- } else {
- System.out.println(">>> PublishTest-test: got all expected "+listener.received);
- return true;
- }
- }
-
- private static class Listener implements NotificationListener {
- public int received = 0;
- public int seqErr = 0;
-
- private long lastSeq = -1;
-
- public void handleNotification(Notification notif, Object handback) {
- if (!myType.equals(notif.getType())) {
- System.out.println(">>> PublishTest-Listener: got unexpected notif: "+notif);
- System.exit(1);
- } else if (!emitter.equals(notif.getSource())) {
- System.out.println(">>> PublishTest-Listener: unknown ObjectName: "+notif.getSource());
- System.exit(1);
- }
-
- if (lastSeq == -1) {
- lastSeq = notif.getSequenceNumber();
- } else if (notif.getSequenceNumber() - lastSeq++ != 1) {
- seqErr++;
- }
-
- System.out.println(">>> PublishTest-Listener: got notif "+notif.getSequenceNumber());
-
- synchronized(this) {
- if (++received >= sendNB) {
- this.notify();
- }
- }
-
- System.out.println(">>> PublishTest-Listener: received = "+received);
- }
- }
-
- private static int sendNB = 20;
- private static long count = 0;
-
- private static final String myType = "notification.my_notification";
-}
--- a/jdk/test/javax/management/eventService/ReconnectableConnectorTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,488 +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.
- *
- * 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.
- */
-
-/*
- * @test ReconnectableJMXConnector
- * @bug 5108776
- * @summary Check that the Event Service can be used to build a
- * ReconnectableJMXConnector.
- * @author Eamonn McManus
- */
-
-import java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Date;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.security.auth.Subject;
-
-/*
- * This test checks that it is possible to use the Event Service to create
- * a "reconnectable connector".
- *
- * In the JMX Remote API, we deliberately specified that a connector client
- * (JMXConnector) that encounters a network failure is then permanently broken.
- * The idea being that adding recovery logic to the basic connector client
- * would make it much more complicated and less reliable, and the logic would
- * in any case never correspond to what a given situation needs. Some of
- * the tough questions are: Should the connector try to mask the failure by
- * blocking operations until the failure is resolved? How long should the
- * connector try to reestablish the connection before giving up? Rather than
- * try to solve this problem in the connector, we suggested that people who
- * wanted to recover from network failures could implement the JMXConnector
- * interface themselves so that it forwards to a wrapped JMXConnector that can
- * be replaced in case of network failure.
- *
- * This works fine except that the connector client has state,
- * in the form of listeners added by the user through the
- * MBeanServerConnection.addNotificationListener method. It's possible
- * for the wrapper to keep track of these listeners as well as forwarding
- * them to the wrapped JMXConnector, so that it can reapply them to
- * a replacement JMXConnector after failure recover. But it's quite
- * tricky, particularly because of the two- and four-argument versions of
- * removeNotificationListener.
- *
- * The Event Service can take care of this for you through the EventClient
- * class. Listeners added through that class are implemented in a way that
- * doesn't require the connector client to maintain any state, so they should
- * continue to work transparently after replacing the wrapped JMXConnector.
- * This test is a proof of concept that shows it works. Quite a number of
- * details would need to be changed to build a reliable reconnectable
- * connector.
- *
- * The test simulates network failure by rewrapping the wrapped JMXConnector's
- * MBeanServerConnection (MBSC) in a "breakable" MBSC which we can cause
- * to stop working. We do this in two phases. The first phase suspends
- * any MBSC calls just at the point where they would return to the caller.
- * The goal here is to block an EventClientDelegateMBean.fetchNotifications
- * operation when it has received notifications but not yet delivered them
- * to the EventClient. This is the most delicate point where a breakage
- * can occur, because the EventClientDelegate must not drop those notifs
- * from its buffer until another fetchNotifs call arrives with a later
- * sequence number (which is an implicit ack of the previous set of
- * notifs). Once the fetchNotifs call is suspended, we "kill" the MBSC,
- * causing it to throw IOException from this and any other calls. That
- * triggers the reconnect logic, which will make a new MBSC and issue
- * the same fetchNotifs call to it.
- *
- * The test could be improved by synchronizing explicitly between the
- * breakable MBSC and the mainline, so we only proceed to kill the MBSC
- * when we are sure that the fetchNotifs call is blocked. As it is,
- * we have a small delay which both ensures that no notifs are delivered
- * while the connection is suspended, and if the machine is fast enough
- * allows the fetchNotifs call to reach the blocking point.
- */
-public class ReconnectableConnectorTest {
- private static class ReconnectableJMXConnector implements JMXConnector {
- private final JMXServiceURL url;
- private AtomicReference<JMXConnector> wrappedJMXC =
- new AtomicReference<JMXConnector>();
- private AtomicReference<MBeanServerConnection> wrappedMBSC =
- new AtomicReference<MBeanServerConnection>();
- private final NotificationBroadcasterSupport broadcaster =
- new NotificationBroadcasterSupport();
- private final Lock connectLock = new ReentrantLock();
-
- ReconnectableJMXConnector(JMXServiceURL url) {
- this.url = url;
- }
-
- private class ReconnectIH implements InvocationHandler {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- try {
- return method.invoke(wrappedMBSC.get(), args);
- } catch (InvocationTargetException e) {
- if (e.getCause() instanceof IOException) {
- connect();
- try {
- return method.invoke(wrappedMBSC.get(),args);
- } catch (InvocationTargetException ee) {
- throw ee.getCause();
- }
- }
- throw e.getCause();
- }
- }
- }
-
- private class FailureListener implements NotificationListener {
- public void handleNotification(Notification n, Object h) {
- String type = n.getType();
- if (type.equals(JMXConnectionNotification.FAILED)) {
- try {
- connect();
- } catch (IOException e) {
- broadcaster.sendNotification(n);
- }
- } else if (type.equals(JMXConnectionNotification.NOTIFS_LOST))
- broadcaster.sendNotification(n);
- }
- }
-
- public void connect() throws IOException {
- connectLock.lock();
- try {
- connectWithLock();
- } finally {
- connectLock.unlock();
- }
- }
-
- private void connectWithLock() throws IOException {
- MBeanServerConnection mbsc = wrappedMBSC.get();
- if (mbsc != null) {
- try {
- mbsc.getDefaultDomain();
- return; // the connection works
- } catch (IOException e) {
- // OK: the connection doesn't work, so make a new one
- }
- }
- // This is where we would need to add the fancy logic that
- // allows the connection to keep failing for a while
- // before giving up.
- JMXConnector jmxc = JMXConnectorFactory.connect(url);
- jmxc.addConnectionNotificationListener(
- new FailureListener(), null, null);
- wrappedJMXC.set(jmxc);
- if (false)
- wrappedMBSC.set(jmxc.getMBeanServerConnection());
- else {
- mbsc = jmxc.getMBeanServerConnection();
- InvocationHandler ih = new BreakableIH(mbsc);
- mbsc = (MBeanServerConnection) Proxy.newProxyInstance(
- MBeanServerConnection.class.getClassLoader(),
- new Class<?>[] {MBeanServerConnection.class},
- ih);
- wrappedMBSC.set(mbsc);
- }
- }
-
- private BreakableIH breakableIH() {
- MBeanServerConnection mbsc = wrappedMBSC.get();
- return (BreakableIH) Proxy.getInvocationHandler(mbsc);
- }
-
- void suspend() {
- BreakableIH ih = breakableIH();
- ih.suspend();
- }
-
- void kill() throws IOException {
- BreakableIH ih = breakableIH();
- wrappedJMXC.get().close();
- ih.kill();
- }
-
- public void connect(Map<String, ?> env) throws IOException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- private final AtomicReference<MBeanServerConnection> mbscRef =
- new AtomicReference<MBeanServerConnection>();
-
- public MBeanServerConnection getMBeanServerConnection()
- throws IOException {
- connect();
- // Synchro here is not strictly correct: two threads could make
- // an MBSC at the same time. OK for a test but beware for real
- // code.
- MBeanServerConnection mbsc = mbscRef.get();
- if (mbsc != null)
- return mbsc;
- mbsc = (MBeanServerConnection) Proxy.newProxyInstance(
- MBeanServerConnection.class.getClassLoader(),
- new Class<?>[] {MBeanServerConnection.class},
- new ReconnectIH());
- mbsc = EventClient.getEventClientConnection(mbsc);
- mbscRef.set(mbsc);
- return mbsc;
- }
-
- public MBeanServerConnection getMBeanServerConnection(
- Subject delegationSubject) throws IOException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void close() throws IOException {
- wrappedJMXC.get().close();
- }
-
- public void addConnectionNotificationListener(
- NotificationListener l, NotificationFilter f, Object h) {
- broadcaster.addNotificationListener(l, f, h);
- }
-
- public void removeConnectionNotificationListener(NotificationListener l)
- throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(l);
- }
-
- public void removeConnectionNotificationListener(
- NotificationListener l, NotificationFilter f, Object h)
- throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(l, f, h);
- }
-
- public String getConnectionId() throws IOException {
- return wrappedJMXC.get().getConnectionId();
- }
- }
-
- // InvocationHandler that allows us to perform a two-phase "break" of
- // an object. The first phase suspends the object, so that calls to
- // it are blocked just before they return. The second phase unblocks
- // suspended threads and causes them to throw IOException.
- private static class BreakableIH implements InvocationHandler {
- private final Object wrapped;
- private final Holder<String> state = new Holder<String>("running");
-
- BreakableIH(Object wrapped) {
- this.wrapped = wrapped;
- }
-
- void suspend() {
- state.set("suspended");
- }
-
- void kill() {
- state.set("killed");
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- Object result;
- try {
- result = method.invoke(wrapped, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- String s = state.get();
- if (s.equals("suspended"))
- state.waitUntilEqual("killed", 3, TimeUnit.SECONDS);
- else if (s.equals("killed"))
- throw new IOException("Broken");
- return result;
- }
- }
-
- private static class Holder<T> {
- private T held;
- private Lock lock = new ReentrantLock();
- private Condition changed = lock.newCondition();
-
- Holder(T value) {
- lock.lock();
- this.held = value;
- lock.unlock();
- }
-
- void waitUntilEqual(T value, long timeout, TimeUnit units)
- throws InterruptedException {
- long millis = units.toMillis(timeout);
- long stop = System.currentTimeMillis() + millis;
- Date stopDate = new Date(stop);
- lock.lock();
- try {
- while (!value.equals(held)) {
- boolean ok = changed.awaitUntil(stopDate);
- if (!ok)
- throw new InterruptedException("Timed out");
- }
- } finally {
- lock.unlock();
- }
- }
-
- void set(T value) {
- lock.lock();
- try {
- held = value;
- changed.signalAll();
- } finally {
- lock.unlock();
- }
- }
-
- T get() {
- lock.lock();
- try {
- return held;
- } finally {
- lock.unlock();
- }
- }
- }
-
- private static class StoreListener implements NotificationListener {
- final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue<Notification>(100);
-
- public void handleNotification(Notification n, Object h) {
- queue.add(n);
- }
-
- Notification nextNotification(long time, TimeUnit units)
- throws InterruptedException {
- Notification n = queue.poll(time, units);
- if (n == null)
- throw new NoSuchElementException("Notification wait timed out");
- return n;
- }
-
- int notifCount() {
- return queue.size();
- }
- }
-
- public static interface SenderMBean {}
- public static class Sender
- extends NotificationBroadcasterSupport implements SenderMBean {
- private AtomicLong seqNo = new AtomicLong(0);
-
- void send() {
- Notification n =
- new Notification("type", this, seqNo.getAndIncrement());
- sendNotification(n);
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- Sender sender = new Sender();
- ObjectName name = new ObjectName("a:b=c");
- mbs.registerMBean(sender, name);
-
- System.out.println("Creating connector server");
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
- url, null, mbs);
- cs.start();
-
- StoreListener csListener = new StoreListener();
- cs.addNotificationListener(csListener, null, null);
-
- System.out.println("Creating reconnectable client");
- JMXServiceURL addr = cs.getAddress();
- ReconnectableJMXConnector cc = new ReconnectableJMXConnector(addr);
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
-
- System.out.println("Checking server has sent new-client notif");
- Notification csn = csListener.nextNotification(1, TimeUnit.SECONDS);
- assertEquals("CS notif type",
- JMXConnectionNotification.OPENED, csn.getType());
-
- StoreListener listener = new StoreListener();
- mbsc.addNotificationListener(name, listener, null, null);
-
- System.out.println("Sending 10 notifs and checking they are received");
- for (int i = 0; i < 10; i++)
- sender.send();
- checkNotifs(listener, 0, 10);
-
- System.out.println("Suspending the fetchNotifs operation");
- cc.suspend();
- System.out.println("Sending a notif while fetchNotifs is suspended");
- sender.send();
- System.out.println("Brief wait before checking no notif is received");
- Thread.sleep(2);
- // dumpThreads();
- assertEquals("notif queue while connector suspended",
- 0, listener.notifCount());
- assertEquals("connector server notif queue while connector suspended",
- 0, csListener.notifCount());
-
- System.out.println("Breaking the connection so fetchNotifs will fail over");
- cc.kill();
-
- System.out.println("Checking that client has reconnected");
- csn = csListener.nextNotification(1, TimeUnit.SECONDS);
- assertEquals("First CS notif type after kill",
- JMXConnectionNotification.CLOSED, csn.getType());
- csn = csListener.nextNotification(1, TimeUnit.SECONDS);
- assertEquals("Second CS notif type after kill",
- JMXConnectionNotification.OPENED, csn.getType());
-
- System.out.println("Checking that suspended notif has been received");
- checkNotifs(listener, 10, 11);
- }
-
- private static void checkNotifs(
- StoreListener sl, long start, long stop)
- throws Exception {
- for (long i = start; i < stop; i++) {
- Notification n = sl.nextNotification(1, TimeUnit.SECONDS);
- assertEquals("received sequence number", i, n.getSequenceNumber());
- }
- }
-
- private static void assertEquals(String what, Object expect, Object actual)
- throws Exception {
- if (!expect.equals(actual)) {
- fail(what + " should be " + expect + " but is " + actual);
- }
- }
-
- private static void fail(String why) throws Exception {
- throw new Exception("TEST FAILED: " + why);
- }
-
- private static void dumpThreads() {
- System.out.println("Thread stack dump");
- Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
- for (Map.Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
- Thread t = entry.getKey();
- System.out.println("===Thread " + t.getName() + "===");
- for (StackTraceElement ste : entry.getValue())
- System.out.println(" " + ste);
- }
- }
-}
--- a/jdk/test/javax/management/eventService/SharingThreadTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +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.
- *
- * 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.
- */
-
-/*
- * @test SharingThreadTest.java 1.3 08/01/22
- * @bug 5108776
- * @summary Basic test for EventClient to see internal thread management.
- * @author Shanliang JIANG
- * @run clean SharingThreadTest
- * @run build SharingThreadTest
- * @run main SharingThreadTest
- */
-
-import java.io.IOException;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventClient;
-import javax.management.event.EventClientDelegate;
-import javax.management.event.EventClientDelegateMBean;
-import javax.management.event.FetchingEventRelay;
-import javax.management.event.RMIPushEventRelay;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-
-public class SharingThreadTest {
-
- private static MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
- private static ObjectName emitter;
- private static NotificationEmitter emitterImpl;
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
-
-
- private static int toSend = 10;
- private static final long bigWaiting = 6000;
- private static int counter = 0;
- private static int jobs = 10;
- private static int endedJobs = 0;
-
- private static volatile String failure;
-
- private static Executor sharedExecutor = new ThreadPoolExecutor(0, 1, 1000,
- TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(jobs));
- //Executors.newFixedThreadPool(1);
-
- public static void main(String[] args) throws Exception {
- System.out.println(">>> Test on sharing threads for multiple EventClient.");
-
- // for 1.5
- if (System.getProperty("java.version").startsWith("1.5") &&
- !mbeanServer.isRegistered(EventClientDelegateMBean.OBJECT_NAME)) {
- System.out.print("Working on "+System.getProperty("java.version")+
- " register "+EventClientDelegateMBean.OBJECT_NAME);
-
- mbeanServer.registerMBean(EventClientDelegate.
- getEventClientDelegate(mbeanServer),
- EventClientDelegateMBean.OBJECT_NAME);
-
- sharedExecutor = new ThreadPoolExecutor(1, 1, 1000,
- TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(jobs));
- }
-
- emitter = new ObjectName("Default:name=NotificationEmitter");
- emitterImpl = new NotificationEmitter();
- mbeanServer.registerMBean(emitterImpl, emitter);
-
- String[] types = new String[]{"PushEventRelay", "FetchingEventRelay"};
- String[] protos = new String[]{"rmi", "iiop", "jmxmp"};
- for (String prot : protos) {
- url = new JMXServiceURL(prot, null, 0);
-
- try {
- server =
- JMXConnectorServerFactory.newJMXConnectorServer(url,
- null, mbeanServer);
- server.start();
- } catch (Exception e) {
- System.out.println(">>> Skip "+prot+", not support.");
- continue;
- }
-
- url = server.getAddress();
-
- // noise
- Thread noise = new Thread(new Runnable() {
- public void run() {
- while (true) {
- emitterImpl.sendNotif(1, null);
- try {
- Thread.sleep(10);
- } catch (Exception e) {
- // OK
- }
- }
- }
- });
- noise.setDaemon(true);
- noise.start();
-
- try {
- for (String type: types) {
- System.out.println("\n\n>>> Testing "+type+" on "+url+" ...");
- JMXConnector conn = newConn();
- try {
- testType(type, conn);
- } finally {
- conn.close();
- System.out.println(">>> Testing "+type+" on "+url+" ... done");
- }
- }
- } finally {
- server.stop();
- }
- }
- }
-
- private static void testType(String type, JMXConnector conn) throws Exception {
- Thread[] threads = new Thread[jobs];
- for (int i=0; i<jobs; i++) {
- threads[i] = new Thread(new Job(type, conn));
- threads[i].setDaemon(true);
- threads[i].start();
- }
-
- // to wait
- long toWait = bigWaiting*jobs;
- long stopTime = System.currentTimeMillis() + toWait;
-
- synchronized(SharingThreadTest.class) {
- while (endedJobs < jobs && toWait > 0 && failure == null) {
- SharingThreadTest.class.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
-
- if (endedJobs != jobs && failure == null) {
- throw new RuntimeException("Need to set bigger waiting timeout?");
- }
-
- endedJobs = 0;
- }
-
- public static class Job implements Runnable {
- public Job(String type, JMXConnector conn) {
- this.type = type;
- this.conn = conn;
- }
- public void run() {
- try {
- test(type, conn);
-
- synchronized(SharingThreadTest.class) {
- endedJobs++;
- if (endedJobs>=jobs) {
- SharingThreadTest.class.notify();
- }
- }
- } catch (RuntimeException re) {
- re.printStackTrace(System.out);
- throw re;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private final String type;
- private final JMXConnector conn;
- }
-
- private static void test(String type, JMXConnector conn) throws Exception {
- String id = getId();
-
- Listener listener = new Listener(id);
- Filter filter = new Filter(id);
-
- //newConn();
- EventClient ec = newEventClient(type, conn);
-
- System.out.println(">>> ("+id+") To receive notifications "+toSend);
- ec.addNotificationListener(emitter,
- listener, filter, null);
-
- emitterImpl.sendNotif(toSend, id);
- listener.waitNotifs(bigWaiting, toSend);
- if (listener.received != toSend) {
- throw new RuntimeException(">>> ("+id+") Expected to receive: "
- +toSend+", but got: "+listener.received);
- }
-
- ec.close();
- }
-
-//--------------------------
-// private classes
-//--------------------------
-
- private static class Listener implements NotificationListener {
- public Listener(String id) {
- this.id = id;
- }
- public void handleNotification(Notification notif, Object handback) {
- if (!id.equals(notif.getUserData())) {
- System.out.println("("+id+") Filter error, my id is: "+id+
- ", but got "+notif.getUserData());
- System.exit(1);
- }
- System.out.println("("+id+") received "+notif.getSequenceNumber());
- synchronized (this) {
- received++;
-
- if (sequenceNB < 0) {
- sequenceNB = notif.getSequenceNumber();
- } else if(++sequenceNB != notif.getSequenceNumber()) {
- fail("(" + id + ") Wrong sequence number, expected: "
- +sequenceNB+", but got: "+notif.getSequenceNumber());
- }
- if (received >= toSend || failure != null) {
- this.notify();
- }
- }
- }
-
- public void waitNotifs(long timeout, int nb) throws Exception {
- long toWait = timeout;
- long stopTime = System.currentTimeMillis() + timeout;
- synchronized(this) {
- while (received < nb && toWait > 0 && failure == null) {
- this.wait(toWait);
- toWait = stopTime - System.currentTimeMillis();
- }
- }
- }
-
- private String id;
- private int received = 0;
-
- private long sequenceNB = -1;
- }
-
- private static class Filter implements NotificationFilter {
- public Filter(String id) {
- this.id = id;
- }
-
- public boolean isNotificationEnabled(Notification n) {
- return id.equals(n.getUserData());
- }
- private String id;
- }
-
- public static class NotificationEmitter extends NotificationBroadcasterSupport
- implements NotificationEmitterMBean {
-
- /**
- * Send Notification objects.
- *
- * @param nb The number of notifications to send
- */
- public void sendNotif(int nb, String userData) {
- new Thread(new SendJob(nb, userData)).start();
- }
-
- private class SendJob implements Runnable {
- public SendJob(int nb, String userData) {
- this.nb = nb;
- this.userData = userData;
- }
-
- public void run() {
- if (userData != null) {
- System.out.println(">>> ("+userData+") sending "+nb);
- }
- long sequenceNumber = 0;
- for (int i = 0; i<nb; i++) {
- Notification notif = new Notification(myType, emitter,
- sequenceNumber++);
- notif.setUserData(userData);
- sendNotification(notif);
- Thread.yield();
- try {
- Thread.sleep(1);
- } catch (Exception e) {}
- }
- if (userData != null) {
- System.out.println(">>> ("+userData+") sending done");
- }
- }
- private int nb;
- private String userData;
- }
- private final String myType = "notification.my_notification";
- }
-
- public interface NotificationEmitterMBean {
- public void sendNotif(int nb, String userData);
- }
-
- private static JMXConnector newConn() throws IOException {
- return JMXConnectorFactory.connect(url);
- }
-
- private static EventClient newEventClient(String type, JMXConnector conn)
- throws Exception {
- EventClientDelegateMBean proxy =
- EventClientDelegate.getProxy(conn.getMBeanServerConnection());
- if (type.equals("PushEventRelay")) {
- return new EventClient(proxy,
- new RMIPushEventRelay(proxy), sharedExecutor, null, 600);
- } else if (type.equals("FetchingEventRelay")) {
- return new EventClient(proxy,
- new FetchingEventRelay(proxy,
- FetchingEventRelay.DEFAULT_BUFFER_SIZE,
- 10,
- FetchingEventRelay.DEFAULT_MAX_NOTIFICATIONS,
- sharedExecutor),
- null, null, 600);
- } else {
- throw new RuntimeException("Wrong event client type: "+type);
- }
- }
-
- private static String getId() {
- synchronized(SharingThreadTest.class) {
- return String.valueOf(counter++);
- }
- }
-
- private static void fail(String msg) {
- System.out.println("FAIL: " + msg);
- failure = msg;
- }
-}
--- a/jdk/test/javax/management/eventService/SubUnsubTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +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.
- *
- * 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.
- */
-
-/*
- * @test SubUnsubTest
- * @bug 6736611
- * @summary Test not to remove other listeners when calling unsubscribe
- * @author Shanliang JIANG
- * @run clean SubUnsubTest
- * @run build SubUnsubTest
- * @run main SubUnsubTest
- */
-
-import java.lang.management.ManagementFactory;
-import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventSubscriber;
-import javax.management.event.EventClient;
-public class SubUnsubTest {
- private static class CountListener implements NotificationListener {
- volatile int count;
-
- public void handleNotification(Notification n, Object h) {
- count++;
- }
- }
-
- public static interface SenderMBean {}
-
- public static class Sender extends NotificationBroadcasterSupport
- implements SenderMBean {
- void send() {
- Notification n = new Notification("type", this, 1L);
- sendNotification(n);
- }
- }
-
- public static void main(String[] args) throws Exception {
- System.out.println("Testing EventSubscriber-unsubscribe method.");
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name1 = new ObjectName("d:type=Sender,id=1");
- ObjectName name2 = new ObjectName("d:type=Sender,id=2");
- ObjectName pattern = new ObjectName("d:type=Sender,*");
- Sender sender1 = new Sender();
- Sender sender2 = new Sender();
- mbs.registerMBean(sender1, name1);
- mbs.registerMBean(sender2, name2);
-
- EventSubscriber sub = EventSubscriber.getEventSubscriber(mbs);
-
- System.out.println("Single subscribe covering both MBeans");
- CountListener listener = new CountListener();
-
- System.out.println("Subscribing and adding listeners ...");
- sub.subscribe(pattern, listener, null, null);
- sub.subscribe(name2, listener, null, null);
- mbs.addNotificationListener(name2, listener, null, null);
-
- sender1.send();
- sender2.send();
- if (listener.count != 4) {
- throw new RuntimeException("Do not receive all notifications: "+
- "Expect 4, got "+listener.count);
- }
-
- System.out.println("Unsubscribe the listener with the pattern.");
- sub.unsubscribe(pattern, listener);
- listener.count = 0;
- sender1.send();
- sender2.send();
- if (listener.count != 2) {
- throw new RuntimeException("The method unsubscribe removes wrong listeners.");
- }
-
- System.out.println("Unsubscribe the listener with the ObjectName.");
- sub.unsubscribe(name2, listener);
- listener.count = 0;
- sender1.send();
- sender2.send();
- if (listener.count != 1) {
- throw new RuntimeException("The method unsubscribe removes wrong listeners.");
- }
-
- System.out.println("Subscribe twice to same MBean with same listener " +
- "but different handback.");
- sub.subscribe(name1, listener, null, new Object());
- sub.subscribe(name1, listener, null, new Object());
- listener.count = 0;
-
- sub.unsubscribe(name1, listener);
- sender1.send();
- if (listener.count > 0) {
- throw new RuntimeException("EventSubscriber: the method unsubscribe" +
- " does not remove a listener which was subscribed 2 times.");
- }
-
- System.out.println("Bye bye!");
- return;
- }
-}
\ No newline at end of file
--- a/jdk/test/javax/management/eventService/SubscribeTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5108776
- * @summary Test that EventSubscriber.subscribe works
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventSubscriber;
-
-public class SubscribeTest {
- private static class CountListener implements NotificationListener {
- volatile int count;
-
- public void handleNotification(Notification n, Object h) {
- count++;
- }
- }
-
- private static class SwitchFilter implements NotificationFilter {
- volatile boolean enabled;
-
- public boolean isNotificationEnabled(Notification n) {
- return enabled;
- }
- }
-
- public static interface SenderMBean {}
-
- public static class Sender extends NotificationBroadcasterSupport
- implements SenderMBean {
- void send() {
- Notification n = new Notification("type", this, 1L);
- sendNotification(n);
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name1 = new ObjectName("d:type=Sender,id=1");
- ObjectName name2 = new ObjectName("d:type=Sender,id=2");
- ObjectName pattern = new ObjectName("d:type=Sender,*");
- Sender sender1 = new Sender();
- Sender sender2 = new Sender();
- mbs.registerMBean(sender1, name1);
- mbs.registerMBean(sender2, name2);
-
- EventSubscriber sub = EventSubscriber.getEventSubscriber(mbs);
-
- System.out.println("Single subscribe covering both MBeans");
- CountListener listen1 = new CountListener();
- sub.subscribe(pattern, listen1, null, null);
- sender1.send();
- assertEquals("Notifs after sender1 send", 1, listen1.count);
- sender2.send();
- assertEquals("Notifs after sender2 send", 2, listen1.count);
-
- System.out.println("Unsubscribe");
- sub.unsubscribe(pattern, listen1);
- sender1.send();
- assertEquals("Notifs after sender1 send", 2, listen1.count);
-
- System.out.println("Subscribe twice to same MBean with same listener " +
- "but different filters");
- SwitchFilter filter1 = new SwitchFilter();
- sub.subscribe(name1, listen1, null, null);
- sub.subscribe(name1, listen1, filter1, null);
- listen1.count = 0;
- sender1.send();
- // switch is off, so only one notif expected
- assertEquals("Notifs after sender1 send", 1, listen1.count);
- filter1.enabled = true;
- sender1.send();
- // switch is on, so two more notifs expected
- assertEquals("Notifs after sender1 send", 3, listen1.count);
-
- System.out.println("Remove those subscriptions");
- sub.unsubscribe(name1, listen1);
- sender1.send();
- assertEquals("Notifs after sender1 send", 3, listen1.count);
- }
-
- private static void assertEquals(String what, Object expected, Object actual)
- throws Exception {
- if (!equal(expected, actual)) {
- String msg = "Expected " + expected + "; got " + actual;
- throw new Exception("TEST FAILED: " + what + ": " + msg);
- }
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null)
- return false;
- return (x.equals(y));
- }
-}
--- a/jdk/test/javax/management/eventService/UsingEventService.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +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.
- *
- * 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.
- */
-
-/*
- * @test UsingEventService.java 1.10 08/01/22
- * @bug 5108776
- * @summary Basic test for EventManager.
- * @author Shanliang JIANG
- * @run clean UsingEventService
- * @run build UsingEventService
- * @run main UsingEventService
- */
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.event.EventConsumer;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class UsingEventService {
- private static JMXServiceURL url;
- private static JMXConnectorServer server;
- private static JMXConnector conn;
- private static MBeanServerConnection client;
-
- public static void main(String[] args) throws Exception {
- if (System.getProperty("java.version").startsWith("1.5")) {
- System.out.println(">>> UsingEventService-main not available for JDK1.5, bye");
- return;
- }
-
- ObjectName oname = new ObjectName("test:t=t");
- Notification n = new Notification("", oname, 0);
-
- System.out.println(">>> UsingEventService-main basic tests ...");
- MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
-
- url = new JMXServiceURL("rmi", null, 0) ;
- JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
- server.start();
- url = server.getAddress();
-
- System.out.println(">>> UsingEventService-main test to not use the event service...");
- conn = JMXConnectorFactory.connect(url, null);
- client = conn.getMBeanServerConnection();
-
- System.out.println(">>> UsingEventService-main test to use the event service...");
- Map env = new HashMap(1);
- env.put("jmx.remote.use.event.service", "true");
- conn = JMXConnectorFactory.connect(url, env);
- client = conn.getMBeanServerConnection();
-
- ((EventConsumer)client).subscribe(oname, listener, null, null);
-
- System.out.println(">>> UsingEventService-main using event service as expected!");
-
- System.out.println(">>> UsingEventService-main test to use" +
- " the event service with system property...");
-
- System.setProperty("jmx.remote.use.event.service", "true");
- conn = JMXConnectorFactory.connect(url, null);
- client = conn.getMBeanServerConnection();
-
- ((EventConsumer)client).subscribe(oname, listener, null, null);
-
- System.out.println("" +
- ">>> UsingEventService-main using event service as expected!");
-
- System.out.println(">>> Happy bye bye!");
- }
-
- private final static NotificationListener listener = new NotificationListener() {
- public void handleNotification(Notification n, Object hk) {
- //
- }
- };
-}
--- a/jdk/test/javax/management/interop/MBeanExceptionInteropTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6456269
- * @summary Test that an MBeanException serialized on JDK 6 deserializes
- * correctly on JDK 7.
- * @author Eamonn McManus
- */
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import javax.management.MBeanException;
-
-// In JDK 6, the Throwable.cause field was always null for an MBeanException,
-// but it didn't matter because we overrode getCause() to return
-// MBeanException.exception instead. In JDK 7, we no longer override getCause()
-// because MBeanException doubles as the serial form of GenericMBeanException.
-// So we need some care to make sure that objects deserialized from JDK 6
-// have the right getCause() behaviour.
-public class MBeanExceptionInteropTest {
- private static final byte[] SERIALIZED_MBEAN_EXCEPTION = {
- -84,-19,0,5,115,114,0,31,106,97,118,97,120,46,109,97,
- 110,97,103,101,109,101,110,116,46,77,66,101,97,110,69,120,
- 99,101,112,116,105,111,110,56,110,-116,-27,110,87,49,-50,2,
- 0,1,76,0,9,101,120,99,101,112,116,105,111,110,116,0,
- 21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,
- 112,116,105,111,110,59,120,114,0,28,106,97,118,97,120,46,
- 109,97,110,97,103,101,109,101,110,116,46,74,77,69,120,99,
- 101,112,116,105,111,110,4,-35,76,-20,-109,-99,126,113,2,0,
- 0,120,114,0,19,106,97,118,97,46,108,97,110,103,46,69,
- 120,99,101,112,116,105,111,110,-48,-3,31,62,26,59,28,-60,
- 2,0,0,120,114,0,19,106,97,118,97,46,108,97,110,103,
- 46,84,104,114,111,119,97,98,108,101,-43,-58,53,39,57,119,
- -72,-53,3,0,3,76,0,5,99,97,117,115,101,116,0,21,
- 76,106,97,118,97,47,108,97,110,103,47,84,104,114,111,119,
- 97,98,108,101,59,76,0,13,100,101,116,97,105,108,77,101,
- 115,115,97,103,101,116,0,18,76,106,97,118,97,47,108,97,
- 110,103,47,83,116,114,105,110,103,59,91,0,10,115,116,97,
- 99,107,84,114,97,99,101,116,0,30,91,76,106,97,118,97,
- 47,108,97,110,103,47,83,116,97,99,107,84,114,97,99,101,
- 69,108,101,109,101,110,116,59,120,112,113,0,126,0,8,116,
- 0,7,79,104,32,100,101,97,114,117,114,0,30,91,76,106,
- 97,118,97,46,108,97,110,103,46,83,116,97,99,107,84,114,
- 97,99,101,69,108,101,109,101,110,116,59,2,70,42,60,60,
- -3,34,57,2,0,0,120,112,0,0,0,2,115,114,0,27,
- 106,97,118,97,46,108,97,110,103,46,83,116,97,99,107,84,
- 114,97,99,101,69,108,101,109,101,110,116,97,9,-59,-102,38,
- 54,-35,-123,2,0,4,73,0,10,108,105,110,101,78,117,109,
- 98,101,114,76,0,14,100,101,99,108,97,114,105,110,103,67,
- 108,97,115,115,113,0,126,0,6,76,0,8,102,105,108,101,
- 78,97,109,101,113,0,126,0,6,76,0,10,109,101,116,104,
- 111,100,78,97,109,101,113,0,126,0,6,120,112,0,0,0,
- 63,116,0,25,77,66,101,97,110,69,120,99,101,112,116,105,
- 111,110,73,110,116,101,114,111,112,84,101,115,116,116,0,30,
- 77,66,101,97,110,69,120,99,101,112,116,105,111,110,73,110,
- 116,101,114,111,112,84,101,115,116,46,106,97,118,97,116,0,
- 5,119,114,105,116,101,115,113,0,126,0,12,0,0,0,46,
- 113,0,126,0,14,113,0,126,0,15,116,0,4,109,97,105,
- 110,120,115,114,0,34,106,97,118,97,46,108,97,110,103,46,
- 73,108,108,101,103,97,108,65,114,103,117,109,101,110,116,69,
- 120,99,101,112,116,105,111,110,-75,-119,115,-45,125,102,-113,-68,
- 2,0,0,120,114,0,26,106,97,118,97,46,108,97,110,103,
- 46,82,117,110,116,105,109,101,69,120,99,101,112,116,105,111,
- 110,-98,95,6,71,10,52,-125,-27,2,0,0,120,113,0,126,
- 0,3,113,0,126,0,21,116,0,3,66,97,100,117,113,0,
- 126,0,10,0,0,0,2,115,113,0,126,0,12,0,0,0,
- 62,113,0,126,0,14,113,0,126,0,15,113,0,126,0,16,
- 115,113,0,126,0,12,0,0,0,46,113,0,126,0,14,113,
- 0,126,0,15,113,0,126,0,18,120,
- };
-
- private static volatile String failure;
-
- public static void main(String[] args) throws Exception {
- if (args.length > 0) {
- if (args[0].equals("write") && args.length == 1) {
- write();
- return;
- } else {
- System.err.println(
- "Usage: java MBeanExceptionInteropTest");
- System.err.println(
- "or: java MBeanExceptionInteropTest write");
- System.exit(1);
- }
- }
-
- // Read the serialized object and check it is correct.
- ByteArrayInputStream bin =
- new ByteArrayInputStream(SERIALIZED_MBEAN_EXCEPTION);
- ObjectInputStream oin = new ObjectInputStream(bin);
- MBeanException mbeanEx = (MBeanException) oin.readObject();
- assertEquals("MBeanException message", "Oh dear", mbeanEx.getMessage());
- System.out.println("getCause(): " + mbeanEx.getCause() + "; " +
- "getTargetException(): " + mbeanEx.getTargetException());
- for (Throwable t :
- new Throwable[] {mbeanEx.getCause(), mbeanEx.getTargetException()}) {
- if (!(t instanceof IllegalArgumentException))
- fail("Nested exception not an IllegalArgumentException: " + t);
- else
- assertEquals("Nested exception message", "Bad", t.getMessage());
- }
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- // Write a file that can be inserted into this source file as the
- // contents of the SERIALIZED_MBEAN_EXCEPTION array. Run this program
- // on JDK 6 to generate the array, then test on JDK 7.
- private static void write() throws Exception {
- Exception wrapped = new IllegalArgumentException("Bad");
- MBeanException mbeanEx = new MBeanException(wrapped, "Oh dear");
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(mbeanEx);
- oout.close();
- byte[] bytes = bout.toByteArray();
- for (int i = 0; i < bytes.length; i++) {
- System.out.printf("%d,", bytes[i]);
- if (i % 16 == 15)
- System.out.println();
- }
- if (bytes.length % 16 != 0)
- System.out.println();
- }
-
- private static void assertEquals(String what, Object expect, Object actual) {
- boolean equal = (expect == null) ? (actual == null) : expect.equals(actual);
- if (equal)
- System.out.println("OK: " + what + ": " + expect);
- else
- fail(what + ": expected " + expect + ", got " + actual);
- }
-
- private static void fail(String why) {
- System.out.println("FAIL: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/modelmbean/DefaultDescriptorFieldTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright 2007 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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6252592 4967755
- * @summary Check that default fields are correctly added to Descriptors
- * and that input Descriptors are never modified
- * @author Lars Westergren
- */
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import javax.management.Descriptor;
-import javax.management.IntrospectionException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanConstructorInfo;
-import javax.management.MBeanException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.RuntimeOperationsException;
-import javax.management.modelmbean.DescriptorSupport;
-import javax.management.modelmbean.ModelMBeanAttributeInfo;
-import javax.management.modelmbean.ModelMBeanConstructorInfo;
-import javax.management.modelmbean.ModelMBeanInfo;
-import javax.management.modelmbean.ModelMBeanInfoSupport;
-import javax.management.modelmbean.ModelMBeanNotificationInfo;
-import javax.management.modelmbean.ModelMBeanOperationInfo;
-
-/**
- * Junit tests for bugs:
- * 6252592 Provide for the user mandatory fields missing in Descriptor given
- * to Model*Info constructors
- * 4967755 ModelMBeanAttributeInfo constructor modifies its Descriptor argument
- *
- * @author Lars Westergren
- */
-public class DefaultDescriptorFieldTest /*extends TestCase*/ {
- public static void main(String[] args) throws Exception {
- boolean fail = false;
- Object test = new DefaultDescriptorFieldTest("Test");
- for (Method m : DefaultDescriptorFieldTest.class.getMethods()) {
- if (m.getName().startsWith("test") &&
- m.getParameterTypes().length == 0) {
- System.out.println("Testing " + m.getName());
- try {
- m.invoke(test);
- } catch (InvocationTargetException e) {
- fail = true;
- Throwable t = e.getCause();
- System.out.println("FAILED: exception: " + t);
- t.printStackTrace(System.out);
- }
- }
- }
- if (fail)
- throw new Exception("TEST FAILED");
- }
-
- //No check WHICH constructor is reflected, at least when the classes tested are constructed,
- //so I just use first one that came to mind.
- final Constructor[] constArr = String.class.getConstructors();
- final Constructor dummyConstructor = constArr[0];
-
-
- Method getMethod = null;
-
- /** Creates a new instance of MBeanTest */
- public DefaultDescriptorFieldTest(final String name) {
- try {
- getMethod = String.class.getMethod("toString");
- } catch (SecurityException ex) {
- ex.printStackTrace();
- } catch (NoSuchMethodException ex) {
- ex.printStackTrace();
- }
- }
-
- /**
- * Test instantiating the 5 different classes with a null
- * Descriptor, and also setting a null descriptor after.
- * Expected: Default Descriptors created.
- */
- public void testNullDescriptors()
- throws IntrospectionException, MBeanException {
- final ModelMBeanConstructorInfo constInfo =
- new ModelMBeanConstructorInfo("Dummy", dummyConstructor, null);
- constInfo.setDescriptor(null);
- ModelMBeanAttributeInfo attInfo =
- new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, null);
- attInfo.setDescriptor(null);
- ModelMBeanNotificationInfo notInfo =
- new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", null);
- notInfo.setDescriptor(null);
- ModelMBeanOperationInfo opInfo =
- new ModelMBeanOperationInfo("test", getMethod, null);
- opInfo.setDescriptor(null);
- ModelMBeanInfoSupport infoSupport =
- new ModelMBeanInfoSupport(new DummyModelMBeanInfo());
- infoSupport.setDescriptor(null,null);
- infoSupport.setDescriptor(null, "mbean");
- }
-
- /**
- * Test instantiating and setting a Descriptor without the "name",
- * "descriptorType" or "role" fields. This also tests whether the
- * Descriptor is cloned before default values are set, since
- * default values for one class will be incorrect for the next.
- * Expected: Descriptor should be cloned, missing default values should be
- * set
- */
- public void testFieldlessDescriptor()
- throws IntrospectionException, MBeanException {
- Descriptor theNamelessOne = new DescriptorSupport();
- final ModelMBeanConstructorInfo constInfo =
- new ModelMBeanConstructorInfo("Dummy", dummyConstructor, theNamelessOne);
- constInfo.setDescriptor(theNamelessOne);
- ModelMBeanAttributeInfo attInfo =
- new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, theNamelessOne);
- attInfo.setDescriptor(theNamelessOne);
- ModelMBeanNotificationInfo notInfo =
- new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", theNamelessOne);
- notInfo.setDescriptor(theNamelessOne);
- ModelMBeanOperationInfo opInfo =
- new ModelMBeanOperationInfo("test", getMethod, theNamelessOne);
- opInfo.setDescriptor(theNamelessOne);
- ModelMBeanInfoSupport infoSupport = new ModelMBeanInfoSupport(new DummyModelMBeanInfo());
- infoSupport.setDescriptor(theNamelessOne, null);
- infoSupport.setDescriptor(theNamelessOne, "mbean");
- }
-
-
- /**
- * Creates an empty DescriptorSupport and then test that ModelMBeanConstructorInfo accepts
- * the correct fields in validation one by one.
- */
- public void testCorrectConstructorDescriptors()
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- Descriptor cDesc = new DescriptorSupport(new String[0],new String[0]);
- final ModelMBeanConstructorInfo constInfo =
- new ModelMBeanConstructorInfo("Dummy", dummyConstructor, cDesc);
- assertFalse(fieldRefuted(constInfo, cDesc, "name" , "java.lang.String"));
- assertFalse(fieldRefuted(constInfo, cDesc, "role" , "constructor"));
- assertFalse(fieldRefuted(constInfo, cDesc, "descriptorType" , "operation"));
- }
-
- /**
- * Test that ModelMBeanConstructorInfo refutes incorrect fields in validation one by one.
- */
- public void testIncorrectConstructorDescriptors()
- throws NoSuchMethodException, IllegalAccessException {
- Descriptor cDesc = new DescriptorSupport(
- new String[] {"getMethod", "setMethod", "role", "Class", "name", "descriptorType"},
- new String[] {"dummyGetMethod", "dummySetMethod", "constructor", "dummyClass", "java.lang.String", "operation"});
- final ModelMBeanConstructorInfo constInfo = new ModelMBeanConstructorInfo("Dummy", dummyConstructor, cDesc);
- assertTrue(fieldRefuted(constInfo, cDesc, "name" , "blah"));
- assertTrue(fieldRefuted(constInfo, cDesc, "descriptorType", "mbean"));
- assertTrue(fieldRefuted(constInfo, cDesc, "descriptorType", "notification"));
- assertTrue(fieldRefuted(constInfo, cDesc, "descriptorType", "constructor"));
- assertTrue(fieldRefuted(constInfo, cDesc, "role", "operation"));
- }
-
- public void testCorrectAttributeDescriptors()
- throws IntrospectionException, NoSuchMethodException, IllegalAccessException {
- Descriptor aDesc = new DescriptorSupport(new String[0],new String[0]);
- final ModelMBeanAttributeInfo attInfo = new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, null);
- assertFalse(fieldRefuted(attInfo, aDesc, "name" , "dummyAttInfoName"));
- assertFalse(fieldRefuted(attInfo, aDesc, "descriptorType" , "attribute"));
- }
-
- public void testIncorrectAttributeDescriptors()
- throws IntrospectionException, NoSuchMethodException, IllegalAccessException {
- Descriptor aDesc = new DescriptorSupport();
- final ModelMBeanAttributeInfo attInfo = new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, null);
- assertTrue(fieldRefuted(attInfo, aDesc, "name" , "blah"));
- assertTrue(fieldRefuted(attInfo, aDesc, "descriptorType" , "constructor"));
- assertTrue(fieldRefuted(attInfo, aDesc, "descriptorType" , "notification"));
- }
-
- public void testCorrectNotificationDescriptors()
- throws NoSuchMethodException, IllegalAccessException {
- Descriptor nDesc = new DescriptorSupport();
- final ModelMBeanNotificationInfo nInfo = new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", nDesc);
- assertFalse(fieldRefuted(nInfo, nDesc, "name" , "notificationClassName"));
- assertFalse(fieldRefuted(nInfo, nDesc, "descriptorType" , "notification"));
- }
-
- public void testIncorrectNotificationDescriptors()
- throws NoSuchMethodException, IllegalAccessException {
- Descriptor nDesc = new DescriptorSupport();
- final ModelMBeanNotificationInfo nInfo = new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", nDesc);
- assertTrue(fieldRefuted(nInfo, nDesc, "name" , "blah"));
- assertTrue(fieldRefuted(nInfo, nDesc, "descriptorType" , "constructor"));
- assertTrue(fieldRefuted(nInfo, nDesc, "descriptorType" , "operation"));
- }
-
- public void testCorrectOperationDescriptors()
- throws NoSuchMethodException, IllegalAccessException {
- Descriptor opDesc = new DescriptorSupport();
- final ModelMBeanOperationInfo opInfo = new ModelMBeanOperationInfo("test", "readable description", null, "type", 1, opDesc);
- assertFalse(fieldRefuted(opInfo, opDesc, "name" , "test"));
- assertFalse(fieldRefuted(opInfo, opDesc, "descriptorType" , "operation"));
- assertFalse(fieldRefuted(opInfo, opDesc, "role" , "operation"));
- assertFalse(fieldRefuted(opInfo, opDesc, "role" , "getter"));
- assertFalse(fieldRefuted(opInfo, opDesc, "role" , "setter"));
- }
-
- public void testIncorrectOperationDescriptors()
- throws NoSuchMethodException, IllegalAccessException {
- Descriptor opDesc = new DescriptorSupport();
- final ModelMBeanOperationInfo opInfo = new ModelMBeanOperationInfo("test", "readable description", null, "type", 1, opDesc);
- assertTrue(fieldRefuted(opInfo, opDesc, "name" , "DENIED!!"));
- assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "constructor"));
- assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "attribute"));
- assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "notification"));
- assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "x"));
- }
-
- //TODO also test ModelMBeanInfoSupport perhaps. Slightly more difficult to set up and test.
-
- /**
- * Clones descriptor, sets a new value in the clone and tries to apply clone to
- * reflected Model*Info object method. The new field should be refuted if it
- * is a bad value.
- */
- //I like java, but this is one case where duck typing would have been slightly easier I think. :)
- private boolean fieldRefuted(Object mbeanInfo, Descriptor desc, String fieldName, String newValue)
- throws NoSuchMethodException, IllegalAccessException {
- Method setDescMethod = mbeanInfo.getClass().getMethod("setDescriptor", Descriptor.class);
- Descriptor newDesc = (Descriptor)desc.clone();
- boolean refused = false;
- newDesc.setField(fieldName, newValue);
- try {
- setDescMethod.invoke(mbeanInfo, newDesc);
- } catch (InvocationTargetException ex) {
- //If we get classcast exception, someone passed in a bad object to reflection.
- //Perhaps an unnecessary check, this cast?
- RuntimeOperationsException rex = (RuntimeOperationsException)ex.getTargetException();
- refused = true;
- }
- return refused;
- }
-
- /**
- * Dummy class used to create test objects. May not be needed.
- */
- private class DummyModelMBeanInfo implements ModelMBeanInfo {
- public Descriptor[] getDescriptors(String inDescriptorType)
- throws MBeanException, RuntimeOperationsException {
- return null;
- }
-
- public void setDescriptors(Descriptor[] inDescriptors)
- throws MBeanException, RuntimeOperationsException {
-
- }
-
- public Descriptor getDescriptor(String inDescriptorName, String inDescriptorType)
- throws MBeanException, RuntimeOperationsException {
- return null;
- }
-
- public void setDescriptor(Descriptor inDescriptor, String inDescriptorType)
- throws MBeanException, RuntimeOperationsException {
-
- }
-
- public Descriptor getMBeanDescriptor()
- throws MBeanException, RuntimeOperationsException {
- return null;
- }
-
- public void setMBeanDescriptor(Descriptor inDescriptor)
- throws MBeanException, RuntimeOperationsException {
-
- }
-
- public ModelMBeanAttributeInfo getAttribute(String inName)
- throws MBeanException, RuntimeOperationsException {
- return null;
- }
-
- public ModelMBeanOperationInfo getOperation(String inName)
- throws MBeanException, RuntimeOperationsException {
- return null;
- }
-
- public ModelMBeanNotificationInfo getNotification(String inName)
- throws MBeanException, RuntimeOperationsException {
- return null;
- }
-
- public MBeanAttributeInfo[] getAttributes() {
- return null;
- }
-
- public String getClassName() {
- return "AnonMBeanInfoImpl";
- }
-
- public MBeanConstructorInfo[] getConstructors() {
- return null;
- }
-
- public String getDescription() {
- return null;
- }
-
- public MBeanNotificationInfo[] getNotifications() {
- return null;
- }
-
- public MBeanOperationInfo[] getOperations() {
- return null;
- }
-
- public Object clone() {
- return null;
-
- }
-
- }
-
- private static void assertFalse(boolean x) {
- assertTrue(!x);
- }
-
- private static void assertTrue(boolean x) {
- if (!x)
- throw new AssertionError("Assertion failed");
- }
-
-}
--- a/jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -32,9 +32,13 @@
* @run main AttributeArbitraryDataTypeTest
*/
+import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import javax.management.AttributeNotFoundException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.Notification;
@@ -723,12 +727,49 @@
System.out.println(message);
}
+ public static Object elementFromComplex(Object complex, String element)
+ throws AttributeNotFoundException {
+ try {
+ if (complex.getClass().isArray() && element.equals("length")) {
+ return Array.getLength(complex);
+ } else if (complex instanceof CompositeData) {
+ return ((CompositeData) complex).get(element);
+ } else {
+ // Java Beans introspection
+ //
+ BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass());
+ PropertyDescriptor[] pds = bi.getPropertyDescriptors();
+ System.out.println("PDs: " + pds.length);
+ for (PropertyDescriptor pd : pds) {
+ System.out.println("Property: " + pd.getName());
+ if (pd.getName().equals(element))
+ return pd.getReadMethod().invoke(complex);
+ }
+ throw new AttributeNotFoundException(
+ "Could not find the getter method for the property " +
+ element + " using the Java Beans introspector");
+ }
+ } catch (InvocationTargetException e) {
+ throw new IllegalArgumentException(e);
+ } catch (AttributeNotFoundException e) {
+ throw e;
+ } catch (Exception e) {
+ AttributeNotFoundException anfe =
+ new AttributeNotFoundException(e.getMessage());
+ anfe.initCause(e);
+ throw anfe;
+ }
+ }
+
/*
* Standalone entry point.
*
* Run the test and report to stdout.
*/
public static void main (String args[]) throws Exception {
+ Match match = Match.do_match_now;
+ String name = (String) elementFromComplex(match, "name");
+ System.out.println("name: " + name);
AttributeArbitraryDataTypeTest test =
new AttributeArbitraryDataTypeTest();
int error = test.monitorNotifications();
--- a/jdk/test/javax/management/monitor/InstantiateMonitorNotificationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-
-import javax.management.ObjectName;
-import javax.management.monitor.MonitorNotification;
-
-/*
- * 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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6373143
- * @summary Test MonitorNotification public constructor
- * @author JFDenise
- * @run clean InstantiateMonitorNotificationTest
- * @run build InstantiateMonitorNotificationTest
- * @run main InstantiateMonitorNotificationTest
- */
-
-public class InstantiateMonitorNotificationTest {
-
- public static void main(String[] args) throws Exception {
- MonitorNotification notif = new MonitorNotification("com.foo.test",
- ObjectName.valueOf(":type=Monitor"),
- 999,
- 999,
- "A message",
- ObjectName.valueOf(":type=Observed"),
- "MyAttribute",
- Integer.valueOf(14),
- Integer.valueOf(15));
- System.out.println("Test passed");
- }
-}
--- a/jdk/test/javax/management/mxbean/CustomTypeTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,642 +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.
- *
- * 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.
- */
-
-/* @test %M% %I%
- * @bug 6562936 6750935
- * @run compile customtypes/package-info.java
- * @run main CustomTypeTest
- */
-
-import java.io.InvalidObjectException;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-import javax.management.Descriptor;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.NotCompliantMBeanException;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingClass;
-import javax.management.openmbean.MXBeanMappingFactory;
-import javax.management.openmbean.MXBeanMappingFactoryClass;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-
-import static javax.management.JMX.MBeanOptions;
-
-import customtypes.*;
-
-public class CustomTypeTest {
- @MXBeanMappingClass(LinkedListMapping.class)
- public static class LinkedList {
- private final String name;
- private final LinkedList next;
-
- public LinkedList(String name, LinkedList next) {
- this.name = name;
- this.next = next;
- }
-
- public String getName() {
- return name;
- }
-
- public LinkedList getNext() {
- return next;
- }
-
- public String toString() {
- if (next == null)
- return "(" + name + ")";
- else
- return "(" + name + " " + next + ")";
- }
-
- public boolean equals(Object x) {
- if (!(x instanceof LinkedList))
- return false;
- LinkedList other = (LinkedList) x;
- return (this.name.equals(other.name) &&
- (this.next == null ? other.next == null :
- this.next.equals(other.next)));
- }
- }
-
- public static class LinkedListMapping extends MXBeanMapping {
- public LinkedListMapping(Type type) throws OpenDataException {
- super(LinkedList.class, ArrayType.getArrayType(SimpleType.STRING));
- if (type != LinkedList.class) {
- throw new OpenDataException("Mapping only valid for " +
- LinkedList.class);
- }
- }
-
- public Object fromOpenValue(Object openValue) throws InvalidObjectException {
- String[] array = (String[]) openValue;
- LinkedList list = null;
- for (int i = array.length - 1; i >= 0; i--)
- list = new LinkedList(array[i], list);
- return list;
- }
-
- public Object toOpenValue(Object javaValue) throws OpenDataException {
- ArrayList<String> array = new ArrayList<String>();
- for (LinkedList list = (LinkedList) javaValue; list != null;
- list = list.getNext())
- array.add(list.getName());
- return array.toArray(new String[0]);
- }
- }
-
- public static interface LinkedListMXBean {
- public LinkedList getLinkedList();
- }
-
- public static class LinkedListImpl implements LinkedListMXBean {
- public LinkedList getLinkedList() {
- return new LinkedList("car", new LinkedList("cdr", null));
- }
- }
-
- public static class ObjectMXBeanMapping extends MXBeanMapping {
- private static final CompositeType wildcardType;
-
- static {
- try {
- wildcardType =
- new CompositeType(Object.class.getName(),
- "Wildcard type for Object",
- new String[0], // itemNames
- new String[0], // itemDescriptions
- new OpenType<?>[0]); // itemTypes
- } catch (OpenDataException e) {
- throw new RuntimeException(e);
- }
- }
-
- public ObjectMXBeanMapping() {
- super(Object.class, wildcardType);
- }
-
- public Object fromOpenValue(Object openValue) throws InvalidObjectException {
- if (!(openValue instanceof CompositeData)) {
- throw new InvalidObjectException("Not a CompositeData: " +
- openValue.getClass());
- }
- CompositeData cd = (CompositeData) openValue;
- if (!cd.containsKey("value")) {
- throw new InvalidObjectException("CompositeData does not " +
- "contain a \"value\" item: " + cd);
- }
- Object x = cd.get("value");
- if (!(x instanceof CompositeData || x instanceof TabularData ||
- x instanceof Object[]))
- return x;
-
- String typeName = (String) cd.get("type");
- if (typeName == null) {
- throw new InvalidObjectException("CompositeData does not " +
- "contain a \"type\" item: " + cd);
- }
- Class<?> c;
- try {
- c = Class.forName(typeName);
- } catch (ClassNotFoundException e) {
- InvalidObjectException ioe =
- new InvalidObjectException("Could not find type");
- ioe.initCause(e);
- throw ioe;
- }
- MXBeanMapping mapping;
- try {
- mapping = objectMappingFactory.mappingForType(c, objectMappingFactory);
- } catch (OpenDataException e) {
- InvalidObjectException ioe =
- new InvalidObjectException("Could not map object's " +
- "type " + c.getName());
- ioe.initCause(e);
- throw ioe;
- }
- return mapping.fromOpenValue(x);
- }
-
- public Object toOpenValue(Object javaValue) throws OpenDataException {
- OpenType<?> openType;
- Object openValue;
- String typeName;
- if (javaValue == null) {
- openType = SimpleType.VOID;
- openValue = null;
- typeName = null;
- } else {
- Class<?> c = javaValue.getClass();
- if (c.equals(Object.class))
- throw new OpenDataException("Cannot map Object to an open value");
- MXBeanMapping mapping =
- objectMappingFactory.mappingForType(c, objectMappingFactory);
- openType = mapping.getOpenType();
- openValue = mapping.toOpenValue(javaValue);
- typeName = c.getName();
- }
- CompositeType ct = new CompositeType(
- (javaValue == null) ? "null" : openType.getClassName(),
- "Open Mapping for Object",
- new String[] {"type", "value"},
- new String[] {"type", "value"},
- new OpenType<?>[] {SimpleType.STRING, openType});
- return new CompositeDataSupport(
- ct,
- new String[] {"type", "value"},
- new Object[] {typeName, openValue});
- }
- }
-
- public static class ObjectMappingFactory extends MXBeanMappingFactory {
- private static MXBeanMapping objectMapping =
- new ObjectMXBeanMapping();
-
- @Override
- public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
- throws OpenDataException {
- if (t.equals(Object.class))
- return objectMapping;
- else
- return MXBeanMappingFactory.DEFAULT.mappingForType(t, f);
- }
- }
-
- private static MXBeanMappingFactory objectMappingFactory =
- new ObjectMappingFactory();
-
- public static interface ObjectMXBean {
- public Object getObject();
- public Object[] getObjects();
- public List<Object> getObjectList();
- public Object[][] getMoreObjects();
- }
-
- public static class ObjectImpl implements ObjectMXBean {
- public Object getObject() {
- return 123;
- }
-
- private static Object[] objects = {
- "foo", 3, 3.14f, 3.14, 3L, new Date(), ObjectName.WILDCARD,
- new byte[3], new char[3], new int[3][3],
- new LinkedListImpl().getLinkedList(),
- };
-
- public Object[] getObjects() {
- return objects;
- }
-
- public List<Object> getObjectList() {
- return Arrays.asList(getObjects());
- }
-
- public Object[][] getMoreObjects() {
- return new Object[][] {{getObjects()}};
- }
- }
-
- @MXBeanMappingFactoryClass(ObjectMappingFactory.class)
- public static interface AnnotatedObjectMXBean extends ObjectMXBean {}
-
- public static class AnnotatedObjectImpl extends ObjectImpl
- implements AnnotatedObjectMXBean {}
-
- public static class BrokenMappingFactory extends MXBeanMappingFactory {
- public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
- throws OpenDataException {
- throw new OpenDataException(t.toString());
- }
- }
-
- public static class ReallyBrokenMappingFactory extends BrokenMappingFactory {
- public ReallyBrokenMappingFactory() {
- throw new RuntimeException("Oops");
- }
- }
-
- @MXBeanMappingFactoryClass(BrokenMappingFactory.class)
- public static interface BrokenMXBean {
- public int getX();
- }
-
- public static class BrokenImpl implements BrokenMXBean {
- public int getX() {return 0;}
- }
-
- @MXBeanMappingFactoryClass(ReallyBrokenMappingFactory.class)
- public static interface ReallyBrokenMXBean {
- public int getX();
- }
-
- public static class ReallyBrokenImpl implements ReallyBrokenMXBean {
- public int getX() {return 0;}
- }
-
- public static class BrokenMapping extends MXBeanMapping {
- public BrokenMapping(Type t) {
- super(t, SimpleType.STRING);
- throw new RuntimeException("Oops");
- }
-
- public Object fromOpenValue(Object openValue) throws InvalidObjectException {
- throw new AssertionError();
- }
-
- public Object toOpenValue(Object javaValue) throws OpenDataException {
- throw new AssertionError();
- }
- }
-
- @MXBeanMappingClass(BrokenMapping.class)
- public static class BrokenType {}
-
- public static interface BrokenTypeMXBean {
- BrokenType getBroken();
- }
-
- public static class BrokenTypeImpl implements BrokenTypeMXBean {
- public BrokenType getBroken() {
- throw new AssertionError();
- }
- }
-
- public static class BadConstructorMXBeanMappingFactory1 extends
- MXBeanMappingFactory {
- private BadConstructorMXBeanMappingFactory1() {}
-
- @Override
- public MXBeanMapping mappingForType(Type arg0, MXBeanMappingFactory arg1)
- throws OpenDataException {
- throw new UnsupportedOperationException("Should not be called");
- }
- }
-
- public static class BadConstructorMXBeanMappingFactory2 extends
- MXBeanMappingFactory {
- public BadConstructorMXBeanMappingFactory2(boolean oops) {}
-
- @Override
- public MXBeanMapping mappingForType(Type arg0, MXBeanMappingFactory arg1)
- throws OpenDataException {
- throw new UnsupportedOperationException("Should not be called");
- }
- }
-
- @MXBeanMappingFactoryClass(BadConstructorMXBeanMappingFactory1.class)
- public static interface BadConstructor1MXBean {}
-
- public static class BadConstructor1 implements BadConstructor1MXBean {}
-
- @MXBeanMappingFactoryClass(BadConstructorMXBeanMappingFactory2.class)
- public static interface BadConstructor2MXBean {}
-
- public static class BadConstructor2 implements BadConstructor2MXBean {}
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-
- System.out.println("Test @MXBeanMappingClass");
- ObjectName linkedName = new ObjectName("d:type=LinkedList");
- LinkedListMXBean linkedListMXBean = new LinkedListImpl();
- LinkedList list1 = linkedListMXBean.getLinkedList();
- mbs.registerMBean(linkedListMXBean, linkedName);
- LinkedListMXBean linkedProxy =
- JMX.newMXBeanProxy(mbs, linkedName, LinkedListMXBean.class);
- MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
- Proxy.getInvocationHandler(linkedProxy);
- if (!mbsih.isMXBean())
- fail("not MXBean proxy");
- LinkedList list2 = linkedProxy.getLinkedList();
- if (list1 == list2)
- fail("lists identical!");
- // They should have gone through the mapping and back,
- // and the mapping doesn't do anything that would allow it
- // to restore the identical object.
- if (!list1.equals(list2))
- fail("lists different: " + list1 + " vs " + list2);
- System.out.println("...success");
-
- System.out.println("Test StandardMBean with MXBeanMappingFactory");
- ObjectMXBean wildcardMBean = new ObjectImpl();
- MBeanOptions options = new MBeanOptions();
- options.setMXBeanMappingFactory(objectMappingFactory);
- if (!options.isMXBean())
- fail("Setting MXBeanMappingFactory should imply MXBean");
- StandardMBean wildcardStandardMBean =
- new StandardMBean(wildcardMBean, ObjectMXBean.class, options);
- testWildcardMBean(mbs, wildcardMBean, wildcardStandardMBean,
- options, ObjectMXBean.class);
-
- System.out.println("Test @MXBeanMappingFactoryClass on interface");
- ObjectMXBean annotatedWildcardMBean = new AnnotatedObjectImpl();
- testWildcardMBean(mbs, annotatedWildcardMBean, annotatedWildcardMBean,
- null, AnnotatedObjectMXBean.class);
-
- System.out.println("Test @MXBeanMappingFactoryClass on package");
- CustomMXBean custom = zeroProxy(CustomMXBean.class);
- ObjectName customName = new ObjectName("d:type=Custom");
- mbs.registerMBean(custom, customName);
- Object x = mbs.getAttribute(customName, "X");
- if (!(x instanceof String))
- fail("Should be String: " + x + " (a " + x.getClass().getName() + ")");
- CustomMXBean customProxy =
- JMX.newMXBeanProxy(mbs, customName, CustomMXBean.class);
- x = customProxy.getX();
- if (!(x instanceof Integer) || (Integer) x != 0)
- fail("Wrong return from proxy: " + x + " (a " + x.getClass().getName() + ")");
-
- System.out.println("Test MXBeanMappingFactory exception");
- try {
- mbs.registerMBean(new BrokenImpl(), new ObjectName("d:type=Broken"));
- fail("Register did not throw exception");
- } catch (NotCompliantMBeanException e) {
- System.out.println("...OK: threw: " + e);
- }
-
- System.out.println("Test MXBeanMappingFactory constructor exception");
- try {
- mbs.registerMBean(new ReallyBrokenImpl(), new ObjectName("d:type=Broken"));
- fail("Register did not throw exception");
- } catch (NotCompliantMBeanException e) {
- System.out.println("...OK: threw: " + e);
- } catch (Exception e) {
- fail("Register threw wrong exception: " + e);
- }
-
- System.out.println("Test MXBeanMappingFactory exception with StandardMBean");
- MXBeanMappingFactory brokenF = new BrokenMappingFactory();
- MBeanOptions brokenO = new MBeanOptions();
- brokenO.setMXBeanMappingFactory(brokenF);
- try {
- new StandardMBean(wildcardMBean, ObjectMXBean.class, brokenO);
- fail("StandardMBean with broken factory did not throw exception");
- } catch (IllegalArgumentException e) {
- if (!(e.getCause() instanceof NotCompliantMBeanException)) {
- fail("StandardMBean with broken factory threw wrong exception: "
- + e.getCause());
- }
- }
-
- System.out.println("Test MXBeanMappingClass exception");
- try {
- mbs.registerMBean(new BrokenTypeImpl(), new ObjectName("d:type=Broken"));
- fail("Broken MXBeanMappingClass did not throw exception");
- } catch (NotCompliantMBeanException e) {
- System.out.println("...OK: threw: " + e);
- }
-
- System.out.println("Test MXBeanMappingFactoryClass constructor exception");
- for (Object mbean : new Object[] {
- new BadConstructor1(), new BadConstructor2(),
- }) {
- String testName = mbean.getClass().getSimpleName();
- try {
- ObjectName name = new ObjectName("d:type=" + testName);
- mbs.registerMBean(mbean, name);
- fail("Broken MXBeanMappingFactoryClass did not throw exception" +
- " (" + testName + ")");
- } catch (NotCompliantMBeanException e) {
- System.out.println("...OK: " + testName + " threw: " + e);
- } catch (Exception e) {
- fail("Broken MXBeanMappingFactoryClass " + testName + " threw " +
- "wrong exception: " + e);
- }
- }
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static void testWildcardMBean(MBeanServer mbs, ObjectMXBean impl,
- Object mbean,
- MBeanOptions proxyOptions,
- Class<? extends ObjectMXBean> intf)
- throws Exception {
- ObjectName wildcardName = new ObjectName("d:type=Object");
- mbs.registerMBean(mbean, wildcardName);
- try {
- testWildcardMBean2(mbs, impl, wildcardName, proxyOptions, intf);
- } finally {
- mbs.unregisterMBean(wildcardName);
- }
- }
-
- private static void testWildcardMBean2(MBeanServer mbs, ObjectMXBean impl,
- ObjectName wildcardName,
- MBeanOptions proxyOptions,
- Class<? extends ObjectMXBean> intf)
- throws Exception {
- if (proxyOptions == null) {
- proxyOptions = new MBeanOptions();
- MXBeanMappingFactory f = MXBeanMappingFactory.forInterface(intf);
- proxyOptions.setMXBeanMappingFactory(f);
- }
- Descriptor d = mbs.getMBeanInfo(wildcardName).getDescriptor();
- String factoryName = (String)
- d.getFieldValue(JMX.MXBEAN_MAPPING_FACTORY_CLASS_FIELD);
- if (!ObjectMappingFactory.class.getName().equals(factoryName)) {
- fail("Descriptor has wrong MXBeanMappingFactory: " + factoryName +
- " should be " + ObjectMappingFactory.class.getName());
- }
- ObjectMXBean wildcardProxy =
- JMX.newMBeanProxy(mbs, wildcardName, intf, proxyOptions);
- MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
- Proxy.getInvocationHandler(wildcardProxy);
- MBeanOptions opts = mbsih.getMBeanOptions();
- if (!opts.equals(proxyOptions)) {
- fail("Proxy options differ from request: " + opts + " vs " +
- proxyOptions);
- }
- Method[] wildcardMethods = ObjectMXBean.class.getMethods();
- for (Method m : wildcardMethods) {
- System.out.println("..." + m.getName());
- Object orig = m.invoke(impl);
- Object copy = m.invoke(wildcardProxy);
- if (!deepEquals(orig, copy)) {
- fail("objects differ: " + deepToString(orig) + " vs " +
- deepToString(copy));
- }
- }
- }
-
- private static <T> T zeroProxy(Class<T> intf) {
- return intf.cast(Proxy.newProxyInstance(intf.getClassLoader(),
- new Class<?>[] {intf},
- new ZeroInvocationHandler()));
- }
-
- private static class ZeroInvocationHandler implements InvocationHandler {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return 0;
- }
- }
-
- private static boolean deepEquals(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
-
- if (x instanceof Collection<?>) {
- if (!(y instanceof Collection<?>))
- return false;
- Collection<?> xcoll = (Collection<?>) x;
- Collection<?> ycoll = (Collection<?>) y;
- if (xcoll.size() != ycoll.size())
- return false;
- Iterator<?> xit = xcoll.iterator();
- Iterator<?> yit = ycoll.iterator();
- while (xit.hasNext()) {
- if (!deepEquals(xit.next(), yit.next()))
- return false;
- }
- return true;
- }
-
- Class<?> xclass = x.getClass();
- Class<?> yclass = y.getClass();
- if (xclass.isArray()) {
- if (!yclass.isArray())
- return false;
- if (!xclass.getComponentType().equals(yclass.getComponentType()))
- return false;
- int len = Array.getLength(x);
- if (Array.getLength(y) != len)
- return false;
- for (int i = 0; i < len; i++) {
- if (!deepEquals(Array.get(x, i), Array.get(y, i)))
- return false;
- }
- return true;
- }
-
-// return x.equals(y);
- if (x.equals(y))
- return true;
- System.out.println("Not equal: <" + x + "> and <" + y + ">");
- return false;
- }
-
- private static String deepToString(Object x) {
- if (x == null)
- return "null";
-
- if (x instanceof Collection<?>) {
- Collection<?> xcoll = (Collection<?>) x;
- StringBuilder sb = new StringBuilder("[");
- for (Object e : xcoll) {
- if (sb.length() > 1)
- sb.append(", ");
- sb.append(deepToString(e));
- }
- sb.append("]");
- return sb.toString();
- }
-
- if (x instanceof Object[]) {
- Object[] xarr = (Object[]) x;
- return deepToString(Arrays.asList(xarr));
- }
-
- if (x.getClass().isArray()) { // primitive array
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
- return x.toString();
- }
-
- private static void fail(String msg) {
- System.out.println("TEST FAILED: " + msg);
- if (msg.length() > 100)
- msg = msg.substring(0, 100) + "...";
- failure = msg;
- }
-
- private static String failure;
-}
--- a/jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,3 +1,26 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
/*
* @test
* @bug 6713777
@@ -180,7 +203,6 @@
private static void testCaseProb() throws Exception {
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
ObjectName name = new ObjectName("a:b=c");
- Object mbean = new CaseProbImpl();
mbs.registerMBean(new CaseProbImpl(), name);
CaseProbMXBean proxy = JMX.newMXBeanProxy(mbs, name, CaseProbMXBean.class);
try {
--- a/jdk/test/javax/management/mxbean/JMXServiceURLTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +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.
- *
- * 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.
- */
-
-/*
- * @test JMXServiceURLTest
- * @bug 6607114 6670375 6731410
- * @summary Test that JMXServiceURL works correctly in MXBeans
- * @author Eamonn McManus
- */
-
-import java.io.InvalidObjectException;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.management.Attribute;
-import javax.management.JMX;
-import javax.management.MBeanException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.remote.JMXServiceURL;
-
-public class JMXServiceURLTest {
- public static interface UrlMXBean {
- public JMXServiceURL getUrl();
- public void setUrl(JMXServiceURL url);
- }
-
- public static class UrlImpl implements UrlMXBean {
- volatile JMXServiceURL url;
-
- public JMXServiceURL getUrl() {
- return url;
- }
-
- public void setUrl(JMXServiceURL url) {
- this.url = url;
- }
- }
-
- private static enum Part {
- PROTOCOL("protocol", SimpleType.STRING, "rmi", 25, "", "a:b", "/", "?", "#"),
- HOST("host", SimpleType.STRING, "a.b.c", 25, "a..b", ".a.b", "a.b."),
- PORT("port", SimpleType.INTEGER, 25, "25", -25),
- PATH("URLPath", SimpleType.STRING, "/tiddly", 25, "tiddly");
-
- Part(String name, OpenType openType, Object validValue, Object... bogusValues) {
- this.name = name;
- this.openType = openType;
- this.validValue = validValue;
- this.bogusValues = bogusValues;
- }
-
- final String name;
- final OpenType openType;
- final Object validValue;
- final Object[] bogusValues;
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = new ObjectName("a:b=c");
- UrlImpl urlImpl = new UrlImpl();
- mbs.registerMBean(urlImpl, name);
-
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://host:8000/noddy");
- UrlMXBean proxy = JMX.newMXBeanProxy(mbs, name, UrlMXBean.class);
- proxy.setUrl(url);
- assertEquals(url, urlImpl.url);
- JMXServiceURL url2 = proxy.getUrl();
- assertEquals(url, url2);
-
- CompositeData cd = (CompositeData) mbs.getAttribute(name, "Url");
- CompositeType ct = cd.getCompositeType();
- // Make sure it looks like what we expect. This will have to be
- // changed if ever we add new properties to CompositeType. In that
- // case this test should also check interoperability between the
- // current version and the new version.
- assertEquals(4, ct.keySet().size());
- Object[][] expectedItems = {
- {"protocol", SimpleType.STRING, "rmi"},
- {"host", SimpleType.STRING, "host"},
- {"port", SimpleType.INTEGER, 8000},
- {"URLPath", SimpleType.STRING, "/noddy"},
- };
- for (Object[] expectedItem : expectedItems) {
- String itemName = (String) expectedItem[0];
- OpenType expectedType = (OpenType) expectedItem[1];
- Object expectedValue = expectedItem[2];
- OpenType actualType = ct.getType(itemName);
- assertEquals(expectedType, actualType);
- Object actualValue = cd.get(itemName);
- assertEquals(expectedValue, actualValue);
- }
-
- // Now make sure we reject any bogus-looking CompositeData items.
- // We first try every combination of omitted items (items can be
- // null but cannot be omitted), then we try every combination of
- // valid and bogus items.
- final Part[] parts = Part.values();
- final int nParts = parts.length;
- final int maxPartMask = (1 << nParts) - 1;
- // Iterate over all possibilities of included and omitted, except
- // 0, because a CompositeDataSupport must have at least one element,
- // and maxPartMask, where all items are included and the result is valid.
- for (int mask = 1; mask < maxPartMask; mask++) {
- Map<String, Object> cdMap = new HashMap<String, Object>();
- List<String> names = new ArrayList<String>();
- List<OpenType> types = new ArrayList<OpenType>();
- for (int i = 0; i < nParts; i++) {
- if ((mask & (1 << i)) != 0) {
- Part part = parts[i];
- cdMap.put(part.name, part.validValue);
- names.add(part.name);
- types.add(openTypeForValue(part.validValue));
- }
- }
- String[] nameArray = names.toArray(new String[0]);
- OpenType[] typeArray = types.toArray(new OpenType[0]);
- CompositeType badct = new CompositeType(
- "bad", "descr", nameArray, nameArray, typeArray);
- CompositeData badcd = new CompositeDataSupport(badct, cdMap);
- checkBad(mbs, name, badcd);
- }
-
- int nBogus = 1;
- for (Part part : parts)
- nBogus *= (part.bogusValues.length + 1);
- // Iterate over all combinations of bogus values. We are basically
- // treating each Part as a digit while counting up from 1. A digit
- // value of 0 stands for the valid value of that Part, and 1 on
- // stand for the bogus values. Hence an integer where all the digits
- // are 0 would represent a valid CompositeData, which is why we
- // start from 1.
- for (int bogusCount = 1; bogusCount < nBogus; bogusCount++) {
- List<String> names = new ArrayList<String>();
- List<OpenType> types = new ArrayList<OpenType>();
- int x = bogusCount;
- Map<String, Object> cdMap = new HashMap<String, Object>();
- for (Part part : parts) {
- int digitMax = part.bogusValues.length + 1;
- int digit = x % digitMax;
- Object value = (digit == 0) ?
- part.validValue : part.bogusValues[digit - 1];
- cdMap.put(part.name, value);
- names.add(part.name);
- types.add(openTypeForValue(value));
- x /= digitMax;
- }
- String[] nameArray = names.toArray(new String[0]);
- OpenType[] typeArray = types.toArray(new OpenType[0]);
- CompositeType badct = new CompositeType(
- "bad", "descr", nameArray, nameArray, typeArray);
- CompositeData badcd = new CompositeDataSupport(badct, cdMap);
- checkBad(mbs, name, badcd);
- }
- }
-
- private static OpenType openTypeForValue(Object value) {
- if (value instanceof String)
- return SimpleType.STRING;
- else if (value instanceof Integer)
- return SimpleType.INTEGER;
- else
- throw new AssertionError("Value has invalid type: " + value);
- }
-
- private static void checkBad(
- MBeanServer mbs, ObjectName name, CompositeData badcd)
- throws Exception {
- try {
- mbs.setAttribute(name, new Attribute("Url", badcd));
- throw new Exception("Expected exception for: " + badcd);
- } catch (MBeanException e) {
- if (!(e.getCause() instanceof InvalidObjectException)) {
- throw new Exception(
- "Wrapped exception should be InvalidObjectException", e);
- }
- System.out.println("OK: rejected " + badcd);
- }
- }
-
- private static void assertEquals(Object expect, Object actual)
- throws Exception {
- if (expect.equals(actual))
- System.out.println("Equal: " + expect);
- else
- throw new Exception("Expected " + expect + ", got " + actual);
- }
-}
--- a/jdk/test/javax/management/mxbean/customtypes/CustomLongMXBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +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.
- *
- * 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.
- */
-
-// CustomLongMXBean.java - see CustomTypeTest
-
-package customtypes;
-
-import javax.management.openmbean.MXBeanMappingFactoryClass;
-
-@MXBeanMappingFactoryClass(IntegerIsLongFactory.class)
-public interface CustomLongMXBean extends CustomMXBean {}
--- a/jdk/test/javax/management/mxbean/customtypes/CustomMXBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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.
- *
- * 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.
- */
-
-// CustomMXBean.java - see CustomTypeTest
-
-package customtypes;
-
-public interface CustomMXBean {
- public Integer getX();
-}
--- a/jdk/test/javax/management/mxbean/customtypes/IntegerIsLongFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.
- *
- * 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.
- */
-
-// IntegerIsLongFactory.java - see CustomTypeTest
-
-package customtypes;
-
-import java.io.InvalidObjectException;
-import java.lang.reflect.Type;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingFactory;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.SimpleType;
-
-public class IntegerIsLongFactory implements MXBeanMappingFactory {
- public MXBeanMapping forType(Type t, MXBeanMappingFactory f)
- throws OpenDataException {
- if (t == Integer.class)
- return IntegerIsLongMapping;
- else
- return MXBeanMappingFactory.DEFAULT.forType(t, f);
- }
-
- private static final MXBeanMapping IntegerIsLongMapping =
- new IntegerIsLongMapping();
-
- private static class IntegerIsLongMapping extends MXBeanMapping {
- IntegerIsLongMapping() {
- super(Integer.class, SimpleType.STRING);
- }
-
- public Object fromOpenValue(Object openValue)
- throws InvalidObjectException {
- try {
- return (Long) openValue;
- } catch (Exception e) {
- InvalidObjectException ioe = new InvalidObjectException("oops");
- ioe.initCause(e);
- throw ioe;
- }
- }
-
- public Object toOpenValue(Object javaValue) throws OpenDataException {
- try {
- Integer i = (Integer) javaValue;
- return new Long((int) i);
- } catch (Exception e) {
- OpenDataException ode = new OpenDataException("oops");
- ode.initCause(e);
- throw ode;
- }
- }
- }
-}
--- a/jdk/test/javax/management/mxbean/customtypes/IntegerIsStringFactory.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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.
- *
- * 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.
- */
-
-// IntegerIsStringFactory.java - see CustomTypeTest
-
-package customtypes;
-
-import java.io.InvalidObjectException;
-import java.lang.reflect.Type;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingFactory;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.SimpleType;
-
-public class IntegerIsStringFactory extends MXBeanMappingFactory {
- @Override
- public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
- throws OpenDataException {
- if (t == Integer.class)
- return integerIsStringMapping;
- else
- return MXBeanMappingFactory.DEFAULT.mappingForType(t, f);
- }
-
- private static final MXBeanMapping integerIsStringMapping =
- new IntegerIsStringMapping();
-
- private static class IntegerIsStringMapping extends MXBeanMapping {
- IntegerIsStringMapping() {
- super(Integer.class, SimpleType.STRING);
- }
-
- public Object fromOpenValue(Object openValue)
- throws InvalidObjectException {
- try {
- String s = (String) openValue;
- return Integer.parseInt(s);
- } catch (Exception e) {
- InvalidObjectException ioe = new InvalidObjectException("oops");
- ioe.initCause(e);
- throw ioe;
- }
- }
-
- public Object toOpenValue(Object javaValue) throws OpenDataException {
- try {
- Integer i = (Integer) javaValue;
- return i.toString();
- } catch (Exception e) {
- OpenDataException ode = new OpenDataException("oops");
- ode.initCause(e);
- throw ode;
- }
- }
- }
-}
--- a/jdk/test/javax/management/mxbean/customtypes/package-info.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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.
- *
- * 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-info.java - test package annotations for custom types
-
-@javax.management.openmbean.MXBeanMappingFactoryClass(IntegerIsStringFactory.class)
-package customtypes;
--- a/jdk/test/javax/management/namespace/DomainCreationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,330 +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.
- *
- * 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.
- */
-/*
- *
- * @test DomainCreationTest.java
- * @bug 5072476
- * @summary Test the creation and registration of JMXDomain instances.
- * @author Daniel Fuchs
- * @run clean DomainCreationTest Wombat WombatMBean
- * @run build DomainCreationTest Wombat WombatMBean
- * @run main DomainCreationTest
- */
-
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.NotificationEmitter;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.RuntimeMBeanException;
-import javax.management.RuntimeOperationsException;
-import javax.management.namespace.JMXDomain;
-import javax.management.namespace.MBeanServerSupport;
-
-/**
- * Test simple creation/registration of namespace.
- *
- */
-public class DomainCreationTest {
- private static Map<String,Object> emptyEnvMap() {
- return Collections.emptyMap();
- }
-
-
- public static class LocalDomainRepository
- extends MBeanServerSupport {
- private final MBeanServer server;
- private final String domain;
-
-
- public class DynamicMBeanProxy implements DynamicMBean {
-
- private final MBeanServer server;
- private final ObjectName name;
-
- public DynamicMBeanProxy(MBeanServer s, ObjectName n) {
- this.server = s;
- this.name = n;
- }
-
- public Object getAttribute(String attribute)
- throws AttributeNotFoundException,
- MBeanException, ReflectionException {
- try {
- return server.getAttribute(name, attribute);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public void setAttribute(Attribute attribute)
- throws AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- try {
- server.setAttribute(name, attribute);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public AttributeList getAttributes(String[] attributes) {
- try {
- return server.getAttributes(name, attributes);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- try {
- return server.setAttributes(name, attributes);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public Object invoke(String actionName, Object[] params,
- String[] signature) throws MBeanException,
- ReflectionException {
- try {
- return server.invoke(name, actionName, params, signature);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public MBeanInfo getMBeanInfo() {
- try {
- return server.getMBeanInfo(name);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
- }
-
- public LocalDomainRepository(String domain) {
- this.server = MBeanServerFactory.newMBeanServer();
- this.domain = domain;
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- try {
- final ObjectName name =
- ObjectName.getInstance(domain+":*");
- return server.queryNames(name, null);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- return new DynamicMBeanProxy(server, name);
- }
-
- @Override
- public NotificationEmitter
- getNotificationEmitterFor(ObjectName name)
- throws InstanceNotFoundException {
- DynamicMBean mbean = getDynamicMBeanFor(name);
- if (mbean instanceof NotificationEmitter)
- return (NotificationEmitter) mbean;
- return null;
- }
-
- }
-
- private static MBeanServer newMBeanServer() {
- return MBeanServerFactory.newMBeanServer();
- }
-
- public static interface ThingMBean {}
- public static class Thing implements ThingMBean, MBeanRegistration {
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- if (name == null) return new ObjectName(":type=Thing");
- else return name;
- }
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
- public void postDeregister() {
- }
- }
-
- /**
- * Test that it is possible to create a dummy MBean with a null
- * ObjectName - this is just a sanity check - as there are already
- * other JMX tests that check that.
- *
- * @throws java.lang.Exception
- */
- public static void testCreateWithNull() throws Exception {
- final MBeanServer server = newMBeanServer();
- final ObjectInstance oi = server.registerMBean(new Thing(),null);
- server.unregisterMBean(oi.getObjectName());
- System.out.println("testCreateWithNull PASSED");
- }
-
- /**
- * Check that we can register a JMXNamespace MBean, using its standard
- * ObjectName.
- * @throws java.lang.Exception
- */
- public static void testGoodObjectName() throws Exception {
- MBeanServer server = newMBeanServer();
- final ObjectName name =
- JMXDomain.getDomainObjectName("gloups");
- final ObjectInstance oi =
- server.registerMBean(new JMXDomain(
- new LocalDomainRepository("gloups")),name);
- System.out.println("Succesfully registered namespace: "+name);
- try {
- if (! name.equals(oi.getObjectName()))
- throw new RuntimeException("testGoodObjectName: TEST failed: " +
- "namespace registered as: "+
- oi.getObjectName()+" expected: "+name);
- } finally {
- server.unregisterMBean(oi.getObjectName());
- }
- System.out.println("Succesfully unregistered namespace: "+name);
- System.out.println("testGoodObjectName PASSED");
- }
-
- /**
- * Check that we cannot register a JMXNamespace MBean, if we don't use
- * its standard ObjectName.
- * @throws java.lang.Exception
- */
- public static void testBadObjectName() throws Exception {
- MBeanServer server = newMBeanServer();
- Throwable exp = null;
- final ObjectName name = new ObjectName("d:k=v");
- try {
- server.registerMBean(new JMXDomain(
- new LocalDomainRepository("d")),name);
- System.out.println("testBadObjectName: " +
- "Error: MBean registered, no exception thrown.");
- } catch(RuntimeMBeanException x) {
- exp = x.getCause();
- } catch(Exception x) {
- throw new RuntimeException("testBadObjectName: TEST failed: " +
- "expected RuntimeMBeanException - got "+
- x);
- }
- if (exp == null) server.unregisterMBean(name);
- if (exp == null)
- throw new RuntimeException("testBadObjectName: TEST failed: " +
- "expected IllegalArgumentException - got none");
- if (!(exp instanceof IllegalArgumentException))
- throw new RuntimeException("testBadObjectName: TEST failed: " +
- "expected IllegalArgumentException - got "+
- exp.toString(),exp);
- System.out.println("Got expected exception: "+exp);
- System.out.println("testBadObjectName PASSED");
- }
-
- /**
- * Check that we cannot register a Domain MBean in a domain that already
- * exists.
- *
- * @throws java.lang.Exception
- */
- public static void testBadDomain() throws Exception {
- MBeanServer server = newMBeanServer();
- Throwable exp = null;
- final ObjectName name = new ObjectName("glips:k=v");
- server.registerMBean(new Wombat(),name);
-
- final ObjectName dname =
- JMXDomain.getDomainObjectName("glips");
-
- try {
- server.registerMBean(new JMXDomain(
- new LocalDomainRepository("glips")),dname);
- System.out.println("testBadDomain: " +
- "Error: MBean registered, no exception thrown.");
- } catch(RuntimeOperationsException x) {
- exp = x.getCause();
- } catch(Exception x) {
- throw new RuntimeException("testBadDomain: TEST failed: " +
- "expected RuntimeOperationsException - got "+
- x);
- } finally {
- server.unregisterMBean(name);
- }
- if (exp == null) {
- server.unregisterMBean(dname);
- }
- if (exp == null)
- throw new RuntimeException("testBadDomain: TEST failed: " +
- "expected IllegalArgumentException - got none");
- if (!(exp instanceof IllegalArgumentException))
- throw new RuntimeException("testBadDomain: TEST failed: " +
- "expected IllegalArgumentException - got "+
- exp.toString(),exp);
- System.out.println("Got expected exception: "+exp);
- System.out.println("testBadDomain PASSED");
- }
-
-
- public static void main(String... args) throws Exception {
- testCreateWithNull();
- testGoodObjectName();
- testBadObjectName();
- testBadDomain();
- }
-}
--- a/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test EventWithNamespaceControlTest.java
- * @summary Check -Djmx.remote.use.event.service=true and
- * -Djmx.remote.delegate.event.service
- * @author Daniel Fuchs
- * @bug 5072476 5108776
- * @run clean EventWithNamespaceTest EventWithNamespaceControlTest
- * Wombat WombatMBean JMXRemoteTargetNamespace
- * NamespaceController NamespaceControllerMBean
- * @compile -XDignore.symbol.file=true EventWithNamespaceTest.java
- EventWithNamespaceControlTest.java
- * Wombat.java WombatMBean.java JMXRemoteTargetNamespace.java
- * NamespaceController.java NamespaceControllerMBean.java
- * @run main/othervm -Djmx.remote.use.event.service=true EventWithNamespaceControlTest
- * @run main/othervm EventWithNamespaceControlTest
- * @run main/othervm -Djmx.remote.delegate.event.service=false EventWithNamespaceControlTest java.lang.UnsupportedOperationException
- */
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.logging.Logger;
-import javax.management.RuntimeOperationsException;
-
-/**
- *
- * @author Sun Microsystems, Inc.
- */
-public class EventWithNamespaceControlTest extends EventWithNamespaceTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(EventWithNamespaceControlTest.class.getName());
-
- /** Creates a new instance of EventWithNamespaceTest */
- public EventWithNamespaceControlTest() {
- }
-
-
-
- public static void main(String[] args) {
- final EventWithNamespaceControlTest test =
- new EventWithNamespaceControlTest();
- if (args.length == 0) {
- test.run(args);
- System.out.println("Test successfully passed");
- } else {
- try {
- test.run(args);
- throw new RuntimeException("Test should have failed.");
- } catch (RuntimeOperationsException x) {
- if (! args[0].equals(x.getCause().getClass().getName())) {
- System.err.println("Unexpected wrapped exception: "+
- x.getCause());
- throw x;
- } else {
- System.out.println("Got expected exception: "+x.getCause());
- }
- }
- }
- }
-
- @Override
- public Map<String, ?> getServerMap() {
- Map<String, ?> retValue = Collections.emptyMap();
- return retValue;
- }
-
-}
--- a/jdk/test/javax/management/namespace/EventWithNamespaceTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test EventWithNamespaceTest.java 1.8
- * @bug 6539857 5072476 5108776
- * @summary General Namespace & Notifications test.
- * @author Daniel Fuchs
- * @run clean EventWithNamespaceTest Wombat WombatMBean
- * JMXRemoteTargetNamespace
- * NamespaceController NamespaceControllerMBean
- * @compile -XDignore.symbol.file=true EventWithNamespaceTest.java
- * Wombat.java WombatMBean.java JMXRemoteTargetNamespace.java
- * NamespaceController.java NamespaceControllerMBean.java
- * @run main EventWithNamespaceTest
- */
-
-import java.lang.management.ManagementFactory;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- *
- * @author Sun Microsystems, Inc.
- */
-public class EventWithNamespaceTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(EventWithNamespaceTest.class.getName());
-
- /** Creates a new instance of EventWithNamespaceTest */
- public EventWithNamespaceTest() {
- }
-
- private static Map<String,?> singletonMap(String key, Object value) {
- final Map<String,Object> map = new HashMap<String,Object>();
- map.put(key,value);
- return map;
- }
-
- public Map<String,?> getServerMap() {
- return singletonMap(JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE,"true");
- }
-
- public JMXServiceURL export(MBeanServer server)
- throws Exception {
- final JMXServiceURL in = new JMXServiceURL("rmi",null,0);
- final Map<String,?> env = getServerMap();
-
- final JMXConnectorServer cs =
- JMXConnectorServerFactory.newJMXConnectorServer(in,env,null);
- final ObjectName csname = ObjectName.
- getInstance(cs.getClass().getPackage().getName()+
- ":type="+cs.getClass().getSimpleName());
- server.registerMBean(cs,csname);
- cs.start();
- return cs.getAddress();
- }
-
- public static class Counter {
- int count;
- public synchronized int count() {
- count++;
- notifyAll();
- return count;
- }
- public synchronized int peek() {
- return count;
- }
- public synchronized int waitfor(int max, long timeout)
- throws InterruptedException {
- final long start = System.currentTimeMillis();
- while (count < max && timeout > 0) {
- final long rest = timeout -
- (System.currentTimeMillis() - start);
- if (rest <= 0) break;
- wait(rest);
- }
- return count;
- }
- }
-
- public static class CounterListener
- implements NotificationListener {
- final private Counter counter;
- public CounterListener(Counter counter) {
- this.counter = counter;
- }
- public void handleNotification(Notification notification,
- Object handback) {
- System.out.println("Received notif from " + handback +
- ":\n\t" + notification);
- if (!notification.getSource().equals(handback)) {
- System.err.println("OhOh... Unexpected source: \n\t"+
- notification.getSource()+"\n\twas expecting:\n\t"+
- handback);
- }
- counter.count();
- }
- }
-
- public void simpleTest(String[] args) {
- try {
- final MBeanServer server1 =
- ManagementFactory.getPlatformMBeanServer();
- final JMXServiceURL url1 = export(server1);
-
- final MBeanServer server2 =
- MBeanServerFactory.createMBeanServer("server2");
- final JMXServiceURL url2 = export(server2);
-
- final MBeanServer server3 =
- MBeanServerFactory.createMBeanServer("server3");
- final JMXServiceURL url3 = export(server3);
-
- final ObjectInstance ncinst =
- NamespaceController.createInstance(server1);
-
- final NamespaceControllerMBean nc =
- JMX.newMBeanProxy(server1,ncinst.getObjectName(),
- NamespaceControllerMBean.class);
-
- final String mount2 = nc.mount(url2,"server2",null);
- final String mount3 = nc.mount(url3,"server2//server3",
- null);
-
- final ObjectName deep =
- new ObjectName("server2//server3//bush:type=Wombat,name=kanga");
- server1.createMBean(Wombat.class.getName(),deep);
-
- System.err.println("There's a wombat in the bush!");
-
- final Counter counter = new Counter();
-
- final NotificationListener listener =
- new CounterListener(counter);
-
- final JMXConnector jc = JMXConnectorFactory.connect(url1);
- final MBeanServerConnection conn1 =
- jc.getMBeanServerConnection();
- final ObjectName shallow =
- new ObjectName("bush:"+
- deep.getKeyPropertyListString());
- final MBeanServerConnection conn2 =
- JMXNamespaces.narrowToNamespace(conn1,"server2//server3");
-
- final WombatMBean proxy1 =
- JMX.newMBeanProxy(conn1,deep,WombatMBean.class,true);
- final WombatMBean proxy2 =
- JMX.newMBeanProxy(conn2,shallow,WombatMBean.class,true);
-
-
- System.err.println("Adding first Notification Listener");
- conn1.addNotificationListener(deep,listener,null,deep);
- System.err.println("Adding second Notification Listener");
- ((NotificationEmitter)proxy2).
- addNotificationListener(listener,null,shallow);
- final JMXConnector c3 = JMXConnectorFactory.connect(url3,
- singletonMap(JMXConnector.USE_EVENT_SERVICE,"false"));
- System.err.println("Adding third Notification Listener");
- c3.getMBeanServerConnection().
- addNotificationListener(shallow,listener,null,shallow);
- System.err.println("Set attribute to trigger notif");
- proxy1.setCaption("I am a new Wombat!");
- System.err.println("Get attribute");
- System.err.println("New caption: "+proxy2.getCaption());
- System.err.println("Wait for Notifs...");
- final int rcvcount = counter.waitfor(3,3000);
- if (rcvcount != 3)
- throw new RuntimeException("simpleTest failed: "+
- "received count is " +rcvcount);
- System.err.println("simpleTest: got expected "+rcvcount+
- " notifs");
-
- System.err.println("removing all listeners");
- conn1.removeNotificationListener(deep,listener,null,deep);
- ((NotificationEmitter)proxy2)
- .removeNotificationListener(listener,null,shallow);
- c3.getMBeanServerConnection().
- removeNotificationListener(shallow,listener,null,shallow);
-
- System.err.println("simpleTest passed: got "+rcvcount+
- " notifs");
-
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException("simpleTest failed: " + x,x);
- }
- }
-
- public void run(String[] args) {
- simpleTest(args);
- }
-
- public static void main(String[] args) {
- new EventWithNamespaceTest().run(args);
- }
-
-}
--- a/jdk/test/javax/management/namespace/ExportNamespaceTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +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.
- *
- * 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.
- */
-/*
- *
- * @test ExportNamespaceTest.java
- * @summary Test that you can export a single namespace through a
- * JMXConnectorServer.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean ExportNamespaceTest Wombat WombatMBean
- * @run build ExportNamespaceTest Wombat WombatMBean
- * @run main ExportNamespaceTest
- */
-
-import javax.management.JMX;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-
-/**
- * Test simple creation/registration of namespace.
- *
- */
-public class ExportNamespaceTest {
-
- public static void testExport() throws Exception {
- final JMXNamespace my =
- new JMXNamespace(MBeanServerFactory.newMBeanServer());
- final MBeanServer s = MBeanServerFactory.newMBeanServer();
- final ObjectName myname = JMXNamespaces.getNamespaceObjectName("my");
- final ObjectName wname = ObjectName.getInstance("backyard:type=Wombat");
- my.getSourceServer().registerMBean(new Wombat(),wname);
- s.registerMBean(my,myname);
-
- if (!s.queryNames(new ObjectName("my//b*:*"),null).contains(
- JMXNamespaces.insertPath("my", wname))) {
- throw new RuntimeException("1: Wombat not found: "+wname);
- }
-
- final MBeanServer cd = JMXNamespaces.narrowToNamespace(s, "my");
- if (!cd.queryNames(new ObjectName("b*:*"),null).contains(wname)) {
- throw new RuntimeException("2: Wombat not found: "+wname);
- }
-
- final JMXServiceURL url = new JMXServiceURL("rmi",null,0);
- final JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, null, cd);
- server.start();
-
- final JMXConnector jc = JMXConnectorFactory.
- connect(server.getAddress(),null);
- final MBeanServerConnection mbsc = jc.getMBeanServerConnection();
-
- if (!mbsc.queryNames(new ObjectName("b*:*"),null).contains(wname)) {
- throw new RuntimeException("3: Wombat not found: "+wname);
- }
- System.out.println("Found a Wombat in my backyard.");
-
- final String deepThoughts = "I want to leave this backyard!";
- final WombatMBean w = JMX.newMBeanProxy(mbsc, wname, WombatMBean.class);
- w.setCaption(deepThoughts);
- if (!deepThoughts.equals(w.getCaption()))
- throw new RuntimeException("4: Wombat is not thinking right: "+
- w.getCaption());
-
- }
-
- public static void main(String... args) throws Exception {
- testExport();
- }
-}
--- a/jdk/test/javax/management/namespace/JMXDomainTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,513 +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.
- *
- * 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.
- */
-/*
- *
- * @test JMXDomainTest.java
- * @bug 5072476
- * @summary Basic test for JMXDomain.
- * @author Daniel Fuchs
- * @run clean JMXDomainTest Wombat WombatMBean
- * @run build JMXDomainTest Wombat WombatMBean
- * @run main JMXDomainTest
- */
-
-
-import java.util.Collections;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.Map;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerFactory;
-import javax.management.MBeanServerNotification;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.namespace.JMXDomain;
-import javax.management.namespace.MBeanServerSupport;
-
-/**
- * Test simple creation/registration of namespace.
- *
- */
-public class JMXDomainTest {
- private static Map<String,Object> emptyEnvMap() {
- return Collections.emptyMap();
- }
-
-
- public static class LocalDomainRepository
- extends MBeanServerSupport {
- private final MBeanServer server;
- private final String domain;
-
- public class DynamicMBeanProxy implements DynamicMBean {
-
- private final MBeanServer server;
- private final ObjectName name;
-
- public DynamicMBeanProxy(MBeanServer s, ObjectName n) {
- this.server = s;
- this.name = n;
- }
-
- public Object getAttribute(String attribute)
- throws AttributeNotFoundException,
- MBeanException, ReflectionException {
- try {
- return server.getAttribute(name, attribute);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public void setAttribute(Attribute attribute)
- throws AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- try {
- server.setAttribute(name, attribute);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public AttributeList getAttributes(String[] attributes) {
- try {
- return server.getAttributes(name, attributes);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- try {
- return server.setAttributes(name, attributes);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public Object invoke(String actionName, Object[] params,
- String[] signature) throws MBeanException,
- ReflectionException {
- try {
- return server.invoke(name, actionName, params, signature);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- public MBeanInfo getMBeanInfo() {
- try {
- return server.getMBeanInfo(name);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
- }
-
- public LocalDomainRepository(String domain) {
- this.server = MBeanServerFactory.newMBeanServer();
- this.domain = domain;
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- try {
- final ObjectName name =
- ObjectName.getInstance(domain+":*");
- return server.queryNames(name, null);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (server.isRegistered(name))
- return new DynamicMBeanProxy(server, name);
- throw new InstanceNotFoundException(name);
- }
-
-
- @Override
- public NotificationEmitter
- getNotificationEmitterFor(final ObjectName name)
- throws InstanceNotFoundException {
- if (server.isInstanceOf(name, NotificationEmitter.class.getName())) {
- return new NotificationEmitter() {
-
- public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
- try {
- server.removeNotificationListener(name, listener, filter, handback);
- } catch (InstanceNotFoundException x) {
- throw new IllegalArgumentException(String.valueOf(name), x);
- }
- }
-
- public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {
- try {
- server.addNotificationListener(name, listener, filter, handback);
- } catch (InstanceNotFoundException x) {
- throw new IllegalArgumentException(String.valueOf(name), x);
- }
- }
-
- public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
- try {
- server.removeNotificationListener(name, listener);
- } catch (InstanceNotFoundException x) {
- throw new IllegalArgumentException(String.valueOf(name), x);
- }
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- try {
- return server.getMBeanInfo(name).getNotifications();
- } catch (Exception x) {
- throw new IllegalArgumentException(String.valueOf(name), x);
- }
- }
- };
- }
- return null;
- }
-
- @Override
- public ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException,
- MBeanRegistrationException, NotCompliantMBeanException {
- return server.registerMBean(object, name);
- }
-
- @Override
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException,
- MBeanRegistrationException {
- server.unregisterMBean(name);
- }
-
- @Override
- public ObjectInstance createMBean(String className,
- ObjectName name, ObjectName loaderName, Object[] params,
- String[] signature, boolean useCLR)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- if (useCLR && loaderName == null) {
- return server.createMBean(className, name, params, signature);
- }
- return server.createMBean(className, name, loaderName,
- params, signature);
- }
-
-
- }
-
- private static MBeanServer newMBeanServer() {
- return MBeanServerFactory.newMBeanServer();
- }
-
- public static interface ThingMBean {}
- public static class Thing implements ThingMBean, MBeanRegistration {
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- if (name == null) return new ObjectName(":type=Thing");
- else return name;
- }
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
- public void postDeregister() {
- }
- }
-
- /**
- * Test that it is possible to create a dummy MBean with a null
- * ObjectName - this is just a sanity check - as there are already
- * other JMX tests that check that.
- *
- * @throws java.lang.Exception
- */
- public static void testCreateWithNull() throws Exception {
- final MBeanServer server = newMBeanServer();
- final ObjectInstance oi = server.registerMBean(new Thing(),null);
- server.unregisterMBean(oi.getObjectName());
- System.out.println("testCreateWithNull PASSED");
- }
-
- public static void testRegisterSimple() throws Exception {
- final ObjectName name =
- JMXDomain.getDomainObjectName("gloups");
- final JMXDomain jmxDomain = new JMXDomain(
- MBeanServerFactory.newMBeanServer());
- testRegister("testRegisterSimple: ",name,jmxDomain);
- }
-
- public static void testRegisterPseudoVirtual()
- throws Exception {
- final ObjectName name =
- JMXDomain.getDomainObjectName("gloups");
- final JMXDomain jmxDomain = new JMXDomain(
- new LocalDomainRepository("gloups"));
- testRegister("testRegisterPseudoVirtual: ",name,jmxDomain);
- }
-
- public static void testRegister(final String test,
- final ObjectName name,
- final JMXDomain jmxDomain) throws Exception {
- System.out.println(test+" START");
- MBeanServer server = newMBeanServer();
- final ObjectInstance oi =
- server.registerMBean(jmxDomain,name);
- System.out.println(test+"Succesfully registered namespace: "+name);
- if (!server.isRegistered(name))
- fail(test+name+" is not registered!");
- if (!server.queryNames(new ObjectName(name.getDomain()+":*"), null).
- contains(name))
- fail(test+name+" not in queryNames");
-
- final Thing thing = new Thing();
- final ObjectName thingName = new ObjectName("gloups:type=Thing");
- server.registerMBean(thing,thingName);
- if (!server.isRegistered(thingName))
- fail(test+thingName+" is not registered!");
- if (!jmxDomain.getSourceServer().isRegistered(thingName))
- fail(test+thingName+" is not registered in domain!");
- if (!server.queryNames(new ObjectName(name.getDomain()+":*"), null).
- contains(thingName))
- fail(test+thingName+" not in queryNames");
-
- server.unregisterMBean(name);
- if (server.isRegistered(thingName))
- fail(test+thingName+" is still registered!");
- if (server.queryNames(new ObjectName(name.getDomain()+":*"), null).
- contains(thingName))
- fail(test+thingName+" still in queryNames");
-
- server.registerMBean(jmxDomain, name);
- if (!server.isRegistered(thingName))
- fail(test+thingName+" is not registered again!");
-
- System.out.println(test+" PASSED");
- }
-
- private static MBeanServerNotification pop(
- BlockingQueue<Notification> queue,
- String type,
- ObjectName mbean,
- String test)
- throws InterruptedException {
- final Notification n = queue.poll(1, TimeUnit.SECONDS);
- if (!(n instanceof MBeanServerNotification))
- fail(test+"expected MBeanServerNotification, got "+n);
- final MBeanServerNotification msn = (MBeanServerNotification)n;
- if (!type.equals(msn.getType()))
- fail(test+"expected "+type+", got "+msn.getType());
- if (!mbean.apply(msn.getMBeanName()))
- fail(test+"expected "+mbean+", got "+msn.getMBeanName());
- System.out.println(test+" got: "+msn);
- return msn;
- }
- private static MBeanServerNotification popADD(
- BlockingQueue<Notification> queue,
- ObjectName mbean,
- String test)
- throws InterruptedException {
- return pop(queue, MBeanServerNotification.REGISTRATION_NOTIFICATION,
- mbean, test);
- }
-
- private static MBeanServerNotification popREM(
- BlockingQueue<Notification> queue,
- ObjectName mbean,
- String test)
- throws InterruptedException {
- return pop(queue, MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
- mbean, test);
- }
-
-
- public static void testRegisterNotifSimple() throws Exception {
- final ObjectName name =
- JMXDomain.getDomainObjectName("gloups");
- final JMXDomain jmxDomain = new JMXDomain(
- MBeanServerFactory.newMBeanServer());
- testRegisterNotif("testRegisterNotifSimple: ",name,jmxDomain);
- }
-
- public static void testRegisterNotifPseudoVirtual()
- throws Exception {
- final ObjectName name =
- JMXDomain.getDomainObjectName("gloups");
- final JMXDomain jmxDomain = new JMXDomain(
- new LocalDomainRepository("gloups"));
- testRegisterNotif("testRegisterNotifPseudoVirtual: ",name,jmxDomain);
- }
-
- public static void testRegisterNotif(final String test,
- final ObjectName name,
- final JMXDomain jmxDomain) throws Exception {
- System.out.println(test+" START");
- MBeanServer server = newMBeanServer();
- final ObjectInstance oi =
- server.registerMBean(jmxDomain,name);
- System.out.println(test+"Succesfully registered namespace: "+name);
- if (!server.isRegistered(name))
- fail(test+name+" is not registered!");
-
- final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue<Notification>(10);
-
- final NotificationListener l = new NotificationListener() {
-
- public void handleNotification(Notification notification,
- Object handback) {
- try {
- if (!queue.offer(notification,5,TimeUnit.SECONDS))
- throw new RuntimeException("timeout exceeded");
- } catch (Exception x) {
- fail(test+"failed to handle notif", x);
- }
- }
- };
-
- server.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, l,
- null, null);
-
- final Thing thing = new Thing();
- final ObjectName thingName = new ObjectName("gloups:type=Thing");
-
- server.registerMBean(thing,thingName);
- if (!jmxDomain.getSourceServer().isRegistered(thingName))
- fail(test+thingName+" is not registered in domain!");
- popADD(queue, thingName, test);
- server.unregisterMBean(thingName);
- if (jmxDomain.getSourceServer().isRegistered(thingName))
- fail(test+thingName+" is still registered in domain!");
- popREM(queue, thingName, test);
- if (queue.size() != 0)
- fail(test+queue.size()+" notifs remain in queue "+queue);
-
- server.unregisterMBean(name);
- popREM(queue, name, test);
-
- jmxDomain.getSourceServer().registerMBean(thing,thingName);
- if (server.isRegistered(thingName))
- fail(test+thingName+" is still registered in domain!");
- jmxDomain.getSourceServer().unregisterMBean(thingName);
- if (queue.size() != 0)
- fail(test+queue.size()+" notifs remain in queue "+queue);
-
- server.registerMBean(jmxDomain, name);
- if (!server.isRegistered(name))
- fail(test+name+" is not registered again!");
- popADD(queue, name, test);
- if (queue.size() != 0)
- fail(test+queue.size()+" notifs remain in queue "+queue);
-
- server.registerMBean(thing,thingName);
- if (!jmxDomain.getSourceServer().isRegistered(thingName))
- fail(test+thingName+" is not registered in domain!");
- popADD(queue, thingName, test);
- server.unregisterMBean(thingName);
- if (jmxDomain.getSourceServer().isRegistered(thingName))
- fail(test+thingName+" is still registered in domain!");
- popREM(queue, thingName, test);
- if (queue.size() != 0)
- fail(test+queue.size()+" notifs remain in queue "+queue);
-
- System.out.println(test+" PASSED");
- }
-
-
-
- private static void fail(String msg) {
- raise(new RuntimeException(msg));
- }
-
- private static void fail(String msg, Throwable cause) {
- raise(new RuntimeException(msg,cause));
- }
-
- private static void raise(RuntimeException x) {
- lastException = x;
- exceptionCount++;
- throw x;
- }
-
- private static volatile Exception lastException = null;
- private static volatile int exceptionCount = 0;
-
- public static void main(String... args) throws Exception {
- testCreateWithNull();
-
- testRegisterSimple();
- testRegisterNotifSimple();
-
- testRegisterPseudoVirtual();
- testRegisterNotifPseudoVirtual();
-
- if (lastException != null)
- throw lastException;
- }
-}
--- a/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test JMXNamespaceSecurityTest.java
- * @summary General JMXNamespaceSecurityTest test.
- * @author Daniel Fuchs
- * @bug 5072476 6299231
- * @run clean JMXNamespaceViewTest JMXNamespaceSecurityTest Wombat WombatMBean
- * LazyDomainTest
- * @run build JMXNamespaceSecurityTest JMXNamespaceViewTest Wombat WombatMBean
- * LazyDomainTest
- * @run main/othervm JMXNamespaceSecurityTest namespace.policy
- */
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXDomain;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.ClientContext;
-
-/**
- *
- * @author Sun Microsystems, Inc.
- */
-public class JMXNamespaceSecurityTest extends JMXNamespaceViewTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(JMXNamespaceSecurityTest.class.getName());
-
- public static class NamedMBeanServerCreator
- extends JMXNamespaceViewTest.MBeanServerConfigCreator {
- public MBeanServer createMBeanServerFor(NamespaceConfig config) {
- return MBeanServerFactory.
- createNamedMBeanServer(config.name,config.name);
- }
- }
- /**
- * Creates a config for a hierarchy of namespaces, mixing local namespaces
- * and remote namespaces using the given protocol.
- * @param protocol The protocol that should be used for remote namespaces.
- * @return A namespace config hierarchy.
- * @throws java.lang.Exception
- */
- public static NamespaceConfig[] makeConfig(String protocol)
- throws Exception {
- final NamespaceConfig[] config = {
- // Top level namespace "top1" (local)
- config("top1",wombats("wchief","w1","w2","w3"),
- // top1//local1
- config("local1",wombats("wchief","ww1","ww2")),
- // top1//local2
- config("local2",wombats("wchief","ww4","ww5","ww6"),
- // top1//local2//local3
- config("local3",wombats("wchief","www1","www2")),
- // top1//local2//rmi1
- config("rmi1",url(protocol),wombats("wchief","www3","www4","www5"))),
- // top1//rmi2
- config("rmi2",url(protocol),wombats("wchief","ww7","ww8","ww9"),
- // top1//rmi2//local4
- config("local4",wombats("wchief","www6","www7")),
- // top1//rmi2//rmi3
- config("rmi3",url(protocol),wombats("wchief","www3","www4","www5"),
- // top1//rmi2//rmi3//local5
- config("local5",wombats("wchief","wwww1"))))),
- // Top level namespace "top2" (local)
- config("top2",wombats("wchief","w21","w22","w23"),
- // top2//local21
- config("local21",wombats("wchief","ww21","ww22")),
- // top2//rmi22
- config("rmi22",url(protocol),wombats("wchief","ww27","ww28","ww29"),
- // top2//rmi22//local24
- config("local24",wombats("wchief","www26","www27")),
- // top2//rmi22//rmi23
- config("rmi23",url(protocol),wombats("wchief","www23","www24","www25"),
- // top2//rmi22//rmi23//local25
- config("local25",wombats("wchief","wwww21"))))),
- // Top level namespace "top3" (remote)
- config("top3",url(protocol),wombats("wchief","w31","w32","w33"),
- // top3//local31
- config("local31",wombats("wchief","ww31","ww32")),
- // top3//rmi32
- config("rmi32",url(protocol),wombats("wchief","ww37","ww38","ww39"),
- // top3//rmi32//local34
- config("local34",wombats("wchief","www36","www37")),
- // top3//rmi32//rmi33
- config("rmi33",url(protocol),wombats("wchief","www33","www34","www35"),
- // top3//rmi32//local35
- config("local35",wombats("wchief","wwww31"))))),
- };
- return config;
- }
-
- public static void test(MBeanServer server, NamespaceConfig[] namespaces)
- throws Exception {
- System.out.println("Launching test...");
- List<JMXConnectorServer> cslist = load(server,
- new NamedMBeanServerCreator(), namespaces);
- Map<String,NamespaceConfig> inputMap =
- new HashMap<String,NamespaceConfig>();
-
- for (NamespaceConfig cfg : namespaces) {
- fillMap(inputMap,"",cfg);
- }
- final MBeanServer platform = ManagementFactory.getPlatformMBeanServer();
- //if (System.getProperty("jmx.wait")!=null) {
- /*
- // if we wanted to lazy load the platform MBeanServer:
- final LazyDomainTest.MBeanServerLoader loader =
- new LazyDomainTest.MBeanServerLoader() {
- public MBeanServer loadMBeanServer() {
- return ManagementFactory.getPlatformMBeanServer();
- }
- };
- final LazyDomainTest.MBeanServerProxy proxy =
- new LazyDomainTest.MBeanServerProxy(loader);
- final LazyDomainTest.LazyDomain domain =
- new LazyDomainTest.LazyDomain(proxy);
- server.registerMBean(domain,
- JMXDomain.getDomainObjectName("java.lang"));
- */
- // Mount java.lang MBeans into our private server so that
- // visualvm can connect.
- server.registerMBean(
- new JMXDomain(platform),
- JMXDomain.getDomainObjectName("java.lang"));
- //}
- if (System.getProperty("jmx.wait")!=null) {
- platform.registerMBean(new JMXNamespace(server),
- JMXNamespaces.getNamespaceObjectName("test"));
- }
-
- System.setSecurityManager(new SecurityManager());
-
- // Some sanity checks... The policy file should allow access
- // to java.lang MBeans.
- final ObjectName platnames = new ObjectName("java.lang:*");
- for (ObjectName o : platform.queryNames(platnames,null)) {
- server.getMBeanInfo(o);
- }
- final Set<ObjectName> lang =
- new HashSet<ObjectName>(server.queryNames(platnames, null));
- lang.remove(JMXDomain.getDomainObjectName("java.lang"));
- if (!lang.equals(platform.
- queryNames(platnames, null)))
- throw new Exception("Wrong list of platform names: "+lang);
- System.out.println("Got all java.lang MBeans: "+lang);
-
- // The policy file should allow to see all namespaces.
- // check this...
- final List<ObjectName> patterns = new ArrayList<ObjectName>();
- final Set<String> paths = new TreeSet<String>();
- final Set<String> uuids = new HashSet<String>();
- patterns.add(new ObjectName("*//:*"));
- while (patterns.size()>0) {
- System.out.println("server.queryNames("+patterns.get(0)+",null)");
- Set<ObjectName> names = server.queryNames(patterns.remove(0),null);
- System.out.println("found: "+names);
-
- for (ObjectName no : names) {
- final String uuid = (String) server.getAttribute(no, "UUID");
- if (uuids.contains(uuid)) {
- System.out.print("namespace "+no+", uuid="+uuid+
- " already parsed. Skipping");
- continue;
- }
- uuids.add(uuid);
- patterns.add(new ObjectName(no.getDomain()+"*//:*"));
- System.out.println("added pattern: "+
- new ObjectName(no.getDomain()+"*//:*"));
- if (no.getDomain().endsWith(ClientContext.NAMESPACE+
- JMXNamespaces.NAMESPACE_SEPARATOR)) continue;
- paths.add(no.getDomain().substring(0,
- no.getDomain().length()-
- JMXNamespaces.NAMESPACE_SEPARATOR.length()));
- }
- }
- final TreeSet<String> expected = new TreeSet<String>(inputMap.keySet());
- if (!expected.equals(paths)) {
- throw new Exception("wrong set of namespaces, expected "+
- expected+", got "+paths);
- }
-
- System.out.println("Got all namespaces: "+paths);
-
- // Check that we can see all wombats.
- //
- ObjectName wchief =
- new ObjectName("top1//rmi2//wombat:name=wchief,type=Wombat");
- String caption = (String) server.getAttribute(wchief,"Caption");
- System.out.println("wchief says "+caption);
- Object mood = server.getAttribute(wchief,"Mood");
- System.out.println("wchief's mood on a scale of 100 is "+mood);
-
- ObjectName wchief2 =
- new ObjectName("top1//wombat:name=wchief,type=Wombat");
- String caption2 = (String) server.getAttribute(wchief2,"Caption");
- System.out.println("wchief2 says "+caption2);
- try {
- Object mood2 = server.getAttribute(wchief2,"Mood");
- System.out.println("wchief2's mood on a scale of 100 is "+mood2);
- throw new Exception("Expected security exception for "+
- "getAttribute("+wchief2+", \"Mood\"");
- } catch (SecurityException x) {
- System.out.println("wchief2's mood is unavailable: "+x);
- }
- try {
- exportAndWaitIfNeeded(server);
- } finally {
- closeAll(cslist);
- }
-
- }
- /** Creates a new instance of JMXNamespaceTest */
- public JMXNamespaceSecurityTest() {
- }
-
- public static void main(String[] args) throws Exception {
- String osName = System.getProperty("os.name");
- System.out.println("os.name = " + osName);
- if (!osName.equals("SunOS")) {
- System.out.println("This test runs on Solaris only.");
- System.out.println("Bye! Bye!");
- return;
- }
- final String policy = System.getProperty("test.src") +
- File.separator + args[0];
- System.out.println("PolicyFile = " + policy);
- System.setProperty("java.security.policy", policy);
- if (!new File(System.getProperty("java.security.policy")).canRead())
- throw new IOException("no such file: "+
- System.getProperty("java.security.policy"));
- test(MBeanServerFactory.createNamedMBeanServer("root","root"),
- makeConfig("rmi"));
- }
-
-}
--- a/jdk/test/javax/management/namespace/JMXNamespaceTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test JMXNamespaceTest.java
- * @summary General JMXNamespace test.
- * @bug 5072476
- * @author Daniel Fuchs
- * @run clean JMXNamespaceTest
- * Wombat WombatMBean JMXRemoteTargetNamespace
- * NamespaceController NamespaceControllerMBean
- * @compile -XDignore.symbol.file=true JMXNamespaceTest.java
- * Wombat.java WombatMBean.java JMXRemoteTargetNamespace.java
- * NamespaceController.java NamespaceControllerMBean.java
- * @run main/othervm JMXNamespaceTest
- */
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Logger;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.InvalidAttributeValueException;
-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.StandardMBean;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaceMBean;
-import javax.management.namespace.JMXRemoteNamespaceMBean;
-import javax.management.namespace.MBeanServerConnectionWrapper;
-import javax.management.namespace.MBeanServerSupport;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- *
- * @author Sun Microsystems, Inc.
- */
-public class JMXNamespaceTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(JMXNamespaceTest.class.getName());
-
- /** Creates a new instance of JMXNamespaceTest */
- public JMXNamespaceTest() {
- }
-
- public static class WombatRepository extends MBeanServerSupport {
- final Wombat wombat;
- final StandardMBean mbean;
- final ObjectName wombatName;
-
- public WombatRepository(ObjectName wombatName) {
- try {
- wombat = new Wombat();
- mbean = wombat;
- this.wombatName = wombatName;
- wombat.preRegister(null,wombatName);
- } catch (Exception x) {
- throw new IllegalArgumentException(x);
- }
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (wombatName.equals(name)) return mbean;
- else throw new InstanceNotFoundException(String.valueOf(name));
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- final Set<ObjectName> res = Collections.singleton(wombatName);
- return res;
- }
-
- @Override
- public NotificationEmitter
- getNotificationEmitterFor(ObjectName name)
- throws InstanceNotFoundException {
- final DynamicMBean mb = getDynamicMBeanFor(name);
- if (mb instanceof NotificationEmitter)
- return (NotificationEmitter)mb;
- return null;
- }
- }
-
- public static class SimpleTest {
- public final String descr;
- private final Class<?> testClass;
- private final Method method;
- public SimpleTest(String descr) {
- this.descr = descr;
- this.testClass = JMXNamespaceTest.class;
- try {
- method = testClass.
- getDeclaredMethod(descr,SimpleTestConf.class,
- Object[].class);
- } catch (NoSuchMethodException x) {
- throw new IllegalArgumentException(descr+": test not found",
- x);
- }
- }
-
- public void run(SimpleTestConf conf, Object... args)
- throws Exception {
- try {
- method.invoke(null,conf,args);
- } catch (InvocationTargetException x) {
- final Throwable cause = x.getCause();
- if (cause instanceof Exception) throw (Exception)cause;
- if (cause instanceof Error) throw (Error)cause;
- throw x;
- }
- }
- }
-
- public static class SimpleTestConf {
- public final Wombat wombat;
- public final StandardMBean mbean;
- public final String dirname;
- public final ObjectName handlerName;
- public final ObjectName wombatNickName;
- public final ObjectName wombatName;
- public final JMXNamespace wombatNamespace;
- public final MBeanServer server;
- public final WombatMBean proxy;
- public SimpleTestConf(String[] args) throws Exception {
- wombat = new Wombat();
- mbean = wombat;
- dirname = "wombat";
- handlerName =
- new ObjectName(dirname+"//:type=JMXNamespace");
-
- wombatNickName =
- new ObjectName("burrow:type=Wombat");
-
- wombatName =
- new ObjectName(dirname+"//"+wombatNickName);
-
- wombatNamespace =
- new JMXNamespace(
- new WombatRepository(wombatNickName));
-
- server = ManagementFactory.getPlatformMBeanServer();
- System.out.println(handlerName+" registered="+
- server.isRegistered(handlerName));
- server.registerMBean(wombatNamespace,handlerName);
-
- try {
- proxy = JMX.newMBeanProxy(server,wombatName,
- WombatMBean.class);
- } catch (Exception x) {
- server.unregisterMBean(handlerName);
- throw x;
- }
- }
-
- public void close() {
- try {
- server.unregisterMBean(handlerName);
- } catch (Exception x) {
- System.out.println("Failed to close: " + x);
- x.printStackTrace();
- }
- }
-
- public void test(SimpleTest test,Object... args)
- throws Exception {
- try {
- test.run(this,args);
- passed++;
- } catch (Exception x) {
- failed++;
- System.err.println(test.descr+" failed: " + x);
- x.printStackTrace();
- }
- }
-
- public volatile int failed = 0;
- public volatile int passed = 0;
- }
-
- static void checkValue(String name,Object expected, Object returned)
- throws InvalidAttributeValueException {
- if (Collections.singletonList(expected).
- equals(Collections.singletonList(returned))) return;
-
- throw new InvalidAttributeValueException("Bad value for "+
- name+": ["+returned+"] - was expecting ["+expected+"]");
- }
-
- // ---------------------------------------------------------------
- // SIMPLE TESTS BEGIN HERE
- // ---------------------------------------------------------------
-
- static void getCaptionTest(SimpleTestConf env, Object... args)
- throws Exception {
- System.out.println(env.proxy.getCaption());
- }
-
- static void setCaptionTest(SimpleTestConf env, Object... args)
- throws Exception {
- env.proxy.setCaption((String)args[0]);
- final String result = env.proxy.getCaption();
- System.out.println(result);
- checkValue("Caption",args[0],result);
- }
-
- static void queryNamesTest1(SimpleTestConf env, Object... args)
- throws Exception {
- final ObjectName pat =
- new ObjectName(env.handlerName.getDomain()+"*:*");
- final Set<ObjectName> res =
- env.server.queryNames(pat,null);
- System.out.println("queryNamesTest1: "+res);
- checkValue("names",Collections.singleton(env.wombatName),res);
- }
-
- static void queryNamesTest2(SimpleTestConf env, Object... args)
- throws Exception {
- final ObjectName pat =
- new ObjectName("*:"+
- env.wombatName.getKeyPropertyListString());
- final Set<ObjectName> res =
- env.server.queryNames(pat,null);
- System.out.println("queryNamesTest2: "+res);
- checkValue("names",Collections.emptySet(),res);
- }
-
- static void getDomainsTest(SimpleTestConf env, Object... args)
- throws Exception {
- final List<String> domains =
- Arrays.asList(env.server.getDomains());
- System.out.println("getDomainsTest: "+domains);
- if (domains.contains(env.wombatName.getDomain()))
- throw new InvalidAttributeValueException("domain: "+
- env.wombatName.getDomain());
- if (!domains.contains(env.handlerName.getDomain()))
- throw new InvalidAttributeValueException("domain not found: "+
- env.handlerName.getDomain());
- }
-
- // ---------------------------------------------------------------
- // SIMPLE TESTS END HERE
- // ---------------------------------------------------------------
-
- private static void simpleTest(String[] args) {
- final SimpleTestConf conf;
- try {
- conf = new SimpleTestConf(args);
- try {
- conf.test(new SimpleTest("getCaptionTest"));
- conf.test(new SimpleTest("setCaptionTest"),
- "I am a new Wombat!");
- conf.test(new SimpleTest("queryNamesTest1"));
- conf.test(new SimpleTest("queryNamesTest2"));
- conf.test(new SimpleTest("getDomainsTest"));
- } finally {
- conf.close();
- }
- } catch (Exception x) {
- System.err.println("simpleTest FAILED: " +x);
- x.printStackTrace();
- throw new RuntimeException(x);
- }
- System.out.println("simpleTest: "+conf.passed+
- " PASSED, " + conf.failed + " FAILED.");
- if (conf.failed>0) {
- System.err.println("simpleTest FAILED ["+conf.failed+"]");
- throw new RuntimeException("simpleTest FAILED ["+conf.failed+"]");
- } else {
- System.err.println("simpleTest PASSED ["+conf.passed+"]");
- }
- }
-
- public static void recursiveTest(String[] args) {
- final SimpleTestConf conf;
- 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 String[] signature2 = {
- JMXServiceURL.class.getName(),
- Map.class.getName(),
- String.class.getName(),
- };
- final Object[] params = {
- address,
- null,
- };
- final MBeanServerConnection c =
- client.getMBeanServerConnection();
- final ObjectName dirName1 =
- new ObjectName("kanga//:type=JMXNamespace");
- c.createMBean(JMXRemoteTargetNamespace.class.getName(),
- dirName1, params,signature);
- c.invoke(dirName1, "connect", null, null);
- try {
- final MemoryMXBean memory =
- JMX.newMXBeanProxy(c,
- new ObjectName("kanga//"+
- ManagementFactory.MEMORY_MXBEAN_NAME),
- MemoryMXBean.class);
- System.out.println("HeapMemory #1: "+
- memory.getHeapMemoryUsage().toString());
- final MemoryMXBean memory2 =
- JMX.newMXBeanProxy(c,
- new ObjectName("kanga//kanga//"+
- ManagementFactory.MEMORY_MXBEAN_NAME),
- MemoryMXBean.class);
- System.out.println("HeapMemory #2: "+
- memory2.getHeapMemoryUsage().toString());
- final Object[] params2 = {
- address,
- null,
- "kanga//kanga"
- // "kanga//kanga//roo//kanga", <= cycle
- };
- final ObjectName dirName2 =
- new ObjectName("kanga//roo//:type=JMXNamespace");
- c.createMBean(JMXRemoteTargetNamespace.class.getName(),
- dirName2, params2, signature2);
- System.out.println(dirName2 + " created!");
- JMX.newMBeanProxy(c,dirName2,
- JMXRemoteNamespaceMBean.class).connect();
- try {
- final ObjectName wombatName1 =
- new ObjectName("kanga//roo//"+conf.wombatName);
- final ObjectName wombatName2 =
- new ObjectName("kanga//roo//"+wombatName1);
- final WombatMBean wombat1 =
- JMX.newMBeanProxy(c,wombatName1,WombatMBean.class);
- final WombatMBean wombat2 =
- JMX.newMBeanProxy(c,wombatName2,WombatMBean.class);
- final String newCaption="I am still the same old wombat";
- wombat1.setCaption(newCaption);
- final String caps = conf.proxy.getCaption();
- System.out.println("Caption: "+caps);
- checkValue("Caption",newCaption,caps);
- final String caps1 = wombat1.getCaption();
- System.out.println("Caption #1: "+caps1);
- checkValue("Caption #1",newCaption,caps1);
- final String caps2 = wombat2.getCaption();
- System.out.println("Caption #2: "+caps2);
- checkValue("Caption #2",newCaption,caps2);
- final ObjectInstance instance =
- NamespaceController.createInstance(conf.server);
- final NamespaceControllerMBean controller =
- JMX.newMBeanProxy(conf.server,instance.getObjectName(),
- NamespaceControllerMBean.class);
- final String[] dirs = controller.findNamespaces();
- System.out.println("directories: " +
- Arrays.asList(dirs));
- final int depth = 4;
- final String[] dirs2 = controller.findNamespaces(null,null,depth);
- System.out.println("directories[depth="+depth+"]: " +
- Arrays.asList(dirs2));
- for (String dir : dirs2) {
- if (dir.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR))
- dir = dir.substring(0,dir.length()-
- JMXNamespaces.NAMESPACE_SEPARATOR.length());
- if (dir.split(JMXNamespaces.NAMESPACE_SEPARATOR).length
- > (depth+1)) {
- throw new RuntimeException(dir+": depth exceeds "+depth);
- }
- final ObjectName handlerName =
- JMXNamespaces.getNamespaceObjectName(dir);
- final JMXNamespaceMBean handler =
- JMX.newMBeanProxy(conf.server,handlerName,
- JMXNamespaceMBean.class);
- try {
- System.err.println("Directory "+dir+" domains: "+
- Arrays.asList(handler.getDomains()));
- System.err.println("Directory "+dir+" default domain: "+
- handler.getDefaultDomain());
- System.err.println("Directory "+dir+" MBean count: "+
- handler.getMBeanCount());
- } catch(Exception x) {
- System.err.println("get info failed for " +
- dir +", "+handlerName+": "+x);
- x.getCause().printStackTrace();
- throw x;
- }
- }
-
- } finally {
- c.unregisterMBean(dirName2);
- }
- } finally {
- c.unregisterMBean(dirName1);
- client.close();
- server.stop();
- }
- } finally {
- conf.close();
- }
- System.err.println("recursiveTest PASSED");
- } catch (Exception x) {
- System.err.println("recursiveTest FAILED: " +x);
- x.printStackTrace();
- throw new RuntimeException(x);
- }
- }
-
- public static void verySimpleTest(String[] args) {
- System.err.println("verySimpleTest: starting");
- try {
- 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("verySimpleTest FAILED: " +x);
- x.printStackTrace();
- throw new RuntimeException(x);
- }
- System.err.println("verySimpleTest: 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("verySimpleTest2 FAILED: " +x);
- x.printStackTrace();
- throw new RuntimeException(x);
- }
- System.err.println("verySimpleTest2: PASSED");
- }
-
- public static void main(String[] args) {
- simpleTest(args);
- recursiveTest(args);
- verySimpleTest(args);
- verySimpleTest2(args);
- }
-
-}
--- a/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,546 +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.
- *
- * 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.
- */
-/*
- *
- * @test JMXNamespaceViewTest.java
- * @summary Test the JMXNamespaceView class.
- * @bug 5072476
- * @author Daniel Fuchs
- * @run clean JMXNamespaceViewTest Wombat WombatMBean
- * @run build JMXNamespaceViewTest Wombat WombatMBean
- * @run main JMXNamespaceViewTest
- */
-
-
-import java.lang.management.ManagementFactory;
-import java.net.ServerSocket;
-import java.rmi.registry.LocateRegistry;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.management.ClientContext;
-import javax.management.JMException;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaceView;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXRemoteNamespace;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * A simple test to test the JMXNamespaceViewTest...
- * @author dfuchs
- */
-public class JMXNamespaceViewTest {
-
- /**
- * Describe the configuration of a namespace
- */
- public static class NamespaceConfig {
- /** name of the namespace - no // allowed **/
- public String name;
- /**
- * JMXServiceURL through which the namespace is exported, if it
- * is a remote namespace. {@code null} if the namespace is local.
- * This is an inpur URL - eg: new JMXServiceURL("rmi",null,0).toString()
- * is acceptable here.
- */
- public String jmxurl;
- /**
- * Values of the name= key for each WombatMBean contained in the
- * namespace.
- */
- public String[] wombats;
- /** list of child namespace **/
- public NamespaceConfig[] children;
- }
-
- /**
- * Creates a NamespaceConfig record for a local namespace.
- * @param name name of the namespace
- * @param wombats names of WombatMBean it should contain.
- * @return a NamespaceConfig.
- */
- public static NamespaceConfig config(String name, String[] wombats) {
- return config(name,null,wombats);
- }
-
- /**
- * Creates a NamespaceConfig record for a remote namespace.
- * @param name name of the namespace
- * @param jmxurl input JMXServiceURL for creating the JMXConnectorServer
- * @param wombats names of WombatMBean it should contain.
- * @return a NamespaceConfig.
- */
- public static NamespaceConfig config(String name, String jmxurl,
- String[] wombats) {
- return config(name,jmxurl,wombats,(NamespaceConfig[])null);
- }
-
- /**
- * Creates a NamespaceConfig record for a local namespace.
- * @param name name of the namespace
- * @param wombats names of WombatMBean it should contain.
- * @param children list of sub namespaces.
- * @return a NamespaceConfig.
- */
- public static NamespaceConfig config(String name, String[] wombats,
- NamespaceConfig... children) {
- return config(name,null,wombats,children);
- }
-
- /**
- * Creates a NamespaceConfig record for a remote namespace.
- * @param name name of the namespace
- * @param jmxurl input JMXServiceURL for creating the JMXConnectorServer
- * @param wombats names of WombatMBean it should contain.
- * @param children list of sub namespaces.
- * @return a NamespaceConfig.
- */
- static NamespaceConfig config(String name, String jmxurl, String[] wombats,
- NamespaceConfig... children) {
- final NamespaceConfig cfg = new NamespaceConfig();
- cfg.name=name; cfg.jmxurl=jmxurl; cfg.wombats=wombats;
- cfg.children=children;
- return cfg;
- }
-
- /**
- * Returns the given names. This is a utility method to ease code
- * reading.
- * @param names names of Wombat MBeans.
- * @return the given names.
- */
- static String[] wombats(String... names) {
- return names;
- }
-
- /**
- * Creates a JMXServiceURL string for the given protocol.
- * This is also a utility method to ease code reading.
- * @param protocol The protocol name (e.g. "rmi")
- * @return A JMXServiceURL string.
- * @throws Exception if creation of the JMXServiceURL fails.
- */
- static String url(String protocol) throws Exception {
- return new JMXServiceURL(protocol,null,0).toString();
- }
-
- /**
- * Creates a config for a hierarchy of namespaces, mixing local namespaces
- * and remote namespaces using the given protocol.
- * @param protocol The protocol that should be used for remote namespaces.
- * @return A namespace config hierarchy.
- * @throws java.lang.Exception
- */
- public static NamespaceConfig[] makeConfig(String protocol)
- throws Exception {
- final NamespaceConfig[] config = {
- // Top level namespace "top1" (local)
- config("top1",wombats("wchief","w1","w2","w3"),
- // top1//local1
- config("local1",wombats("wchief","ww1","ww2")),
- // top1//local2
- config("local2",wombats("wchief","ww4","ww5","ww6"),
- // top1//local2//local3
- config("local3",wombats("wchief","www1","www2")),
- // top1//local2//rmi1
- config("rmi1",url(protocol),wombats("wchief","www3","www4","www5"))),
- // top1//rmi2
- config("rmi2",url(protocol),wombats("wchief","ww7","ww8","ww9"),
- // top1//rmi2//local4
- config("local4",wombats("wchief","www6","www7")),
- // top1//rmi2//rmi3
- config("rmi3",url(protocol),wombats("wchief","www3","www4","www5"),
- // top1//rmi2//rmi3//local5
- config("local5",wombats("wchief","wwww1"))))),
- // Top level namespace "top2" (local)
- config("top2",wombats("wchief","w21","w22","w23"),
- // top2//local21
- config("local21",wombats("wchief","ww21","ww22")),
- // top2//rmi22
- config("rmi22",url(protocol),wombats("wchief","ww27","ww28","ww29"),
- // top2//rmi22//local24
- config("local24",wombats("wchief","www26","www27")),
- // top2//rmi22//rmi23
- config("rmi23",url(protocol),wombats("wchief","www23","www24","www25"),
- // top2//rmi22//rmi23//local25
- config("local25",wombats("wchief","wwww21"))))),
- // Top level namespace "top3" (remote)
- config("top3",url(protocol),wombats("wchief","w31","w32","w33"),
- // top3//local31
- config("local31",wombats("wchief","ww31","ww32")),
- // top3//rmi32
- config("rmi32",url(protocol),wombats("wchief","ww37","ww38","ww39"),
- // top3//rmi32//local34
- config("local34",wombats("wchief","www36","www37")),
- // top3//rmi32//rmi33
- config("rmi33",url(protocol),wombats("wchief","www33","www34","www35"),
- // top3//rmi32//local35
- config("local35",wombats("wchief","wwww31"))))),
- };
- return config;
- }
-
- /**
- * Close all connector servers in the list.
- * @param cslist List of connector servers to close.
- */
- public static void closeAll(List<JMXConnectorServer> cslist) {
- for (JMXConnectorServer cs : cslist) {
- try {
- cs.stop();
- } catch (Exception xx) {
- System.err.println("Failed to stop connector: " + xx);
- }
- }
- }
-
- public static class MBeanServerConfigCreator {
- public MBeanServer createMBeanServerFor(NamespaceConfig config) {
- return MBeanServerFactory.newMBeanServer();
- }
- }
-
- /**
- * Load the given namespace configuration inside the given MBeanServer.
- * Return a list of connector servers created in the process.
- * @param server The MBeanServer in which the namespaces must
- * be created.
- * @param namespaces The list of namespaces to create.
- * @return a list of started connector servers.
- * @throws java.lang.Exception failed to create the specified namespaces.
- */
- public static List<JMXConnectorServer> load(MBeanServer server,
- MBeanServerConfigCreator factory,
- NamespaceConfig... namespaces) throws Exception {
- final List<JMXConnectorServer> cslist =
- new ArrayList<JMXConnectorServer>();
- try {
- final ObjectName creator =
- new ObjectName("jmx.creator:type=JMXNamespaceCreator");
- if (System.getProperty("jmx.wait")!=null
- && !server.isRegistered(creator)) {
- server.registerMBean(new JMXNamespaceCreator(),creator);
- }
- for (NamespaceConfig cfg : namespaces) {
- final MBeanServer srv = factory.createMBeanServerFor(cfg);
- if (System.getProperty("jmx.wait")!=null
- && !srv.isRegistered(creator)) {
- srv.registerMBean(new JMXNamespaceCreator(),creator);
- }
- if (cfg.wombats != null) {
- for (String w : cfg.wombats) {
- final ObjectName n =
- new ObjectName("wombat:type=Wombat,name=" + w);
- final WombatMBean ww = new Wombat();
- srv.registerMBean(ww, n);
- }
- }
- if (cfg.children != null) {
- cslist.addAll(load(srv, factory, cfg.children));
- }
- JMXNamespace nm;
- if (cfg.jmxurl == null) {
- nm = new JMXNamespace(srv);
- } else {
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL(cfg.jmxurl),
- null, srv);
- srv.registerMBean(cs,
- new ObjectName("jmx.remote:type=JMXConnectorServer"));
- cs.start();
- cslist.add(cs);
- nm = JMXRemoteNamespace.
- newJMXRemoteNamespace(cs.getAddress(),
- null);
- }
- server.registerMBean(nm,
- JMXNamespaces.getNamespaceObjectName(cfg.name));
- if (nm instanceof JMXRemoteNamespace) {
- server.invoke(
- JMXNamespaces.getNamespaceObjectName(cfg.name),
- "connect", null, null);
- }
- }
- } catch (Exception x) {
- closeAll(cslist);
- throw x;
- }
- return cslist;
- }
-
- /**
- * Add an entry {@code <path,NamespaceConfig>} in the map for the given
- * namespace and its subnamespaces.
- * @param map A {@code Map<path,NamespaceConfig>}.
- * @param parent The path of the parent workspace.
- * @param cfg The NamespaceConfig hierarchy to index in the map.
- */
- public static void fillMap(Map<String,NamespaceConfig> map, String parent,
- NamespaceConfig cfg) {
-
- final String where;
- if (parent == null || parent.equals(""))
- where=cfg.name;
- else
- where=parent+JMXNamespaces.NAMESPACE_SEPARATOR+cfg.name;
- map.put(where,cfg);
- if (cfg.children==null) return;
- for(NamespaceConfig child:cfg.children) {
- fillMap(map,where,child);
- }
- }
-
- /**
- * Compare a list of namespace names obtained from JMXNamespaceView.list()
- * with the expected clildren list of the corresponding NamespaceConfig.
- * @param list A list of namespace names
- * @param children A list of NamespaceConfig correspondng to expected
- * namespace.
- * @param fail If true and the comparison yields false, throws an
- * exception instead of simply returning false.
- * @return true if OK, false if NOK.
- */
- private static boolean compare(String[] list, NamespaceConfig[] children,
- boolean fail) {
- final List<String> found = new ArrayList<String>(Arrays.asList(list));
- if (found.contains(ClientContext.NAMESPACE))
- found.remove(ClientContext.NAMESPACE);
-
- if (children == null && found.size()==0) return true;
- if (children == null && fail == false) return false;
- if (children == null) throw new RuntimeException(
- "No child expected. Found "+Arrays.toString(list));
- final Set<String> names = new HashSet<String>();
- for (NamespaceConfig cfg : children) {
- names.add(cfg.name);
- if (found.contains(cfg.name)) continue;
- if (!fail) return false;
- throw new RuntimeException(cfg.name+" not found in "+
- found);
- }
- found.removeAll(names);
- if (found.size()==0) return true;
- if (fail==false) return false;
- throw new RuntimeException("found additional namespaces: "+
- found);
- }
-
- /**
- * Compares the result of queryNames(null,null) with a set of expected
- * wombats.
- * @param where The path of the namespace that was queried.
- * @param list The set of ObjectNames found.
- * @param wombats The expected list of wombats.
- * @param fail If true and the comparison yields false, throws an
- * exception instead of simply returning false.
- * @return true if OK, false if NOK.
- * @throws java.lang.Exception something went wrong.
- */
- private static boolean compare(String where,
- Set<ObjectName>list, String[] wombats,
- boolean fail) throws Exception {
- final Set<ObjectName> found = new HashSet<ObjectName>();
- final Set<ObjectName> expected = new HashSet<ObjectName>();
- for (ObjectName n : list) {
- if ("Wombat".equals(n.getKeyProperty("type")))
- found.add(n);
- }
- for(String w : wombats) {
- final ObjectName n =
- new ObjectName("wombat:type=Wombat,name=" + w);
- expected.add(n);
- if (found.contains(n)) continue;
- if (fail == false) return false;
- throw new RuntimeException(where+
- ": Wombat "+w+" not found in "+found);
- }
- found.removeAll(expected);
- if (found.size()==0) {
- System.out.println(where+": found all expected: "+expected);
- return true;
- }
- if (fail==false) return false;
- throw new RuntimeException(where+": found additional MBeans: "+
- found);
- }
-
- /**
- * A generic test to test JMXNamespaceView over a namespace configuration.
- * @param server The MBeanServer in which to load the namespace
- * config.
- * @param namespaces The namespace config to run the test over...
- * @throws java.lang.Exception
- */
- public static void doTest(MBeanServer server, NamespaceConfig... namespaces)
- throws Exception {
- List<JMXConnectorServer> cslist = load(server,
- new MBeanServerConfigCreator(), namespaces);
- Map<String,NamespaceConfig> inputMap =
- new HashMap<String,NamespaceConfig>();
-
- for (NamespaceConfig cfg : namespaces) {
- fillMap(inputMap,"",cfg);
- }
- try {
- final JMXNamespaceView root = new JMXNamespaceView(server);
- List<JMXNamespaceView> vlist = new ArrayList<JMXNamespaceView>();
- vlist.add(root);
-
- while (!vlist.isEmpty()) {
- JMXNamespaceView v = vlist.remove(0);
- final String where = v.isRoot()?"root":v.where();
- System.out.println(where+": "+
- v.getMBeanServerConnection().queryNames(null,null));
- for (String ns : v.list()) {
- final JMXNamespaceView down = v.down(ns);
- vlist.add(down);
- if (!down.where().equals(v.isRoot()?ns:where+
- JMXNamespaces.NAMESPACE_SEPARATOR+ns)) {
- throw new RuntimeException("path of "+down.where()+
- " should be "+(v.isRoot()?ns:where+
- JMXNamespaces.NAMESPACE_SEPARATOR+ns));
- }
- if (down.up().equals(v)) continue;
- throw new RuntimeException("parent of "+down.where()+
- " should be "+where);
- }
- final NamespaceConfig[] children;
- final NamespaceConfig cfg;
- if (v.isRoot()) {
- children=namespaces;
- cfg = null;
- } else {
- cfg = inputMap.get(where);
- children = cfg==null?null:cfg.children;
- }
- compare(v.list(),children,true);
- if (!v.isRoot()) {
- if (where.endsWith(ClientContext.NAMESPACE)) {
- System.out.println(where+": skipping queryNames analysis");
- continue;
- }
- //System.out.println(where+": cfg is: "+cfg);
- compare(where,v.getMBeanServerConnection().
- queryNames(null, null),cfg.wombats,true);
- }
- }
-
- exportAndWaitIfNeeded(server);
- } finally {
- closeAll(cslist);
- }
- }
-
- public static interface JMXNamespaceCreatorMBean {
- public ObjectInstance createLocalNamespace(String namespace)
- throws JMException ;
- public void removeLocalNamespace(String namespace)
- throws JMException;
- }
-
- public static class JMXNamespaceCreator
- implements MBeanRegistration,
- JMXNamespaceCreatorMBean {
-
- private volatile MBeanServer mbeanServer;
-
- public ObjectInstance createLocalNamespace(String namespace)
- throws JMException {
- return mbeanServer.registerMBean(
- new JMXNamespace(MBeanServerFactory.newMBeanServer()),
- JMXNamespaces.getNamespaceObjectName(namespace));
- }
-
- public void removeLocalNamespace(String namespace)
- throws JMException {
- mbeanServer.unregisterMBean(
- JMXNamespaces.getNamespaceObjectName(namespace));
- }
-
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- mbeanServer = server;
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
-
- public void postDeregister() {
- }
-
- }
-
- public static void exportAndWaitIfNeeded(MBeanServer server)
- throws Exception {
- if (System.getProperty("jmx.wait")!=null) {
- final int port = getPortFor("rmi");
- LocateRegistry.createRegistry(port);
- final JMXServiceURL url =
- new JMXServiceURL("rmi",null,port,
- "/jndi/rmi://localhost:"+port+"/jmxrmi");
- final JMXConnectorServer cs =
- JMXConnectorServerFactory.
- newJMXConnectorServer(url, null, server);
- cs.start();
- try {
- System.out.println("RMI Server waiting at: "+cs.getAddress());
- System.in.read();
- } finally {
- cs.stop();
- }
- }
- }
-
- public static int getPortFor(String protocol) throws Exception {
- final int aport =
- Integer.valueOf(System.getProperty("jmx."+protocol+".port","0"));
- if (aport > 0) return aport;
- final ServerSocket s = new ServerSocket(0);
- try {
- final int port = s.getLocalPort();
- return port;
- } finally {
- s.close();
- }
- }
-
- public static void main(String[] args) throws Exception {
- doTest(ManagementFactory.getPlatformMBeanServer(),makeConfig("rmi"));
- }
-
-}
--- a/jdk/test/javax/management/namespace/JMXNamespacesTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,648 +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.
- *
- * 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.
- */
-/*
- * @test JMXNamespacesTest.java
- * @summary Test the static method that rewrite ObjectNames in JMXNamespacesTest
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean JMXNamespacesTest
- * @compile -XDignore.symbol.file=true JMXNamespacesTest.java
- * @run main JMXNamespacesTest
- */
-
-import com.sun.jmx.namespace.ObjectNameRouter;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.logging.Logger;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespaces;
-
-/**
- * Class JMXNamespacesTest
- * @author Sun Microsystems, 2005 - All rights reserved.
- */
-public class JMXNamespacesTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(JMXNamespacesTest.class.getName());
-
- /** Creates a new instance of JMXNamespacesTest */
- public JMXNamespacesTest() {
- }
-
- public static class CustomObject implements Serializable {
- ObjectName toto;
- String titi;
- CustomObject(String toto, String titi) {
- try {
- this.toto = new ObjectName(toto);
- } catch (MalformedObjectNameException m) {
- throw new IllegalArgumentException(m);
- }
- this.titi = titi;
- }
- private Object[] data() {
- return new Object[] {toto, titi};
- }
- @Override
- public boolean equals(Object other) {
- if (! (other instanceof CustomObject)) return false;
- return Arrays.deepEquals(data(),((CustomObject)other).data());
- }
- @Override
- public int hashCode() {
- return Arrays.deepHashCode(data());
- }
- }
-
- public static CustomObject obj(String toto, String titi) {
- return new CustomObject(toto,titi);
- }
-
- private static String failure;
-
- public static void testDeepRewrite() throws Exception {
- failure = null;
- String s1 = "x//y//d:k=v";
- String s2 = "v//w//x//y//d:k=v";
- String p1 = "v//w";
- String p3 = "a//b";
-
- System.out.println("inserting "+p1);
- final CustomObject foo1 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(s1,s1),"",p1);
- assertEquals(foo1.toto.toString(),p1+"//"+s1);
- assertEquals(foo1.titi,s1);
-
- System.out.println("removing "+p1);
- final CustomObject foo2 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(s2,s2),p1,"");
- assertEquals(foo2.toto.toString(),s1);
- assertEquals(foo2.titi,s2);
-
- System.out.println("removing "+p1);
- final CustomObject foo3 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(p1+"//"+s2,s2),p1,"");
- assertEquals(foo3.toto.toString(),s2);
- assertEquals(foo3.titi,s2);
-
- System.out.println("replacing "+p1+" with "+p3);
- final CustomObject foo4 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(s2,s2),p1,p3);
- assertEquals(foo4.toto.toString(),p3+"//"+s1);
- assertEquals(foo4.titi,s2);
-
- System.out.println("replacing "+p1+" with "+p1);
- final CustomObject foo5 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(s2,s2),p1,p1);
- assertEquals(foo5.toto.toString(),s2);
- assertEquals(foo5.titi,s2);
-
- System.out.println("removing x//y in "+s2);
- try {
- final CustomObject foo7 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(s2,s2),"x//y","");
- failed("Remove x//y in "+s2+" should have failed!");
- } catch (IllegalArgumentException x) {
- System.out.println("Received expected exception: "+x);
- }
-
- System.out.println("replacing x//y with "+p3+" in "+s2);
- try {
- final CustomObject foo7 =
- JMXNamespaces.deepReplaceHeadNamespace(obj(s2,s2),"x//y",p3);
- failed("Replace x//y in "+s2+" should have failed!");
- } catch (IllegalArgumentException x) {
- System.out.println("Received expected exception: "+x);
- }
-
- if (failure != null) throw new Exception(failure);
- }
-
- private static String[][] wildcards = {
- { "", "*:*" },
- { "//", "//*:*" },
- { "foo", "foo//*:*" },
- { "//foo", "//foo//*:*" },
- { "////foo", "//foo//*:*" },
- { "foo//", "foo//*:*" },
- { "foo////", "foo//*:*" },
- { "//foo//", "//foo//*:*" },
- { "////foo//", "//foo//*:*" },
- { "////foo////", "//foo//*:*" },
- { "foo//bar", "foo//bar//*:*" },
- { "//foo//bar", "//foo//bar//*:*" },
- { "////foo//bar", "//foo//bar//*:*" },
- { "foo//bar//", "foo//bar//*:*" },
- { "foo//bar////", "foo//bar//*:*" },
- { "//foo//bar//", "//foo//bar//*:*" },
- { "////foo//bar//", "//foo//bar//*:*" },
- { "////foo//bar////", "//foo//bar//*:*" },
- { "foo////bar", "foo//bar//*:*" },
- { "//foo////bar", "//foo//bar//*:*" },
- { "////foo////bar", "//foo//bar//*:*" },
- { "foo////bar//", "foo//bar//*:*" },
- { "foo////bar////", "foo//bar//*:*" },
- { "//foo////bar//", "//foo//bar//*:*" },
- { "////foo////bar//", "//foo//bar//*:*" },
- { "////foo////bar////", "//foo//bar//*:*" },
- { "fo/o", "fo/o//*:*" },
- { "//f/oo", "//f/oo//*:*" },
- { "////f/o/o", "//f/o/o//*:*" },
- { "fo/o//", "fo/o//*:*" },
- { "f/oo////", "f/oo//*:*" },
- { "//fo/o//", "//fo/o//*:*" },
- { "////f/oo//", "//f/oo//*:*" },
- { "////f/o/o////", "//f/o/o//*:*" },
- { "foo//b/a/r", "foo//b/a/r//*:*" },
- { "//fo/o//bar", "//fo/o//bar//*:*" },
- { "////foo//b/ar", "//foo//b/ar//*:*" },
- { "foo//ba/r//", "foo//ba/r//*:*" },
- { "f/oo//bar////", "f/oo//bar//*:*" },
- { "//f/o/o//bar//", "//f/o/o//bar//*:*" },
- { "////foo//b/a/r//", "//foo//b/a/r//*:*" },
- { "////f/o/o//b/a/r////", "//f/o/o//b/a/r//*:*" },
- { "foo////ba/r", "foo//ba/r//*:*" },
- { "//foo////b/ar", "//foo//b/ar//*:*" },
- { "////f/oo////bar", "//f/oo//bar//*:*" },
- { "fo/o////bar//", "fo/o//bar//*:*" },
- { "foo////ba/r////", "foo//ba/r//*:*" },
- { "//fo/o////ba/r//", "//fo/o//ba/r//*:*" },
- { "////f/oo////b/ar//", "//f/oo//b/ar//*:*" },
- { "////f/o/o////b/a/r////", "//f/o/o//b/a/r//*:*" },
- };
- private final static String[] badguys = {
- null,
- "/", "/*:*",
- "///", "///*:*" ,
- "/foo", "/foo//*:*",
- "//foo/", "//foo///*:*" ,
- "/////foo", "///foo//*:*",
- "/foo//", "/foo//*:*",
- "foo/////", "foo///*:*",
- "///foo//", "///foo//*:*",
- "////foo///", "//foo///*:*" ,
- "/////foo/////", "///foo///*:*",
- "/foo//bar", "/foo//bar//*:*",
- "//foo///bar", "//foo///bar//*:*",
- "/////foo////bar/", "///foo//bar///*:*",
- "foo///bar//", "foo//bar///*:*",
- "foo//bar/////", "foo///bar//*:*",
- "///foo//bar//", "//foo///bar//*:*" ,
- };
- public static void testWildcard() throws Exception {
- int i = 0;
- for (String[] pair : wildcards) {
- i++;
- final String msg = "testWildcard[good,"+i+"] "+Arrays.asList(pair)+": ";
- assertEquals(msg, new ObjectName(pair[1]),
- JMXNamespaces.getWildcardFor(pair[0]));
- }
- i=0;
- for (String bad : badguys) {
- i++;
- try {
- JMXNamespaces.getWildcardFor(bad);
- failed("testWildcard[bad,"+i+"] "+bad+" incorrectly accepted. " +
- "IllegalArgumentException was expected");
- } catch (IllegalArgumentException x) {
- // OK
- }
- }
- if (failure != null) throw new Exception(failure);
- }
-
- private static String[][] goodinsert = {
- {"","d:k=v","d:k=v"},
- {"","//d:k=v","//d:k=v"},
- {"//","d:k=v","//d:k=v"},
- {"//","//d:k=v","//d:k=v"},
- {"//","a//d:k=v","//a//d:k=v"},
- {"//","//a//d:k=v","//a//d:k=v"},
- {"//","////a////d:k=v","//a//d:k=v"},
- {"//b","////a////d:k=v","//b//a//d:k=v"},
- {"b","////a////d:k=v","b//a//d:k=v"},
- {"b","d:k=v","b//d:k=v"},
- {"b//","d:k=v","b//d:k=v"},
- {"//b//","d:k=v","//b//d:k=v"},
- {"//b","////a////d:k=v","//b//a//d:k=v"},
- {"b//c","////a////d:k=v","b//c//a//d:k=v"},
- {"b//c","d:k=v","b//c//d:k=v"},
- {"b//c//","d:k=v","b//c//d:k=v"},
- {"//b//c//","d:k=v","//b//c//d:k=v"},
- {"","/d:k=v","/d:k=v"},
- {"","///d:k=v","///d:k=v"},
- {"//","/d:k=v","///d:k=v"},
- {"//","///d:k=v","///d:k=v"},
- {"//","a///d:k=v","//a///d:k=v"},
- {"//","//a///d:k=v","//a///d:k=v"},
- {"//","////a////d/:k=v","//a//d/:k=v"},
- {"//b","////a/////d:k=v","//b//a///d:k=v"},
- {"b","////a////d/:k=v","b//a//d/:k=v"},
- {"b","/d:k=v","b///d:k=v"},
- {"b//","/d:k=v","b///d:k=v"},
- {"//b//","/d:k=v","//b///d:k=v"},
- {"//b","////a/////d:k=v","//b//a///d:k=v"},
- {"b//c","////a/////d:k=v","b//c//a///d:k=v"},
- {"b//c","/d:k=v","b//c///d:k=v"},
- {"b//c//","/d:k=v","b//c///d:k=v"},
- {"//b//c//","d/:k=v","//b//c//d/:k=v"},
- };
-
- private static String[][] badinsert = {
- {"/","d:k=v"},
- {"/","//d:k=v"},
- {"///","d:k=v"},
- {"///","//d:k=v"},
- {"///","/a//d:k=v"},
- {"///","///a//d:k=v"},
- {"///","/////a////d:k=v"},
- {"//b","/////a////d:k=v"},
- {"b/","////a////d:k=v"},
- {"b/","d:k=v"},
- {"b///","d:k=v"},
- {"//b///","d:k=v"},
- {"//b/","////a////d:k=v"},
- {"b///c","////a////d:k=v"},
- {"b//c/","d:k=v"},
- {"b///c//","d:k=v"},
- {"//b///c//","d:k=v"},
-
- };
-
- public static void testInsertPath() throws Exception {
- int i = 0;
- for (String[] pair : goodinsert) {
- i++;
- final String msg = "testInsertPath[good,"+i+"] "+Arrays.asList(pair)+": ";
- assertEquals(msg,new ObjectName(pair[2]),
- JMXNamespaces.insertPath(pair[0],
- new ObjectName(pair[1])));
- }
- i=0;
- for (String[] bad : badinsert) {
- i++;
- try {
- JMXNamespaces.insertPath(bad[0],
- new ObjectName(bad[1]));
- failed("testInsertPath[bad,"+i+"] "+
- Arrays.asList(bad)+" incorrectly accepted. " +
- "IllegalArgumentException was expected");
- } catch (IllegalArgumentException x) {
- // OK
- }
- }
- if (failure != null) throw new Exception(failure);
- }
-
- private static String[][] testpath = {
- {"/a/a/:k=v",""},
- {"/:k=v",""},
- {"bli:k=v",""},
- {"///a/a/:k=v",""},
- {"///:k=v",""},
- {"//bli:k=v",""},
- {"/////a/a/:k=v",""},
- {"/////:k=v",""},
- {"////bli:k=v",""},
- {"y///a/a/:k=v","y"},
- {"y///:k=v","y"},
- {"y//bli:k=v","y"},
- {"y/////a/a/:k=v","y"},
- {"y/////:k=v","y"},
- {"y////bli:k=v","y"},
- {"//y///a/a/:k=v","y"},
- {"//y///:k=v","y"},
- {"//y//bli:k=v","y"},
- {"//y/////a/a/:k=v","y"},
- {"//y/////:k=v","y"},
- {"//y////bli:k=v","y"},
- {"////y///a/a/:k=v","y"},
- {"////y///:k=v","y"},
- {"////y//bli:k=v","y"},
- {"////y/////a/a/:k=v","y"},
- {"////y/////:k=v","y"},
- {"////y////bli:k=v","y"},
-
- {"z//y///a/a/:k=v","z//y"},
- {"z//y///:k=v","z//y"},
- {"z//y//bli:k=v","z//y"},
- {"z//y/////a/a/:k=v","z//y"},
- {"z//y/////:k=v","z//y"},
- {"z//y////bli:k=v","z//y"},
- {"//z//y///a/a/:k=v","z//y"},
- {"//z//y///:k=v","z//y"},
- {"//z//y//bli:k=v","z//y"},
- {"//z//y/////a/a/:k=v","z//y"},
- {"//z//y/////:k=v","z//y"},
- {"//z//y////bli:k=v","z//y"},
- {"z////y///a/a/:k=v","z//y"},
- {"z////y///:k=v","z//y"},
- {"z////y//bli:k=v","z//y"},
- {"z////y/////a/a/:k=v","z//y"},
- {"z////y/////:k=v","z//y"},
- {"z////y////bli:k=v","z//y"},
- {"//z////y///a/a/:k=v","z//y"},
- {"//z////y///:k=v","z//y"},
- {"//z////y//bli:k=v","z//y"},
- {"//z////y/////a/a/:k=v","z//y"},
- {"//z////y/////:k=v","z//y"},
- {"//z////y////bli:k=v","z//y"},
- {"////z////y///a/a/:k=v","z//y"},
- {"////z////y///:k=v","z//y"},
- {"////z////y//bli:k=v","z//y"},
- {"////z////y/////a/a/:k=v","z//y"},
- {"////z////y/////:k=v","z//y"},
- {"////z////y////bli:k=v","z//y"},
-
- };
-
- public static void testGetNormalizedPath() throws Exception {
- int i = 0;
- for (String[] pair : testpath) {
- i++;
- final String msg = "testGetNormalizedPath["+i+"] "+Arrays.asList(pair)+": ";
- assertEquals(msg,pair[1],
- JMXNamespaces.getContainingNamespace(new ObjectName(pair[0])));
- }
- if (failure != null) throw new Exception(failure);
- }
-
- private static String[][] testdomain = {
- {"/a/a/","/a/a/"},
- {"/","/"},
- {"bli","bli"},
- {"///a/a/","///a/a/"},
- {"///","///"},
- {"//bli","//bli"},
- {"/////a/a/","///a/a/"},
- {"/////","///"},
- {"////bli","//bli"},
- {"y///a/a/","y///a/a/"},
- {"y///","y///"},
- {"y//bli","y//bli"},
- {"y/////a/a/","y///a/a/"},
- {"y/////","y///"},
- {"y////bli","y//bli"},
- {"//y///a/a/","//y///a/a/"},
- {"//y///","//y///"},
- {"//y//bli","//y//bli"},
- {"//y/////a/a/","//y///a/a/"},
- {"//y/////","//y///"},
- {"//y////bli","//y//bli"},
- {"////y///a/a/","//y///a/a/"},
- {"////y///","//y///"},
- {"////y//bli","//y//bli"},
- {"////y/////a/a/","//y///a/a/"},
- {"////y/////","//y///"},
- {"////y////bli","//y//bli"},
-
- {"z//y///a/a/","z//y///a/a/"},
- {"z//y///","z//y///"},
- {"z//y//bli","z//y//bli"},
- {"z//y/////a/a/","z//y///a/a/"},
- {"z//y/////","z//y///"},
- {"z//y////bli","z//y//bli"},
- {"//z//y///a/a/","//z//y///a/a/"},
- {"//z//y///","//z//y///"},
- {"//z//y//bli","//z//y//bli"},
- {"//z//y/////a/a/","//z//y///a/a/"},
- {"//z//y/////","//z//y///"},
- {"//z//y////bli","//z//y//bli"},
- {"z////y///a/a/","z//y///a/a/"},
- {"z////y///","z//y///"},
- {"z////y//bli","z//y//bli"},
- {"z////y/////a/a/","z//y///a/a/"},
- {"z////y/////","z//y///"},
- {"z////y////bli","z//y//bli"},
- {"//z////y///a/a/","//z//y///a/a/"},
- {"//z////y///","//z//y///"},
- {"//z////y//bli","//z//y//bli"},
- {"//z////y/////a/a/","//z//y///a/a/"},
- {"//z////y/////","//z//y///"},
- {"//z////y////bli","//z//y//bli"},
- {"////z////y///a/a/","//z//y///a/a/"},
- {"////z////y///","//z//y///"},
- {"////z////y//bli","//z//y//bli"},
- {"////z////y/////a/a/","//z//y///a/a/"},
- {"////z////y/////","//z//y///"},
- {"////z////y////bli","//z//y//bli"},
-
- {"bli//","bli//"},
- {"//bli//","//bli//"},
- {"////bli//","//bli//"},
- {"y////","y//"},
- {"y//bli//","y//bli//"},
- {"y////","y//"},
- {"y////bli//","y//bli//"},
- {"//y////","//y//"},
- {"//y//bli//","//y//bli//"},
- {"//y//////","//y//"},
- {"//y////bli//","//y//bli//"},
- {"////y////","//y//"},
- {"////y//bli////","//y//bli//"},
- {"////y//////","//y//"},
- {"////y////bli////","//y//bli//"},
- {"z//y////","z//y//"},
- {"z//y//bli//","z//y//bli//"},
- {"z//y//////","z//y//"},
- {"z//y////bli//","z//y//bli//"},
- {"//z//y////","//z//y//"},
- {"//z//y//bli//","//z//y//bli//"},
- {"//z//y//////","//z//y//"},
- {"//z//y////bli//","//z//y//bli//"},
- {"z////y////","z//y//"},
- {"z////y//bli//","z//y//bli//"},
- {"z////y//////","z//y//"},
- {"z////y////bli//","z//y//bli//"},
- {"//z////y////","//z//y//"},
- {"//z////y//bli//","//z//y//bli//"},
- {"//z////y//////","//z//y//"},
- {"//z////y////bli//","//z//y//bli//"},
- {"////z////y////","//z//y//"},
- {"////z////y//bli//","//z//y//bli//"},
- {"////z////y//////","//z//y//"},
- {"////z////y////bli//","//z//y//bli//"},
-
- };
- private static String[][] testnolead = {
- {"/a/a/","/a/a/"},
- {"/","/"},
- {"bli","bli"},
- {"///a/a/","/a/a/"},
- {"///","/"},
- {"//bli","bli"},
- {"/////a/a/","/a/a/"},
- {"/////","/"},
- {"////bli","bli"},
- {"y///a/a/","y///a/a/"},
- {"y///","y///"},
- {"y//bli","y//bli"},
- {"y/////a/a/","y///a/a/"},
- {"y/////","y///"},
- {"y////bli","y//bli"},
- {"//y///a/a/","y///a/a/"},
- {"//y///","y///"},
- {"//y//bli","y//bli"},
- {"//y/////a/a/","y///a/a/"},
- {"//y/////","y///"},
- {"//y////bli","y//bli"},
- {"////y///a/a/","y///a/a/"},
- {"////y///","y///"},
- {"////y//bli","y//bli"},
- {"////y/////a/a/","y///a/a/"},
- {"////y/////","y///"},
- {"////y////bli","y//bli"},
-
- {"z//y///a/a/","z//y///a/a/"},
- {"z//y///","z//y///"},
- {"z//y//bli","z//y//bli"},
- {"z//y/////a/a/","z//y///a/a/"},
- {"z//y/////","z//y///"},
- {"z//y////bli","z//y//bli"},
- {"//z//y///a/a/","z//y///a/a/"},
- {"//z//y///","z//y///"},
- {"//z//y//bli","z//y//bli"},
- {"//z//y/////a/a/","z//y///a/a/"},
- {"//z//y/////","z//y///"},
- {"//z//y////bli","z//y//bli"},
- {"z////y///a/a/","z//y///a/a/"},
- {"z////y///","z//y///"},
- {"z////y//bli","z//y//bli"},
- {"z////y/////a/a/","z//y///a/a/"},
- {"z////y/////","z//y///"},
- {"z////y////bli","z//y//bli"},
- {"//z////y///a/a/","z//y///a/a/"},
- {"//z////y///","z//y///"},
- {"//z////y//bli","z//y//bli"},
- {"//z////y/////a/a/","z//y///a/a/"},
- {"//z////y/////","z//y///"},
- {"//z////y////bli","z//y//bli"},
- {"////z////y///a/a/","z//y///a/a/"},
- {"////z////y///","z//y///"},
- {"////z////y//bli","z//y//bli"},
- {"////z////y/////a/a/","z//y///a/a/"},
- {"////z////y/////","z//y///"},
- {"////z////y////bli","z//y//bli"},
-
- {"bli//","bli//"},
- {"//bli//","bli//"},
- {"////bli//","bli//"},
- {"y////","y//"},
- {"y//bli//","y//bli//"},
- {"y////","y//"},
- {"y////bli//","y//bli//"},
- {"//y////","y//"},
- {"//y//bli//","y//bli//"},
- {"//y//////","y//"},
- {"//y////bli//","y//bli//"},
- {"////y////","y//"},
- {"////y//bli////","y//bli//"},
- {"////y//////","y//"},
- {"////y////bli////","y//bli//"},
- {"z//y////","z//y//"},
- {"z//y//bli//","z//y//bli//"},
- {"z//y//////","z//y//"},
- {"z//y////bli//","z//y//bli//"},
- {"//z//y////","z//y//"},
- {"//z//y//bli//","z//y//bli//"},
- {"//z//y//////","z//y//"},
- {"//z//y////bli//","z//y//bli//"},
- {"z////y////","z//y//"},
- {"z////y//bli//","z//y//bli//"},
- {"z////y//////","z//y//"},
- {"z////y////bli//","z//y//bli//"},
- {"//z////y////","z//y//"},
- {"//z////y//bli//","z//y//bli//"},
- {"//z////y//////","z//y//"},
- {"//z////y////bli//","z//y//bli//"},
- {"////z////y////","z//y//"},
- {"////z////y//bli//","z//y//bli//"},
- {"////z////y//////","z//y//"},
- {"////z////y////bli//","z//y//bli//"},
-
- };
-
- public static void testNormalizeDomain() throws Exception {
- int i = 0;
- for (String[] pair : testdomain) {
- i++;
- final String msg = "testNormalizeDomain["+i+", false] "+Arrays.asList(pair)+": ";
- assertEquals(msg,pair[1],
- ObjectNameRouter.normalizeDomain(pair[0],false));
- }
- if (failure != null) throw new Exception(failure);
- i = 0;
- for (String[] pair : testnolead) {
- i++;
- final String msg = "testNormalizeDomain["+i+", true] "+Arrays.asList(pair)+": ";
- assertEquals(msg,pair[1],
- ObjectNameRouter.normalizeDomain(pair[0],true));
- }
- if (failure != null) throw new Exception(failure);
- }
-
- public static void main(String[] args) throws Exception {
- testDeepRewrite();
- testNormalizeDomain();
- testInsertPath();
- testWildcard();
- testGetNormalizedPath();
- }
-
- private static void assertEquals(Object x, Object y) {
- assertEquals("",x,y);
- }
-
- private static void assertEquals(String msg, Object x, Object y) {
- if (msg == null) msg="";
- if (!equal(x, y))
- failed(msg+"expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-
-}
--- a/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +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.
- *
- * 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.
- */
-/*
- *
- * @test JMXRemoteNamespaceTest.java
- * @summary Basic tests on a JMXRemoteNamespace.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean JMXRemoteNamespaceTest Wombat WombatMBean
- * @run build JMXRemoteNamespaceTest Wombat WombatMBean
- * @run main JMXRemoteNamespaceTest
- */
-
-import javax.management.JMX;
-import javax.management.Notification;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.NotificationListener;
-import javax.management.namespace.JMXRemoteNamespace;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.io.IOException;
-import javax.management.AttributeChangeNotification;
-
-/**
- * Test simple creation/registration of namespace.
- *
- */
-public class JMXRemoteNamespaceTest {
-
- static class MyConnect implements NotificationListener {
- private final JMXRemoteNamespace my;
- private final List<Notification> list;
- private volatile int connectCount=0;
- private int closeCount=0;
- private final ObjectName myname;
- public MyConnect(JMXRemoteNamespace my, ObjectName myname) {
- this.my=my;
- this.myname = myname;
- list = Collections.synchronizedList(new ArrayList<Notification>());
- my.addNotificationListener(this, null, null);
- }
-
- public synchronized void connect() throws IOException {
- my.connect();
- if (!my.isConnected())
- throw new IOException(myname+" should be connected");
- connectCount++;
- }
-
- public void close() throws IOException {
- my.close();
- if (my.isConnected())
- throw new IOException(myname+" shouldn't be connected");
- closeCount++;
- }
-
- public synchronized int getConnectCount() {
- return connectCount;
- }
- public synchronized int getClosedCount() {
- return closeCount;
- }
-
- public synchronized void handleNotification(Notification notification,
- Object handback) {
- list.add(notification);
- }
-
- public synchronized void checkNotifs(int externalConnect,
- int externalClosed) throws Exception {
- System.err.println("Connected: "+connectCount+" time"+
- ((connectCount>1)?"s":""));
- System.err.println("Closed: "+closeCount+" time"+
- ((closeCount>1)?"s":""));
- System.err.println("Received:");
- int cl=0;
- int co=0;
- for (Notification n : list) {
- System.err.println("\t"+n);
- if (!(n instanceof AttributeChangeNotification))
- throw new Exception("Unexpected notif: "+n.getClass());
- final AttributeChangeNotification acn =
- (AttributeChangeNotification)n;
- if (((Boolean)acn.getNewValue()).booleanValue())
- co++;
- else cl++;
- if ((((Boolean)acn.getNewValue()).booleanValue())
- == (((Boolean)acn.getOldValue()).booleanValue())) {
- throw new Exception("Bad values: old=new");
- }
- }
- if (! (list.size()==(closeCount+connectCount+
- externalClosed+externalConnect))) {
- throw new Exception("Bad notif count - got "+list.size());
- }
- if (cl!=(closeCount+externalClosed)) {
- throw new Exception("Bad count of close notif: expected "
- +(closeCount+externalClosed)+", got"+cl);
- }
- if (co!=(connectCount+externalConnect)) {
- throw new Exception("Bad count of connect notif: expected "
- +(connectCount+externalConnect)+", got"+co);
- }
- }
- }
-
- public static void testConnectClose() throws Exception {
- final MBeanServer myServer = MBeanServerFactory.newMBeanServer();
- final JMXConnectorServer myRMI =
- JMXConnectorServerFactory.newJMXConnectorServer(
- new JMXServiceURL("rmi",null,0), null, myServer);
- myRMI.start();
- try {
- final JMXRemoteNamespace my =
- JMXRemoteNamespace.newJMXRemoteNamespace(
- myRMI.getAddress(),null);
- final MBeanServer s = MBeanServerFactory.newMBeanServer();
- final ObjectName myname = JMXNamespaces.getNamespaceObjectName("my");
- final ObjectName wname = ObjectName.getInstance("backyard:type=Wombat");
- myServer.registerMBean(new Wombat(),wname);
- final MyConnect myc = new MyConnect(my,myname);
- myc.connect();
- myc.close();
- myc.connect();
- s.registerMBean(my,myname);
- myc.close();
- myc.connect();
- if (!s.queryNames(new ObjectName("my//b*:*"),null).contains(
- JMXNamespaces.insertPath("my", wname))) {
- throw new RuntimeException("1: Wombat not found: "+wname);
- }
- myc.close();
- myc.connect();
- final MBeanServer cd = JMXNamespaces.narrowToNamespace(s, "my");
- if (!cd.queryNames(new ObjectName("b*:*"),null).contains(wname)) {
- throw new RuntimeException("2: Wombat not found: "+wname);
- }
- myc.close();
- myc.connect();
- System.out.println("Found a Wombat in my backyard.");
-
- final String deepThoughts = "I want to leave this backyard!";
- final WombatMBean w = JMX.newMBeanProxy(cd, wname, WombatMBean.class);
- w.setCaption(deepThoughts);
- if (!deepThoughts.equals(w.getCaption()))
- throw new RuntimeException("4: Wombat is not thinking right: "+
- w.getCaption());
- s.unregisterMBean(myname);
- if (my.isConnected())
- throw new Exception(myname+" shouldn't be connected");
- myc.connect();
- myc.close();
- myc.checkNotifs(0,1);
- } finally {
- myRMI.stop();
- }
-
- }
-
- public static void main(String... args) throws Exception {
- testConnectClose();
- }
-}
--- a/jdk/test/javax/management/namespace/JMXRemoteTargetNamespace.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +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.
- */
-
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.MBeanException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServerConnection;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.event.EventClient;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXRemoteNamespace;
-import javax.management.namespace.JMXRemoteNamespaceMBean;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXServiceURL;
-
-// These options originally in the draft of javax/management/namespaces
-// but we decided to retire them - since they could be implemented
-// by subclasses. The JMXRemoteTargetNamespace is such a subclass.
-//
-public class JMXRemoteTargetNamespace extends JMXRemoteNamespace {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(JMXRemoteTargetNamespace.class.getName());
- public static final String CREATE_EVENT_CLIENT =
- "jmx.test.create.event.client";
-
- private final String sourceNamespace;
- private final boolean createEventClient;
-
- public JMXRemoteTargetNamespace(JMXServiceURL sourceURL,
- Map<String,?> optionsMap) {
- this(sourceURL,optionsMap,null);
- }
-
- public JMXRemoteTargetNamespace(JMXServiceURL sourceURL,
- Map<String,?> optionsMap, String sourceNamespace) {
- super(sourceURL, optionsMap);
- this.sourceNamespace = sourceNamespace;
- this.createEventClient = createEventClient(optionsMap);
- }
-
- private boolean createEventClient(Map<String,?> options) {
- if (options == null) return false;
- final Object createValue = options.get(CREATE_EVENT_CLIENT);
- if (createValue == null) return false;
- if (createValue instanceof Boolean)
- return ((Boolean)createValue).booleanValue();
- if (createValue instanceof String)
- return Boolean.valueOf((String)createValue);
- throw new IllegalArgumentException("Bad type for value of property " +
- CREATE_EVENT_CLIENT+": "+createValue.getClass().getName());
- }
-
- @Override
- protected MBeanServerConnection getMBeanServerConnection(JMXConnector jmxc)
- throws IOException {
- MBeanServerConnection mbsc = super.getMBeanServerConnection(jmxc);
- if (sourceNamespace != null && sourceNamespace.length() > 0)
- mbsc = JMXNamespaces.narrowToNamespace(mbsc, sourceNamespace);
- if (createEventClient)
- mbsc = EventClient.getEventClientConnection(mbsc);
- return mbsc;
- }
-
-
- /**
- * Creates a target name space to mirror a remote source name space in
- * the target server.
- * @param targetServer A connection to the target MBean server in which
- * the new name space should be created.
- * @param targetPath the name space to create in the target server. Note
- * that if the target name space is a path - that is if
- * {@code targetPath} contains '//', then the parent name space
- * must be pre-existing in the target server. Attempting to create
- * {code targetPath="a//b//c"} in {@code targetServer}
- * will fail if name space {@code "a//b"} doesn't already exists
- * in {@code targetServer}.
- * @param sourceURL a JMX service URL that can be used to connect to the
- * source MBean server.
- * @param options the set of options to use when creating the
- * {@link #JMXRemoteNamespace JMXRemoteNamespace} that will
- * handle the new name space.
- * @return An {@code ObjectInstance} representing the
- * {@link JMXRemoteNamespaceMBean} which handles the
- * new name space.
- *
- **/
- public static ObjectInstance createNamespace(
- MBeanServerConnection targetServer,
- String targetPath,
- JMXServiceURL sourceURL,
- Map<String,?> options)
- throws IOException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException {
- final ObjectName name =
- JMXNamespaces.getNamespaceObjectName(targetPath);
- return createInstance(targetServer, name, sourceURL, options, null);
- }
-
- /**
- * Creates a target name space to mirror a remote source name space in
- * the target server.
- * @param targetServer A connection to the target MBean server in which
- * the new name space should be created.
- * @param targetPath the name space to create in the target server. Note
- * that if the target name space is a path - that is if
- * {@code targetPath} contains '//', then the parent name space
- * must be pre-existing in the target server. Attempting to create
- * {code targetPath="a//b//c"} in {@code targetServer}
- * will fail if name space {@code "a//b"} doesn't already exists
- * in {@code targetServer}.
- * @param sourceURL a JMX service URL that can be used to connect to the
- * source MBean server.
- * @param sourcePath the source namespace path insode the source server.
- * @param options the set of options to use when creating the
- * {@link #JMXRemoteNamespace JMXRemoteNamespace} that will
- * handle the new name space.
- * @return An {@code ObjectInstance} representing the
- * {@link JMXRemoteNamespaceMBean} which handles the
- * new name space.
- *
- **/
- public static ObjectInstance createNamespace(
- MBeanServerConnection targetServer,
- String targetPath,
- JMXServiceURL sourceURL,
- Map<String,?> options,
- String sourcePath)
- throws IOException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException {
- final ObjectName name =
- JMXNamespaces.getNamespaceObjectName(targetPath);
- return createInstance(targetServer, name, sourceURL, options, sourcePath);
- }
-
- /**
- * Creates and registers a {@link JMXRemoteNamespaceMBean} in a target
- * server, to mirror a remote source name space.
- *
- * @param server A connection to the target MBean server in which
- * the new name space should be created.
- * @param handlerName the name of the JMXRemoteNamespace to create.
- * This must be a compliant name space handler name as returned
- * by {@link
- * JMXNamespaces#getNamespaceObjectName JMXNamespaces.getNamespaceObjectName}.
- * @param sourceURL a JMX service URL that can be used to connect to the
- * source MBean server.
- * @param sourcePath the path inside the source server
- * @param options the set of options to use when creating the
- * {@link #JMXRemoteNamespace JMXRemoteNamespace} that will
- * handle the new name space.
- * @return An {@code ObjectInstance} representing the new
- * {@link JMXRemoteNamespaceMBean} created.
- * @see #createNamespace createNamespace
- */
- static ObjectInstance createInstance(MBeanServerConnection server,
- ObjectName handlerName,
- JMXServiceURL sourceURL, Map<String,?> options,
- String sourcePath)
- throws IOException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException {
- try {
- final String[] signature = {
- JMXServiceURL.class.getName(),
- Map.class.getName(),
- String.class.getName()
- };
- final Object[] params = {
- sourceURL,options,sourcePath
- };
- final ObjectInstance instance =
- server.createMBean(JMXRemoteTargetNamespace.class.getName(),
- handlerName,params,signature);
- return instance;
- } catch (NotCompliantMBeanException ex) {
- throw new RuntimeException("unexpected exception: " + ex, ex);
- } catch (ReflectionException ex) {
- throw new RuntimeException("unexpected exception: " + ex, ex);
- }
- }
-
-}
--- a/jdk/test/javax/management/namespace/LazyDomainTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,790 +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.
- *
- * 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.
- */
-/*
- *
- * @test LazyDomainTest.java
- * @bug 5072476
- * @summary Basic test for Lazy Domains.
- * @author Daniel Fuchs
- * @run clean LazyDomainTest Wombat WombatMBean
- * @run build LazyDomainTest Wombat WombatMBean
- * @run main LazyDomainTest
- */
-
-
-import java.lang.management.ClassLoadingMXBean;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.Map;
-import java.util.Set;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerBuilder;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerFactory;
-import javax.management.MBeanServerNotification;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXDomain;
-import javax.management.remote.MBeanServerForwarder;
-
-/**
- * Test simple creation/registration of namespace.
- *
- */
-public class LazyDomainTest {
- private static Map<String,Object> emptyEnvMap() {
- return Collections.emptyMap();
- }
-
-
- public static interface MBeanServerLoader {
- public MBeanServer loadMBeanServer();
- }
-
-
- public static class MBeanServerProxy implements InvocationHandler {
-
- private final static Map<Method,Method> localMap;
- static {
- localMap = new HashMap<Method, Method>();
- for (Method m : MBeanServerForwarder.class.getDeclaredMethods()) {
- try {
- final Method loc = MBeanServerProxy.class.
- getMethod(m.getName(), m.getParameterTypes());
- localMap.put(m, loc);
- } catch (Exception x) {
- // not defined...
- }
- }
- try {
- localMap.put(MBeanServer.class.
- getMethod("getMBeanCount", (Class[]) null),
- MBeanServerProxy.class.
- getMethod("getMBeanCount", (Class[]) null));
- } catch (NoSuchMethodException x) {
- // OK.
- }
- }
-
- private final MBeanServerLoader loader;
- private MBeanServer server;
- private final Set<LazyDomain> domains;
-
- public MBeanServerProxy(MBeanServerLoader loader) {
- if (loader == null)
- throw new IllegalArgumentException("null loader");
- this.loader = loader;
- this.server = null;
- domains = new HashSet<LazyDomain>();
- }
-
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (method.getDeclaringClass().equals(Object.class)) {
- return invokeMethod(this,method,args);
- }
- final Method local = localMap.get(method);
- if (local != null) {
- return invokeMethod(this,local,args);
- }
- if (method.getDeclaringClass().equals(MBeanServer.class)) {
- return invokeMethod(getMBeanServer(),method,args);
- }
- throw new NoSuchMethodException(method.getName());
- }
-
- private Object invokeMethod(Object on, Method method, Object[] args)
- throws Throwable {
- try {
- return method.invoke(on, args);
- } catch (InvocationTargetException ex) {
- throw ex.getTargetException();
- }
- }
-
- public synchronized MBeanServer getMBeanServer() {
- if (server == null) setMBeanServer(loader.loadMBeanServer());
- return server;
- }
-
- public synchronized void setMBeanServer(MBeanServer mbs) {
- this.server = mbs;
- if (mbs != null) {
- for (LazyDomain dom : domains) dom.loaded();
- domains.clear();
- }
- }
-
- public synchronized boolean isLoaded() {
- return server != null;
- }
-
- public synchronized void add(LazyDomain dom) {
- if (isLoaded()) dom.loaded();
- else domains.add(dom);
- }
-
- public synchronized boolean remove(LazyDomain dom) {
- return domains.remove(dom);
- }
-
- public Integer getMBeanCount() {
- if (isLoaded()) return server.getMBeanCount();
- else return Integer.valueOf(0);
- }
- }
-
- public static class LazyDomain extends JMXDomain {
- public static MBeanServer makeProxyFor(MBeanServerProxy proxy) {
- return (MBeanServer)
- Proxy.newProxyInstance(LazyDomain.class.getClassLoader(),
- new Class[] {MBeanServer.class, MBeanServerForwarder.class},
- proxy);
- }
-
- private final MBeanServerProxy proxy;
- private volatile NotificationListener listener;
- private volatile NotificationFilter filter;
-
- public LazyDomain(MBeanServerProxy proxy) {
- super(makeProxyFor(proxy));
- this.proxy = proxy;
- }
-
- @Override
- public Integer getMBeanCount() {
- if (proxy.isLoaded())
- return super.getMBeanCount();
- return 0;
- }
-
-
- @Override
- public synchronized void addMBeanServerNotificationListener(
- NotificationListener listener,
- NotificationFilter filter) {
- if (proxy.isLoaded()) {
- super.addMBeanServerNotificationListener(listener, filter);
- } else {
- this.listener = listener;
- this.filter = filter;
- proxy.add(this);
- }
- }
-
- @Override
- public synchronized void removeMBeanServerNotificationListener(
- NotificationListener listener)
- throws ListenerNotFoundException {
- if (this.listener != listener)
- throw new ListenerNotFoundException();
- this.listener = null;
- this.filter = null;
- if (proxy.isLoaded())
- super.removeMBeanServerNotificationListener(listener);
- proxy.remove(this);
- }
-
- public synchronized void loaded() {
- if (listener != null)
- addMBeanServerNotificationListener(listener, filter);
- }
-
- }
-
- /**
- * This is a use case for e.g GlassFish: the LazyStarterDomain MBean
- * is a place holder that will unregister itself and autoload a set
- * of MBeans in place of its own domain when that domain is
- * accessed.
- * This is an abstract class, where the only abstract method
- * is loadMBeans(MBeanServer).
- * Subclasses should implement that method to register whatever MBeans
- * in the domain previously held by that LazyStarterDomain object.
- * In other words: the LazyStarterDomain MBean is 'replaced' by the
- * MBeans loaded by loadMBeans();
- */
- public static abstract class LazyStarterDomain extends LazyDomain {
-
- /**
- * This is a loader that will unregister the JMXDomain that
- * created it, and register a bunch of MBeans in its place
- * by calling LazyStarterDomain.loadMBeans
- *
- * That one gave me "la migraine".
- */
- private static class HalfGrainLoader implements MBeanServerLoader {
- private volatile LazyStarterDomain domain;
- public MBeanServer loadMBeanServer() {
- if (domain == null)
- throw new IllegalStateException(
- "JMXDomain MBean not registered!");
- final MBeanServer server = domain.getMBeanServer();
- final ObjectName domainName = domain.getObjectName();
- try {
- server.unregisterMBean(domainName);
- } catch (Exception x) {
- throw new IllegalStateException("Can't unregister " +
- "JMXDomain: "+x,x);
- }
- domain.loadMBeans(server,domainName.getDomain());
- return server;
- }
- public void setDomain(LazyStarterDomain domain) {
- this.domain = domain;
- }
- }
-
- /**
- * This is an MBeanServerProxy which create a loader for the
- * LazyStarterDomain MBean.
- */
- private static class DomainStarter extends MBeanServerProxy {
-
- public DomainStarter() {
- this(new HalfGrainLoader());
- }
-
- private final HalfGrainLoader loader;
- private DomainStarter(HalfGrainLoader loader) {
- super(loader);
- this.loader = loader;
- }
-
- public void setDomain(LazyStarterDomain domain) {
- loader.setDomain(domain);
- }
- }
-
- /**
- * A new LazyStarterDomain. When the domain monitored by this
- * MBean is accessed, this MBean will unregister itself and call
- * the abstract loadMBeans(MBeanServer) method.
- * Subclasses need only to implement loadMBeans().
- */
- public LazyStarterDomain() {
- this(new DomainStarter());
- }
-
- private LazyStarterDomain(DomainStarter starter) {
- super(starter);
- starter.setDomain(this);
- }
-
- // Contrarily to its LazyDomain superclass, this LazyDomain
- // doesn't wrapp another MBeanServer: it simply registers a bunch
- // of MBeans in its own MBeanServer.
- // Thus, there's no notifications to forward.
- //
- @Override
- public void addMBeanServerNotificationListener(
- NotificationListener listener, NotificationFilter filter) {
- // nothing to do.
- }
-
- // Contrarily to its LazyDomain superclass, this LazyDomain
- // doesn't wrapp another MBeanServer: it simply registers a bunch
- // of MBeans in its own MBeanServer.
- // Thus, there's no notifications to forward.
- //
- @Override
- public void removeMBeanServerNotificationListener(
- NotificationListener listener) throws ListenerNotFoundException {
- // nothing to do
- }
-
- // If this domain is registered, it contains no MBean.
- // If it is not registered, then it no longer contain any MBean.
- // The MBeanCount is thus always 0.
- @Override
- public Integer getMBeanCount() {
- return 0;
- }
-
- /**
- * Called when the domain is first accessed.
- * {@code server} is the server in which this MBean was registered.
- * A subclass must override this method in order to register
- * the MBeans that should be contained in domain.
- *
- * @param server the server in which to load the MBeans.
- * @param domain the domain in which the MBeans should be registered.
- */
- protected abstract void loadMBeans(MBeanServer server, String domain);
-
-
- }
-
- private static MBeanServerNotification pop(
- BlockingQueue<Notification> queue,
- String type,
- ObjectName mbean,
- String test)
- throws InterruptedException {
- final Notification n = queue.poll(1, TimeUnit.SECONDS);
- if (!(n instanceof MBeanServerNotification))
- fail(test+"expected MBeanServerNotification, got "+n);
- final MBeanServerNotification msn = (MBeanServerNotification)n;
- if (!type.equals(msn.getType()))
- fail(test+"expected "+type+", got "+msn.getType());
- if (!mbean.apply(msn.getMBeanName()))
- fail(test+"expected "+mbean+", got "+msn.getMBeanName());
- System.out.println(test+" got: "+msn);
- return msn;
- }
- private static MBeanServerNotification popADD(
- BlockingQueue<Notification> queue,
- ObjectName mbean,
- String test)
- throws InterruptedException {
- return pop(queue, MBeanServerNotification.REGISTRATION_NOTIFICATION,
- mbean, test);
- }
-
- private static MBeanServerNotification popREM(
- BlockingQueue<Notification> queue,
- ObjectName mbean,
- String test)
- throws InterruptedException {
- return pop(queue, MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
- mbean, test);
- }
-
-
- private static void fail(String msg) {
- raise(new RuntimeException(msg));
- }
-
- private static void fail(String msg, Throwable cause) {
- raise(new RuntimeException(msg,cause));
- }
-
- private static void raise(RuntimeException x) {
- lastException = x;
- exceptionCount++;
- throw x;
- }
-
- private static volatile Exception lastException = null;
- private static volatile int exceptionCount = 0;
-
- // ZZZ need to add a test case with several LazyDomains, and
- // need to test that nothing is loaded until the lazy domains
- // are accessed...
- //
-
- private static void registerWombats(MBeanServer server, String domain,
- int count) {
- try {
- for (int i=0;i<count;i++) {
- final ObjectName name =
- new ObjectName(domain+":type=Wombat,name=wombat#"+i);
- server.createMBean("Wombat", name);
- }
- } catch (RuntimeException x) {
- throw x;
- } catch(Exception x) {
- throw new RuntimeException(x.toString(),x);
- }
- }
-
- public static void checkSize(String test, MBeanServer server, int size) {
- System.out.println("We have now "+server.getMBeanCount()+
- " MBeans in "+Arrays.toString(server.getDomains()));
- if (server.getMBeanCount() != size)
- fail(test+"Expected "+size+
- " MBeans, found " + server.getMBeanCount());
- }
-
- private static MBeanServer newMBeanServer() {
- return MBeanServerFactory.newMBeanServer();
- }
-
- public static void lazyTest() throws Exception {
- final String test = "lazyTest: ";
- System.out.println("" +
- "\nThis test checks that it is possible to perform lazy loading" +
- "\nof MBeans in a given domain by using a JMXDomain subclass" +
- "\nfor that domain.");
-
- System.out.println(test + " START");
-
- // The "global" MBeanServer...
- final MBeanServer server = newMBeanServer();
-
- // An MBeanServer proxy which makes it possible to `lazy load'
- // the platform MBeanServer domains inside the global MBeanServer.
- //
- final MBeanServerProxy platform =
- new MBeanServerProxy(new MBeanServerLoader() {
-
- public MBeanServer loadMBeanServer() {
- return ManagementFactory.getPlatformMBeanServer();
- }
- });
-
-
- // The list of domain from the platform MBeanServer that will be
- // lazily loaded in the global MBeanServer
- //
- final String[] platformDomains = {
- "java.lang", "com.sun.management",
- "java.util.logging", "java.nio"
- };
-
- // We create a second MBeanServer, in which we will store some
- // custom MBeans. We will use this server to perform lazy loading
- // of two domains: custom.awomb and custom.bwomb.
- //
- // We use an MBeanServerBuilder here so that the MBeans registered
- // in our custom domain see all the MBeans in the global MBeanServer.
- // We do this by saying that the 'outer' MBeanServer is our global
- // servers. This means that the MBeans registered in the global
- // MBeanServer will see the MBeans from custom.awomb and custom.bwomb,
- // and the MBeans from custom.awomb and custom.bwomb will also see
- // the MBeans from the global MBeanServer, including those from
- // the platform domains.
- //
- final MBeanServerBuilder builder = new MBeanServerBuilder();
- final MBeanServerDelegate delegate = builder.newMBeanServerDelegate();
- final MBeanServer custom = builder.newMBeanServer("custom",
- server, delegate);
-
- // Number of MBean that we will put in each of the custom domain.
- //
- final int customCount = 10;
-
- // We use one MBeanServer proxy for each of the custom domains.
- // This makes it possible to load custom.awomb independently of
- // custom.bwomb.
- //
- // Here, the logic of the loader is to register MBeans in the loaded
- // domain as soon as the domain is loaded.
- //
- final MBeanServerProxy customa =
- new MBeanServerProxy(new MBeanServerLoader() {
- // A loader to register awomb MBeans in the custom MBeanServer.
- public MBeanServer loadMBeanServer() {
- registerWombats(custom, "custom.awomb", customCount);
- return custom;
- }
- });
- final MBeanServerProxy customb =
- new MBeanServerProxy(new MBeanServerLoader() {
- // A loader to register bwomb MBeans in the custom MBeanServer.
- public MBeanServer loadMBeanServer() {
- registerWombats(custom, "custom.bwomb", customCount);
- return custom;
- }
- });
-
- // A notification queue.
- final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue<Notification>(100);
-
- // A listener that puts notifs in the queue.
- final NotificationListener l = new NotificationListener() {
-
- public void handleNotification(Notification notification,
- Object handback) {
- try {
- if (!queue.offer(notification, 5, TimeUnit.SECONDS)) {
- throw new RuntimeException("timeout exceeded");
- }
- } catch (Exception x) {
- fail(test + "failed to handle notif", x);
- }
- }
- };
-
- // Create a LazyDomain for each of the platform domain.
- // All platform domain share the same MBeanServer proxy, which means
- // that loading one domain will also load all the others.
- //
- Map<String,LazyDomain> domainsMap = new HashMap<String,LazyDomain>();
- for (String dom : platformDomains) {
- domainsMap.put(dom, new LazyDomain(platform));
- }
- domainsMap.put("custom.awomb", new LazyDomain(customa));
- domainsMap.put("custom.bwomb", new LazyDomain(customb));
-
- for (Map.Entry<String,LazyDomain> e : domainsMap.entrySet()) {
- server.registerMBean(e.getValue(),
- JMXDomain.getDomainObjectName(e.getKey()));
- }
-
- // check that lazy MBeans are not there...
- checkSize(test,server,domainsMap.size()+1);
-
- System.out.println(test+" registering listener with delegate.");
- server.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, l,
- null, null);
-
- // check that lazy MBeans are not there...
- checkSize(test,server,domainsMap.size()+1);
-
- // force loading of custom.awomb.
- final ObjectName awombat = new ObjectName(
- "custom.awomb:type=Wombat,name=wombat#"+customCount/2);
- if (!server.isRegistered(awombat))
- fail(test+"Expected "+awombat+" to be reggistered!");
-
- final int oldCount = domainsMap.size()+1+customCount;
- checkSize(test,server,oldCount);
-
- if (queue.peek() != null)
- fail(test+"Received unexpected notifications: "+queue);
-
-
- System.out.println(test+"creating a proxy for ClassLoadingMXBean.");
- final ClassLoadingMXBean cl =
- JMX.newMXBeanProxy(server,
- new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME),
- ClassLoadingMXBean.class);
-
- checkSize(test,server,oldCount);
-
- System.out.println(test+"Loaded classes: "+cl.getLoadedClassCount());
-
- final int newCount = server.getMBeanCount();
- if (newCount < oldCount+6)
- fail(test+"Expected at least "+(oldCount+6)+
- " MBeans. Found "+newCount);
-
- final ObjectName jwombat = new ObjectName("java.lang:type=Wombat");
- server.createMBean("Wombat", jwombat);
- System.out.println(test+"Created "+jwombat);
- checkSize(test,server,newCount+1);
-
- popADD(queue, jwombat, test);
- if (queue.peek() != null)
- fail(test+"Received unexpected notifications: "+queue);
-
-
- int platcount = 0;
- for (String dom : platformDomains) {
- final Set<ObjectName> found =
- server.queryNames(new ObjectName(dom+":*"),null);
- final int jcount = found.size();
- System.out.println(test+"Found "+jcount+" MBeans in "+dom+
- ": "+found);
- checkSize(test,server,newCount+1);
- platcount += (jcount-1);
- }
- checkSize(test,server,oldCount+platcount);
-
- final ObjectName owombat = new ObjectName("custom:type=Wombat");
- server.createMBean("Wombat", owombat);
- System.out.println(test+"Created "+owombat);
- checkSize(test,server,newCount+2);
- popADD(queue, owombat, test);
- if (queue.peek() != null)
- fail(test+"Received unexpected notifications: "+queue);
-
- final Set<ObjectName> jwombatView = (Set<ObjectName>)
- server.invoke(jwombat, "listMatching", new Object[] {null},
- new String[] {ObjectName.class.getName()});
- System.out.println(test+jwombat+" sees: "+jwombatView);
- checkSize(test, server, newCount+2);
- if (jwombatView.size() != (platcount+1))
- fail(test+jwombat+" sees "+jwombatView.size()+" MBeans - should" +
- " have seen "+(platcount+1));
-
- final Set<ObjectName> platformMBeans =
- ManagementFactory.getPlatformMBeanServer().
- queryNames(null, null);
- if (!platformMBeans.equals(jwombatView))
- fail(test+jwombat+" should have seen "+platformMBeans);
-
- // check that awombat triggers loading of bwombats
- final Set<ObjectName> awombatView = (Set<ObjectName>)
- server.invoke(awombat, "listMatching", new Object[] {null},
- new String[] {ObjectName.class.getName()});
- System.out.println(test+awombat+" sees: "+awombatView);
- final int totalCount = newCount+2+customCount;
- checkSize(test, server, totalCount);
- if (awombatView.size() != totalCount)
- fail(test+jwombat+" sees "+jwombatView.size()+" MBeans - should" +
- " have seen "+totalCount);
-
- final Set<ObjectName> allMBeans = server.
- queryNames(null, null);
- if (!allMBeans.equals(awombatView))
- fail(test+awombat+" should have seen "+allMBeans);
-
- System.out.println(test + " PASSED");
-
- }
-
-
- public static void lazyStarterTest() throws Exception {
- final String test = "lazyStarterTest: ";
- System.out.println("" +
- "\nThis test checks that it is possible to perform lazy loading" +
- "\nof MBeans in a given domain by using a transient JMXDomain" +
- "\nsubclass for that domain. ");
-
- System.out.println(test + " START");
-
- // The "global" MBeanServer...
- final MBeanServer platform =
- ManagementFactory.getPlatformMBeanServer();
-
- // A notification queue.
- final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue<Notification>(100);
-
- // A listener that puts notifs in the queue.
- final NotificationListener l = new NotificationListener() {
-
- public void handleNotification(Notification notification,
- Object handback) {
- try {
- if (!queue.offer(notification, 5, TimeUnit.SECONDS)) {
- throw new RuntimeException("timeout exceeded");
- }
- } catch (Exception x) {
- fail(test + "failed to handle notif", x);
- }
- }
- };
-
- System.out.println(test+" registering listener with delegate.");
- platform.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, l,
- null, null);
-
- final String ld1 = "lazy1";
- final String ld2 = "lazy2";
- final int wCount = 5;
- final LazyStarterDomain lazy1 = new LazyStarterDomain() {
- @Override
- protected void loadMBeans(MBeanServer server, String domain) {
- registerWombats(server, ld1, wCount);
- }
- };
- final LazyStarterDomain lazy2 = new LazyStarterDomain() {
- @Override
- protected void loadMBeans(MBeanServer server, String domain) {
- registerWombats(server, ld2, wCount);
- }
- };
- final ObjectName lo1 = JMXDomain.getDomainObjectName(ld1);
- final ObjectName lo2 = JMXDomain.getDomainObjectName(ld2);
-
- final int initial = platform.getMBeanCount();
-
- platform.registerMBean(lazy1, lo1);
- System.out.println(test+"registered "+lo1);
- checkSize(test, platform, initial+1);
- popADD(queue, lo1, test);
-
- platform.registerMBean(lazy2, lo2);
- System.out.println(test+"registered "+lo2);
- checkSize(test, platform, initial+2);
- popADD(queue, lo2, test);
-
-
- final ObjectName awombat = new ObjectName(
- ld1+":type=Wombat,name=wombat#"+wCount/2);
- if (!platform.isRegistered(awombat))
- fail(test+"Expected "+awombat+" to be reggistered!");
- checkSize(test,platform,initial+wCount+1);
- popREM(queue, lo1, test);
- final ObjectName pat1 =
- new ObjectName(ld1+":type=Wombat,name=wombat#*");
- for (int i=0;i<wCount;i++) {
- popADD(queue,pat1,test);
- }
- System.out.println(test+"Found: "+
- platform.queryNames(pat1,null));
- checkSize(test,platform,initial+wCount+1);
-
- final Set<ObjectName> all = platform.queryNames(null, null);
- popREM(queue, lo2, test);
- System.out.println(test+"Now found: "+all);
- checkSize(test,platform,initial+wCount+wCount);
- final ObjectName pat2 =
- new ObjectName(ld2+":type=Wombat,name=wombat#*");
- for (int i=0;i<wCount;i++) {
- popADD(queue,pat2,test);
- }
-
- System.out.println(test+"check concurrent modification " +
- "of the DomainDispatcher.");
- System.out.println(test+"This will fail if the DomainDispatcher" +
- " doesn't allow concurrent modifications.");
- final HashMap<String,LazyStarterDomain> testConcurrent =
- new HashMap<String,LazyStarterDomain>();
- for (int i=0;i<(100/wCount);i++) {
- final String ld = "concurrent.lazy"+i;
- final LazyStarterDomain lazy = new LazyStarterDomain() {
- @Override
- protected void loadMBeans(MBeanServer server, String domain) {
- registerWombats(server, ld, wCount-1);
- }
- };
- testConcurrent.put(ld, lazy);
- final ObjectName lo = JMXDomain.getDomainObjectName(ld);
- platform.registerMBean(lazy, lo);
- popADD(queue, lo, test);
- }
-
- System.out.println(test+"Big autoload: "+
- platform.queryNames(null,null));
- System.out.println(test+"Big after load: "+
- platform.queryNames(null,null));
- if (!platform.queryNames(JMXDomain.getDomainObjectName("*"), null).
- isEmpty()) {
- fail(test+" some domains are still here: "+
- platform.queryNames(
- JMXDomain.getDomainObjectName("*"), null));
- }
- queue.clear();
- System.out.println(test+"PASSED: The DomainDispatcher appears to be " +
- "resilient to concurrent modifications.");
- }
-
- public static void main(String... args) throws Exception {
-
- lazyTest();
- lazyStarterTest();
-
- if (lastException != null)
- throw lastException;
- }
-}
--- a/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +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.
- *
- * 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.
- */
-/*
- * @test LeadingSeparatorsTest.java
- * @summary Test that the semantics of a leading // in ObjectName is respected.
- * @author Daniel Fuchs
- * @bug 5072476 6768935
- * @run clean LeadingSeparatorsTest Wombat WombatMBean
- * @compile -XDignore.symbol.file=true LeadingSeparatorsTest.java
- * @run build LeadingSeparatorsTest Wombat WombatMBean
- * @run main LeadingSeparatorsTest
- */
-
-import java.lang.management.ManagementFactory;
-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;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXRemoteNamespace;
-import javax.management.namespace.JMXNamespace;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * Class LeadingSeparatorsTest
- * @author Sun Microsystems, 2005 - All rights reserved.
- */
-public class LeadingSeparatorsTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(LeadingSeparatorsTest.class.getName());
-
- /** Creates a new instance of NullObjectNameTest */
- public LeadingSeparatorsTest() {
- }
-
- public static interface MyWombatMBean extends WombatMBean {
- public Set<ObjectName> untrue(ObjectName pat) throws Exception;
- }
- public static class MyWombat
- extends Wombat implements MyWombatMBean {
- public MyWombat() throws NotCompliantMBeanException {
- super(MyWombatMBean.class);
- }
-
- public Set<ObjectName> untrue(ObjectName pat) throws Exception {
- final Set<ObjectName> res=listMatching(pat.withDomain("*"));
- final Set<ObjectName> untrue = new HashSet<ObjectName>();
- for (ObjectName a:res) {
- untrue.add(a.withDomain(pat.getDomain()+"//"+a.getDomain()));
- }
- return untrue;
- }
- }
-
- static String failure=null;
-
- public static void testRegister() throws Exception {
- final MBeanServer top = ManagementFactory.getPlatformMBeanServer();
- final MBeanServer sub = MBeanServerFactory.createMBeanServer();
- final JMXServiceURL url = new JMXServiceURL("rmi",null,0);
- final JMXConnectorServer srv =
- JMXConnectorServerFactory.newJMXConnectorServer(url,null,sub);
- srv.start();
-
- try {
-
- // Create a namespace rmi// that points to 'sub' and flows through
- // a JMXRemoteNamespace connected to 'srv'
- // The namespace rmi// will accept createMBean, but not registerMBean.
- //
- final JMXRemoteNamespace rmiHandler = JMXRemoteNamespace.
- newJMXRemoteNamespace(srv.getAddress(),null);
- top.registerMBean(rmiHandler,
- JMXNamespaces.getNamespaceObjectName("rmi"));
- top.invoke(JMXNamespaces.getNamespaceObjectName("rmi"),
- "connect", null, null);
-
- // Create a namespace direct// that points to 'sub' and flows
- // through a direct reference to 'sub'.
- // The namespace direct// will accept createMBean, and registerMBean.
- //
- final JMXNamespace directHandler = new JMXNamespace(sub);
- top.registerMBean(directHandler,
- JMXNamespaces.getNamespaceObjectName("direct"));
-
- final ObjectName n1 = new ObjectName("//direct//w:type=Wombat");
- final ObjectName n2 = new ObjectName("direct//w:type=Wombat");
- final ObjectName n3 = new ObjectName("//rmi//w:type=Wombat");
- final ObjectName n4 = new ObjectName("rmi//w:type=Wombat");
-
- // 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, 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"));
- 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"));
- 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<ObjectName> res = (Set<ObjectName>)
- top.invoke(n4, "listMatching",
- // remove rmi// from rmi//*:*
- JMXNamespaces.deepReplaceHeadNamespace(
- new Object[] {ObjectName.WILDCARD.withDomain("rmi//*")},
- "rmi", ""), new String[] {ObjectName.class.getName()});
-
- // add rmi// prefix to all names in res.
- final Set<ObjectName> res1 =
- JMXNamespaces.deepReplaceHeadNamespace(res, "", "rmi");
- System.out.println("got: "+res1);
-
- // compute expected result
- final Set<ObjectName> res2 = sub.queryNames(null,null);
- final Set<ObjectName> res3 = new HashSet<ObjectName>();
- for (ObjectName o:res2) {
- res3.add(o.withDomain("rmi//"+o.getDomain()));
- }
- System.out.println("expected: "+res3);
- assertEquals(res1, res3);
-
- // invoke "untrue(//niark//niark:*)"
- // should return a set were all ObjectNames begin with
- // //niark//niark//
- //
- final Set<ObjectName> res4 = (Set<ObjectName>)
- top.invoke(n4, "untrue",
- // remove niark//niark : should remove nothing since
- // our ObjectName begins with a leading //
- JMXNamespaces.deepReplaceHeadNamespace(
- new Object[] {
- ObjectName.WILDCARD.withDomain("//niark//niark")},
- "niark//niark", ""),
- new String[] {ObjectName.class.getName()});
- System.out.println("got: "+res4);
-
- // add rmi// should add nothing since the returned names have a
- // leading //
- //
- final Set<ObjectName> res5 =
- JMXNamespaces.deepReplaceHeadNamespace(res4, "", "rmi");
- System.out.println("got#2: "+res5);
-
- // compute expected result
- final Set<ObjectName> res6 = new HashSet<ObjectName>();
- for (ObjectName o:res2) {
- res6.add(o.withDomain("//niark//niark//"+o.getDomain()));
- }
- System.out.println("expected: "+res6);
-
- // both res4 and res5 should be equals to the expected result.
- assertEquals(res4, res6);
- assertEquals(res5, res6);
-
- } finally {
- srv.stop();
- }
-
- if (failure != null)
- throw new Exception(failure);
-
-
- }
- private static void assertEquals(Object x, Object y) {
- if (!equal(x, y))
- failed("expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-
- public static void main(String[] args) throws Exception {
- testRegister();
- }
-}
--- a/jdk/test/javax/management/namespace/MXBeanRefTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +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.
- *
- * 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.
- */
-/*
- * @test MXBeanRefTest.java
- * @bug 5072476
- * @summary Test that MXBean proxy references work correctly in the presence
- * of namespaces.
- * @author Eamonn Mcmanus
- */
-
-/**
- * The idea is that we will create a hierarchy like this:
- * a//
- * X
- * b//
- * Y
- * Z
- * and we will use MXBean references so we have links like this:
- * a//
- * X----+
- * b// |
- * /
- * Y
- * \
- * /
- * Z
- * In other words, X.getY() will return a proxy for Y, which the MXBean
- * framework will map to b//Y. A proxy for a//X should then map this
- * into a proxy for a//b//Y. That's easy. But then if we call getZ()
- * on this proxy, the MXBean framework will return just Z, and the proxy
- * must map that into a proxy for a//b//Z.
- */
-
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.UndeclaredThrowableException;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.openmbean.OpenDataException;
-
-public class MXBeanRefTest {
-
- public static interface ZMXBean {
- public void success();
- }
- public static class ZImpl implements ZMXBean {
- public void success() {}
- }
-
- public static interface YMXBean {
- public ZMXBean getZ();
- public void setZ(ZMXBean z);
- }
- public static class YImpl implements YMXBean {
- private ZMXBean z;
-
- public YImpl(ZMXBean z) {
- this.z = z;
- }
-
- public ZMXBean getZ() {
- return z;
- }
-
- public void setZ(ZMXBean z) {
- this.z = z;
- }
- }
-
- public static interface XMXBean {
- public YMXBean getY();
- }
- public static class XImpl implements XMXBean {
- private final YMXBean yProxy;
-
- public XImpl(YMXBean yProxy) {
- this.yProxy = yProxy;
- }
-
- public YMXBean getY() {
- return yProxy;
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-
- // Set up namespace hierarchy a//b//
- MBeanServer ambs = MBeanServerFactory.newMBeanServer();
- MBeanServer bmbs = MBeanServerFactory.newMBeanServer();
- JMXNamespace bHandler = new JMXNamespace(bmbs);
- ObjectName bHandlerName = JMXNamespaces.getNamespaceObjectName("b");
- System.out.println(bHandlerName);
- ambs.registerMBean(bHandler, bHandlerName);
- JMXNamespace aHandler = new JMXNamespace(ambs);
- ObjectName aHandlerName = JMXNamespaces.getNamespaceObjectName("a");
- mbs.registerMBean(aHandler, aHandlerName);
-
- ZMXBean z = new ZImpl();
- ObjectName zName = new ObjectName("foo:type=Z");
- bmbs.registerMBean(z, zName);
-
- YMXBean y = new YImpl(z);
- ObjectName yName = new ObjectName("foo:type=Y");
- bmbs.registerMBean(y, yName);
-
- ObjectName yNameInA = new ObjectName("b//" + yName);
- System.out.println("MBeanInfo for Y as seen from a//:");
- System.out.println(ambs.getMBeanInfo(yNameInA));
- YMXBean yProxyInA = JMX.newMXBeanProxy(ambs, yNameInA, YMXBean.class);
- XMXBean x = new XImpl(yProxyInA);
- ObjectName xName = new ObjectName("foo:type=X");
- ambs.registerMBean(x, xName);
-
- ObjectName xNameFromTop = new ObjectName("a//" + xName);
- XMXBean xProxy = JMX.newMXBeanProxy(mbs, xNameFromTop, XMXBean.class);
- System.out.println("Name of X Proxy: " + proxyName(xProxy));
- YMXBean yProxy = xProxy.getY();
- System.out.println("Name of Y Proxy: " + proxyName(yProxy));
- ZMXBean zProxy = yProxy.getZ();
- System.out.println("Name of Z Proxy: " + proxyName(zProxy));
-
- System.out.println("Operation through Z proxy...");
- zProxy.success();
-
- System.out.println("Changing Y's ref to Z...");
- yProxy.setZ(zProxy);
- zProxy = yProxy.getZ();
- System.out.println("Name of Z Proxy now: " + proxyName(zProxy));
- System.out.println("Operation through Z proxy again...");
- zProxy.success();
-
- System.out.println("Changing Y's ref to a bogus one...");
- ZMXBean zProxyBad = JMX.newMXBeanProxy(mbs, zName, ZMXBean.class);
- try {
- yProxy.setZ(zProxyBad);
- } catch (UndeclaredThrowableException e) {
- Throwable cause = e.getCause();
- if (cause instanceof OpenDataException) {
- System.out.println("...correctly got UndeclaredThrowableException");
- System.out.println("...wrapping: " + cause);
- } else
- throw new Exception("FAILED: wrong exception: " + cause);
- }
-
- System.out.println("Test passed");
- }
-
- private static ObjectName proxyName(Object proxy) {
- InvocationHandler ih = Proxy.getInvocationHandler(proxy);
- MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler) ih;
- return mbsih.getObjectName();
- }
-}
--- a/jdk/test/javax/management/namespace/NamespaceController.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,405 +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.
- */
-
-import com.sun.jmx.namespace.ObjectNameRouter;
-import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-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.ReflectionException;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXRemoteNamespaceMBean;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * The {@code NamespaceController} MBean makes it possible to easily
- * create mount points ({@linkplain JMXNamespace JMXNamespaces}) in an
- * {@code MBeanServer}.
- * There is at most one instance of NamespaceController in an
- * MBeanServer - which can be created using the {@link #createInstance
- * createInstance} method. The {@code NamespaceController} MBean will
- * make it possible to remotely create name spaces by mounting remote
- * MBeanServers into the MBeanServer in which it was registered.
- */
-// This API was originally in the draft of javax/management/namespaces
-// but we decided to retire it. Rather than removing all the associated
-// tests I have moved the API to the test hierarchy - so it is now used as
-// an additional (though somewhat complex) test case...
-//
-public class NamespaceController implements NamespaceControllerMBean,
- NotificationEmitter, MBeanRegistration {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(NamespaceController.class.getName());
-
- private static long seqNumber=0;
-
- private final NotificationBroadcasterSupport broadcaster =
- new NotificationBroadcasterSupport();
-
- private volatile MBeanServer mbeanServer = null;
-
- private volatile ObjectName objectName = null;
-
- //was: NamespaceController.class.getPackage().getName()
- public static final String NAMESPACE_CONTROLLER_DOMAIN = "jmx.ns";
-
- /**
- * Creates a new NamespaceController.
- * Using {@link #createInstance} should be preferred.
- **/
- public NamespaceController() {
- this(null);
- }
-
- public NamespaceController(MBeanServer mbeanServer) {
- this.mbeanServer = mbeanServer;
- }
-
- /*
- * MBeanNotification support
- * You shouldn't update these methods
- */
- public final void addNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback) {
- broadcaster.addNotificationListener(listener, filter, handback);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return new MBeanNotificationInfo[] {
- };
- }
-
- public final void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(listener);
- }
-
- public final void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter, Object handback)
- throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(listener, filter, handback);
- }
-
- public static synchronized long getNextSeqNumber() {
- return seqNumber++;
- }
-
- protected final void sendNotification(Notification n) {
- if (n.getSequenceNumber()<=0)
- n.setSequenceNumber(getNextSeqNumber());
- if (n.getSource()==null)
- n.setSource(objectName);
- broadcaster.sendNotification(n);
- }
-
- /**
- * The ObjectName with which this MBean was registered.
- * <p>Unless changed by subclasses, this is
- * {@code
- * "javax.management.namespace:type="+this.getClass().getSimpleName()}.
- * @return this MBean's ObjectName, or null if this MBean was never
- * registered.
- **/
- public final ObjectName getObjectName() {
- return objectName;
- }
-
- /**
- * The MBeanServer served by this NamespaceController.
- * @return the MBeanServer served by this NamespaceController.
- **/
- public final MBeanServer getMBeanServer() {
- return mbeanServer;
- }
-
- /**
- * Allows the MBean to perform any operations it needs before being
- * registered in the MBean server. If the name of the MBean is not
- * specified, the MBean can provide a name for its registration. If
- * any exception is raised, the MBean will not be registered in the
- * MBean server. Subclasses which override {@code preRegister}
- * must call {@code super.preRegister(name,server)};
- * @param server The MBean server in which the MBean will be registered.
- * @param name The object name of the MBean.
- * The name must be either {@code null} - or equal to that
- * described by {@link #getObjectName}.
- * @return The name under which the MBean is to be registered.
- * This will be the name described by {@link #getObjectName}.
- * @throws MalformedObjectNameException if the supplied name does not
- * meet expected requirements.
- */
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws MalformedObjectNameException {
- objectName = name;
- final ObjectName single =
- ObjectName.getInstance(NAMESPACE_CONTROLLER_DOMAIN+
- ":type="+this.getClass().getSimpleName());
- if (name!=null && !single.equals(name))
- throw new MalformedObjectNameException(name.toString());
- if (mbeanServer == null) mbeanServer = server;
- return single;
- }
-
- /**
- * Allows the MBean to perform any operations needed after having
- * been registered in the MBean server or after the registration has
- * failed.
- * @param registrationDone Indicates whether or not the MBean has been
- * successfully registered in the MBean server. The value false means
- * that the registration has failed.
- */
- public void postRegister(Boolean registrationDone) {
- //TODO postRegister implementation;
- }
-
- /**
- * Allows the MBean to perform any operations it needs before being
- * unregistered by the MBean server.
- * @throws Exception This exception will be caught by the MBean server and
- * re-thrown as an MBeanRegistrationException.
- */
- public void preDeregister() throws Exception {
- //TODO preDeregister implementation;
- }
-
- /**
- * Allows the MBean to perform any operations needed after having been
- * unregistered in the MBean server.
- */
- public void postDeregister() {
- //TODO postDeregister implementation;
- }
-
- public String mount(JMXServiceURL url,
- String targetPath,
- Map<String,Object> optionsMap)
- throws IOException {
- return mount(url, targetPath, "", optionsMap);
- }
-
- // see NamespaceControllerMBean
- public String mount(JMXServiceURL url,
- String targetPath,
- String sourcePath,
- Map<String,Object> optionsMap)
- throws IOException {
-
- // TODO: handle description.
- final String dirName =
- JMXNamespaces.normalizeNamespaceName(targetPath);
-
- try {
- final ObjectInstance moi =
- JMXRemoteTargetNamespace.createNamespace(mbeanServer,
- dirName,url,optionsMap,
- JMXNamespaces.normalizeNamespaceName(sourcePath)
- );
- final ObjectName nsMBean = moi.getObjectName();
- try {
- mbeanServer.invoke(nsMBean, "connect", null,null);
- } catch (Throwable t) {
- mbeanServer.unregisterMBean(nsMBean);
- throw t;
- }
- return getMountPointID(nsMBean);
- } catch (InstanceAlreadyExistsException x) {
- throw new IllegalArgumentException(targetPath,x);
- } catch (IOException x) {
- throw x;
- } catch (Throwable x) {
- if (x instanceof Error) throw (Error)x;
- Throwable cause = x.getCause();
- if (cause instanceof IOException)
- throw ((IOException)cause);
- if (cause == null) cause = x;
-
- final IOException io =
- new IOException("connect failed: "+cause);
- io.initCause(cause);
- throw io;
- }
- }
-
- private String getMountPointID(ObjectName dirName) {
- return dirName.toString();
- }
-
- private ObjectName getHandlerName(String mountPointID) {
- try {
- final ObjectName tryit = ObjectName.getInstance(mountPointID);
- final ObjectName formatted =
- JMXNamespaces.getNamespaceObjectName(tryit.getDomain());
- if (!formatted.equals(tryit))
- throw new IllegalArgumentException(mountPointID+
- ": invalid mountPointID");
- return formatted;
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(mountPointID,x);
- }
- }
-
- public boolean unmount(String mountPointID)
- throws IOException {
- final ObjectName dirName = getHandlerName(mountPointID);
- if (!mbeanServer.isRegistered(dirName))
- throw new IllegalArgumentException(mountPointID+
- ": no such name space");
- final JMXRemoteNamespaceMBean mbean =
- JMX.newMBeanProxy(mbeanServer,dirName,
- JMXRemoteNamespaceMBean.class);
- try {
- mbean.close();
- } catch (IOException io) {
- LOG.fine("Failed to close properly - ignoring exception: "+io);
- LOG.log(Level.FINEST,
- "Failed to close properly - ignoring exception",io);
- } finally {
- try {
- mbeanServer.unregisterMBean(dirName);
- } catch (InstanceNotFoundException x) {
- throw new IllegalArgumentException(mountPointID+
- ": no such name space", x);
- } catch (MBeanRegistrationException x) {
- final IOException io =
- new IOException(mountPointID +": failed to unmount");
- io.initCause(x);
- throw io;
- }
- }
- return true;
- }
-
- public boolean ismounted(String targetPath) {
- return mbeanServer.isRegistered(JMXNamespaces.getNamespaceObjectName(targetPath));
- }
-
- public ObjectName getHandlerNameFor(String targetPath) {
- return JMXNamespaces.getNamespaceObjectName(targetPath);
- }
-
- public String[] findNamespaces() {
- return findNamespaces(null,null,0);
- }
-
-
- private ObjectName getDirPattern(String from) {
- try {
- if (from == null)
- return ObjectName.getInstance(ALL_NAMESPACES);
- final String namespace =
- ObjectNameRouter.normalizeNamespacePath(from,false,true,false);
- if (namespace.equals(""))
- return ObjectName.getInstance(ALL_NAMESPACES);
- if (JMXNamespaces.getNamespaceObjectName(namespace).isDomainPattern())
- throw new IllegalArgumentException(from);
- return ObjectName.getInstance(namespace+NAMESPACE_SEPARATOR+ALL_NAMESPACES);
- } catch (MalformedObjectNameException x) {
- throw new IllegalArgumentException(from,x);
- }
- }
-
- public String[] findNamespaces(String from, String regex, int depth) {
- if (depth < 0) return new String[0];
- final Set<String> res = new TreeSet<String>();
- final ObjectName all = getDirPattern(from);
- Set<ObjectName> names = mbeanServer.queryNames(all,null);
- for (ObjectName dirName : names) {
- final String dir = dirName.getDomain();
- if (regex == null || dir.matches(regex))
- res.add(dir);
- if (depth > 0)
- res.addAll(Arrays.asList(findNamespaces(dir,regex,depth-1)));
- }
- return res.toArray(new String[res.size()]);
- }
-
- /**
- * Creates a {@link NamespaceController} MBean in the provided
- * {@link MBeanServerConnection}.
- * <p>The name of the MBean is that returned by {@link #preRegister}
- * as described by {@link #getObjectName}.
- * @throws IOException if an {@code IOException} is raised when invoking
- * the provided connection.
- * @throws InstanceAlreadyExistsException if an MBean was already
- * registered with the NamespaceController's name.
- * @throws MBeanRegistrationException if thrown by {@link
- * MBeanServerConnection#createMBean(java.lang.String,javax.management.ObjectName)
- * server.createMBean}
- * @throws MBeanException if thrown by {@link
- * MBeanServerConnection#createMBean(java.lang.String,javax.management.ObjectName)
- * server.createMBean}
- * @return the {@link ObjectInstance}, as returned by {@link
- * MBeanServerConnection#createMBean(java.lang.String,javax.management.ObjectName)
- * server.createMBean}
- **/
- public static ObjectInstance createInstance(MBeanServerConnection server)
- throws IOException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException {
- try {
- final ObjectInstance instance =
- server.createMBean(NamespaceController.class.getName(), null);
- return instance;
- } catch (NotCompliantMBeanException ex) {
- throw new RuntimeException("unexpected exception: " + ex, ex);
- } catch (ReflectionException ex) {
- throw new RuntimeException("unexpected exception: " + ex, ex);
- }
- }
-
- private final static String ALL_NAMESPACES=
- "*"+NAMESPACE_SEPARATOR+":"+
- JMXNamespace.TYPE_ASSIGNMENT;
-
-}
--- a/jdk/test/javax/management/namespace/NamespaceControllerMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +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.
- */
-
-import java.io.IOException;
-import java.util.Map;
-
-import javax.management.ObjectName;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * The {@link NamespaceController} MBean makes it possible to easily
- * create mount points ({@link JMXNamespace JMXNamespaces}) in an
- * {@code MBeanServer}.
- */
-// This API was originally in the draft of javax/management/namespaces
-// but we decided to retire it. Rather than removing all the associated
-// tests I have moved the API to the test hierarchy - so it is now used as
-// an additional (though somewhat complex) test case...
-//
-public interface NamespaceControllerMBean {
- /**
- * Mount MBeans from the source path of the source URL into the specified
- * target path of the target.
- * @param url URL of the mounted source.
- * @param targetPath Target path in which MBeans will be mounted.
- * @param optionsMap connection map and options. See {@link
- * javax.management.namespace.JMXRemoteNamespace.Options
- * JMXRemoteNamespace.Options}
- * @throws IOException Connection with the source failed
- * @throws IllegalArgumentException Supplied parameters are
- * illegal, or combination of supplied parameters is illegal.
- * @return A mount point id.
- */
- public String mount(JMXServiceURL url,
- String targetPath,
- Map<String,Object> optionsMap)
- throws IOException, IllegalArgumentException;
-
- /**
- * Mount MBeans from the source path of the source URL into the specified
- * target path of the target.
- * @param url URL of the mounted source.
- * @param targetPath Target path in which MBeans will be mounted.
- * @param sourcePath source namespace path.
- * @param optionsMap connection map and options. See {@link
- * javax.management.namespace.JMXRemoteNamespace.Options
- * JMXRemoteNamespace.Options}
- * @throws IOException Connection with the source failed
- * @throws IllegalArgumentException Supplied parameters are
- * illegal, or combination of supplied parameters is illegal.
- * @return A mount point id.
- */
- public String mount(JMXServiceURL url,
- String targetPath,
- String sourcePath,
- Map<String,Object> optionsMap)
- throws IOException, IllegalArgumentException;
-
- /**
- * Unmount a previously mounted mount point.
- * @param mountPointId A mount point id, as previously returned
- * by mount.
- * @throws IllegalArgumentException Supplied parameters are
- * illegal, or combination of supplied parameters is illegal.
- * @throws IOException thrown if the mount point {@link JMXNamespace}
- * couldn't be unregistered.
- */
- public boolean unmount(String mountPointId)
- throws IOException, IllegalArgumentException;
-
- /**
- * Tells whether there already exists a {@link JMXNamespace} for
- * the given <var>targetPath</var>.
- * @param targetPath a target name space path.
- * @return true if a {@link JMXNamespace} is registered for that
- * name space path.
- **/
- public boolean ismounted(String targetPath);
-
- /**
- * Returns the handler name for the provided target name space
- * path. Can throw IllegalArgumentException if the provided
- * targetPath contains invalid characters (like e.g. ':').
- * @param targetPath A target name space path.
- * @return the handler name for the provided target name space
- * path.
- **/
- public ObjectName getHandlerNameFor(String targetPath);
-
- /**
- * Return a sorted array of locally mounted name spaces.
- * This is equivalent to calling {@link
- * #findNamespaces(java.lang.String,java.lang.String,int)
- * findNamespaces(null,null,0)};
- * @return a sorted array of locally mounted name spaces.
- **/
- public String[] findNamespaces();
-
- /**
- * Return a sorted array of mounted name spaces, starting at
- * <var>from</var> (if non null), and recursively searching up to
- * provided <var>depth</var>.
- * @param from A name spaces from which to start the search. If null,
- * will start searching from the MBeanServer root.
- * If not null, all returned names will start with <var>from//</var>.
- * @param regex A regular expression that the returned names must match.
- * If null - no matching is performed and all found names are
- * returned. If not null, then all returned names satisfy
- * {@link String#matches name.matches(regex)};
- * @param depth the maximum number of levels that the search algorithm
- * will cross. 0 includes only top level name spaces, 1 top level
- * and first level children etc... <var>depth</var> is evaluated
- * with regard to where the search starts - if a non null
- * <var>from</var> parameter is provided - then {@code depth=0}
- * corresponds to all name spaces found right below
- * <var>from//</var>.
- * @return A sorted array of name spaces matching the provided criteria.
- * All returned names end with "//".
- **/
- public String[] findNamespaces(String from, String regex, int depth);
-}
--- a/jdk/test/javax/management/namespace/NamespaceCreationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +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.
- *
- * 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.
- */
-/*
- *
- * @test NamespaceCreationTest.java
- * @summary General JMXNamespace test.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean NamespaceCreationTest Wombat WombatMBean
- * @run build NamespaceCreationTest Wombat WombatMBean
- * @run main NamespaceCreationTest
- */
-
-
-import java.util.Collections;
-import java.util.Map;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.RuntimeMBeanException;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-
-/**
- * Test simple creation/registration of namespace.
- *
- */
-public class NamespaceCreationTest {
- private static Map<String,Object> emptyEnvMap() {
- return Collections.emptyMap();
- }
-
-
- public static class LocalNamespace extends JMXNamespace {
-
- public LocalNamespace() {
- super(MBeanServerFactory.newMBeanServer());
- }
-
- }
-
- private static MBeanServer newMBeanServer() {
- return MBeanServerFactory.newMBeanServer();
- }
-
- public static interface ThingMBean {}
- public static class Thing implements ThingMBean, MBeanRegistration {
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- if (name == null) return new ObjectName(":type=Thing");
- else return name;
- }
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
- public void postDeregister() {
- }
- }
-
- /**
- * Test that it is possible to create a dummy MBean with a null
- * ObjectName - this is just a sanity check - as there are already
- * other JMX tests that check that.
- *
- * @throws java.lang.Exception
- */
- public static void testCreateWithNull() throws Exception {
- final MBeanServer server = newMBeanServer();
- final ObjectInstance oi = server.registerMBean(new Thing(),null);
- server.unregisterMBean(oi.getObjectName());
- System.out.println("testCreateWithNull PASSED");
- }
-
- /**
- * Check that we can register a JMXNamespace MBean, using its standard
- * ObjectName.
- * @throws java.lang.Exception
- */
- public static void testGoodObjectName() throws Exception {
- MBeanServer server = newMBeanServer();
- final ObjectName name =
- JMXNamespaces.getNamespaceObjectName("gloups");
- final ObjectInstance oi =
- server.registerMBean(new LocalNamespace(),name);
- System.out.println("Succesfully registered namespace: "+name);
- try {
- if (! name.equals(oi.getObjectName()))
- throw new RuntimeException("testGoodObjectName: TEST failed: " +
- "namespace registered as: "+
- oi.getObjectName()+" expected: "+name);
- } finally {
- server.unregisterMBean(oi.getObjectName());
- }
- System.out.println("Succesfully unregistered namespace: "+name);
- System.out.println("testGoodObjectName PASSED");
- }
-
- /**
- * Check that we cannot register a JMXNamespace MBean, if we don't use
- * its standard ObjectName.
- * @throws java.lang.Exception
- */
- public static void testBadObjectName() throws Exception {
- MBeanServer server = newMBeanServer();
- Throwable exp = null;
- final ObjectName name = new ObjectName("d:k=v");
- try {
- server.registerMBean(new LocalNamespace(),name);
- System.out.println("testBadObjectName: " +
- "Error: MBean registered, no exception thrown.");
- } catch(RuntimeMBeanException x) {
- exp = x.getCause();
- } catch(Exception x) {
- throw new RuntimeException("testBadObjectName: TEST failed: " +
- "expected RuntimeMBeanException - got "+
- x);
- }
- if (exp == null) server.unregisterMBean(name);
- if (exp == null)
- throw new RuntimeException("testBadObjectName: TEST failed: " +
- "expected IllegalArgumentException - got none");
- if (!(exp instanceof IllegalArgumentException))
- throw new RuntimeException("testBadObjectName: TEST failed: " +
- "expected IllegalArgumentException - got "+
- exp.toString(),exp);
- System.out.println("Got expected exception: "+exp);
- System.out.println("testBadObjectName PASSED");
- }
-
- /**
- * Check that we cannot register a Wombat MBean in a namespace that does
- * not exists.
- *
- * @throws java.lang.Exception
- */
- public static void testBadNamespace() throws Exception {
- MBeanServer server = newMBeanServer();
- Throwable exp = null;
- final ObjectName name = new ObjectName("glips//d:k=v");
-
- try {
- server.registerMBean(new Wombat(),name);
- System.out.println("testBadNamespace: " +
- "Error: MBean registered, no exception thrown.");
- } catch(MBeanRegistrationException x) {
- exp = x.getCause();
- } catch(Exception x) {
- throw new RuntimeException("testBadNamespace: TEST failed: " +
- "expected MBeanRegistrationException - got "+
- x);
- }
- if (exp == null) server.unregisterMBean(name);
- if (exp == null)
- throw new RuntimeException("testBadNamespace: TEST failed: " +
- "expected IllegalArgumentException - got none");
- if (!(exp instanceof IllegalArgumentException))
- throw new RuntimeException("testBadNamespace: TEST failed: " +
- "expected IllegalArgumentException - got "+
- exp.toString(),exp);
- System.out.println("Got expected exception: "+exp);
- System.out.println("testBadNamespace PASSED");
- }
-
- /**
- * Check that we cannot register a Wombat MBean with a domain name
- * that ends with //. This is reserved for namespaces.
- *
- * @throws java.lang.Exception
- */
- public static void testBadDomain() throws Exception {
- MBeanServer server = newMBeanServer();
- Throwable exp = null;
- final ObjectName name = new ObjectName("glups//:k=v");
-
- try {
- server.registerMBean(new Wombat(),name);
- System.out.println("testBadDomain: Error: MBean registered, no exception thrown.");
- } catch(RuntimeMBeanException x) {
- exp = x.getCause();
- } catch(Exception x) {
- throw new RuntimeException("testBadDomain: TEST failed: " +
- "expected RuntimeMBeanException - got "+
- x);
- }
- if (exp == null) server.unregisterMBean(name);
- if (exp == null)
- throw new RuntimeException("testBadDomain: TEST failed: " +
- "expected IllegalArgumentException - got none");
- if (!(exp instanceof IllegalArgumentException))
- throw new RuntimeException("testBadDomain: TEST failed: " +
- "expected IllegalArgumentException - got "+
- exp.toString(),exp);
- System.out.println("Got expected exception: "+exp);
- System.out.println("testBadDomain PASSED");
- }
-
- /**
- * Check that we cannot register a Wombat MBean as if it were a
- * JMXNamespace. Only JMXNamespace MBeans can have JMX Namespace names.
- * @throws java.lang.Exception
- */
- public static void testBadClassName() throws Exception {
- MBeanServer server = newMBeanServer();
- Throwable exp = null;
- final ObjectName name =
- JMXNamespaces.getNamespaceObjectName("glops");
- try {
- server.registerMBean(new Wombat(),name);
- System.out.println("testBadClassName: " +
- "Error: MBean registered, no exception thrown.");
- } catch(RuntimeMBeanException x) {
- exp = x.getCause();
- } catch(Exception x) {
- throw new RuntimeException("testBadClassName: TEST failed: " +
- "expected RuntimeMBeanException - got "+
- x);
- }
- if (exp == null) server.unregisterMBean(name);
- if (exp == null)
- throw new RuntimeException("testBadClassName: TEST failed: " +
- "expected IllegalArgumentException - got none");
- if (!(exp instanceof IllegalArgumentException))
- throw new RuntimeException("testBadClassName: TEST failed: " +
- "expected IllegalArgumentException - got "+
- exp.toString(),exp);
- System.out.println("Got expected exception: "+exp);
- System.out.println("testBadClassName PASSED");
- }
-
- public static void main(String... args) throws Exception {
- testCreateWithNull();
- testGoodObjectName();
- testBadObjectName();
- testBadNamespace();
- testBadDomain();
- testBadClassName();
- }
-}
--- a/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test NamespaceNotificationsTest.java 1.12
- * @summary General Namespace & Notifications test.
- * @bug 5072476
- * @author Daniel Fuchs
- * @run clean NamespaceNotificationsTest
- * Wombat WombatMBean JMXRemoteTargetNamespace
- * NamespaceController NamespaceControllerMBean
- * @compile -XDignore.symbol.file=true NamespaceNotificationsTest.java
- * Wombat.java WombatMBean.java JMXRemoteTargetNamespace.java
- * NamespaceController.java NamespaceControllerMBean.java
- * @run main NamespaceNotificationsTest
- */
-import com.sun.jmx.remote.util.EventClientConnection;
-import java.lang.management.ManagementFactory;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerFactory;
-import javax.management.MBeanServerNotification;
-import javax.management.MalformedObjectNameException;
-import javax.management.Notification;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.loading.MLet;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.remote.JMXAddressable;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- *
- * @author Sun Microsystems, Inc.
- */
-public class NamespaceNotificationsTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(NamespaceNotificationsTest.class.getName());
-
- /** Creates a new instance of NamespaceNotificationsTest */
- public NamespaceNotificationsTest() {
- }
-
-
- public static JMXServiceURL export(MBeanServer server)
- throws Exception {
- final JMXServiceURL in = new JMXServiceURL("rmi",null,0);
- final JMXConnectorServer cs =
- JMXConnectorServerFactory.newJMXConnectorServer(in,null,null);
- final ObjectName csname = ObjectName.
- getInstance(cs.getClass().getPackage().getName()+
- ":type="+cs.getClass().getSimpleName());
- server.registerMBean(cs,csname);
- cs.start();
- return cs.getAddress();
- }
-
- public static class Counter {
- int count;
- public synchronized int count() {
- count++;
- notifyAll();
- return count;
- }
- public synchronized int peek() {
- return count;
- }
- public synchronized int waitfor(int max, long timeout)
- throws InterruptedException {
- final long start = System.currentTimeMillis();
- while (count < max && timeout > 0) {
- final long rest = timeout -
- (System.currentTimeMillis() - start);
- if (rest <= 0) break;
- wait(rest);
- }
- return count;
- }
- }
-
- public static class CounterListener
- implements NotificationListener {
- final private Counter counter;
- public CounterListener(Counter counter) {
- this.counter = counter;
- }
- public void handleNotification(Notification notification,
- Object handback) {
- System.out.println("Received notif from " + handback +
- ":\n\t" + notification);
- if (!notification.getSource().equals(handback)) {
- System.err.println("OhOh... Unexpected source: \n\t"+
- notification.getSource()+"\n\twas expecting:\n\t"+
- handback);
- }
- counter.count();
- }
- }
-
- public static void simpleTest(String[] args) {
- try {
- final MBeanServer server1 =
- ManagementFactory.getPlatformMBeanServer();
- final JMXServiceURL url1 = export(server1);
-
- final MBeanServer server2 =
- MBeanServerFactory.createMBeanServer("server2");
- final JMXServiceURL url2 = export(server2);
-
- final MBeanServer server3 =
- MBeanServerFactory.createMBeanServer("server3");
- final JMXServiceURL url3 = export(server3);
-
- final ObjectInstance ncinst =
- NamespaceController.createInstance(server1);
-
- final NamespaceControllerMBean nc =
- JMX.newMBeanProxy(server1,ncinst.getObjectName(),
- NamespaceControllerMBean.class);
-
- final Map<String,Object> options = new HashMap<String,Object>();
- options.put(JMXRemoteTargetNamespace.CREATE_EVENT_CLIENT,"true");
-
- final String mount1 =
- nc.mount(url1,"server1",options);
- final String mount2 = nc.mount(url2,"server1//server2",
- options);
- final String mount3 = nc.mount(url3,
- "server1//server2//server3",
- options);
- final String mount13 = nc.mount(
- url1,
- "server3",
- "server2//server3",
- options);
- final String mount21 = nc.mount(url1,"server2//server1",
- options);
- final String mount31 = nc.mount(
- url1,
- "server3//server1",
- "server1",
- options);
- final String mount32 = nc.mount(
- url1,
- "server3//server2",
- "server2",
- options);
-
-
- final ObjectName deep =
- new ObjectName("server1//server2//server3//bush:type=Wombat,name=kanga");
- server1.createMBean(Wombat.class.getName(),deep);
-
- System.err.println("There's a wombat in the bush!");
-
- final Counter counter = new Counter();
-
- final NotificationListener listener =
- new CounterListener(counter);
-
- final JMXConnector jc = JMXConnectorFactory.connect(url1);
- final MBeanServerConnection aconn =
- EventClientConnection.getEventConnectionFor(
- jc.getMBeanServerConnection(),null);
- aconn.addNotificationListener(deep,listener,null,deep);
-
-
- MBeanServerConnection iconn =
- JMXNamespaces.narrowToNamespace(aconn, "server1//server1");
- MBeanServerConnection bconn =
- JMXNamespaces.narrowToNamespace(aconn, "server3");
- final ObjectName shallow =
- new ObjectName("bush:"+
- deep.getKeyPropertyListString());
- final WombatMBean proxy =
- JMX.newMBeanProxy(EventClientConnection.getEventConnectionFor(
- bconn,null),shallow,WombatMBean.class,true);
-
- ((NotificationEmitter)proxy).
- addNotificationListener(listener,null,shallow);
- proxy.setCaption("I am a new Wombat!");
- System.err.println("New caption: "+proxy.getCaption());
- final int rcvcount = counter.waitfor(2,3000);
- if (rcvcount != 2)
- throw new RuntimeException("simpleTest failed: "+
- "received count is " +rcvcount);
-
- System.err.println("simpleTest passed: got "+rcvcount+
- " notifs");
-
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new RuntimeException("simpleTest failed: " + x,x);
- }
- }
-
- public static class LocalNamespace extends
- JMXNamespace {
- LocalNamespace() {
- super(MBeanServerFactory.newMBeanServer());
- }
-
- }
-
- public static class ContextObject<K,V> {
- public final K name;
- public final V object;
- public ContextObject(K name, V object) {
- this.name = name;
- this.object = object;
- }
- private Object[] data() {
- return new Object[] {name,object};
- }
-
- @Override
- public boolean equals(Object x) {
- if (x instanceof ContextObject)
- return Arrays.deepEquals(data(),((ContextObject<?,?>)x).data());
- return false;
- }
- @Override
- public int hashCode() {
- return Arrays.deepHashCode(data());
- }
- }
-
- private static <K,V> ContextObject<K,V> context(K k, V v) {
- return new ContextObject<K,V>(k,v);
- }
-
- private static ObjectName name(String name) {
- try {
- return new ObjectName(name);
- } catch(MalformedObjectNameException x) {
- throw new IllegalArgumentException(name,x);
- }
- }
-
- public static void simpleTest2() {
- try {
- System.out.println("\nsimpleTest2: STARTING\n");
- final LocalNamespace foo = new LocalNamespace();
- final LocalNamespace joe = new LocalNamespace();
- final LocalNamespace bar = new LocalNamespace();
- final MBeanServer server = MBeanServerFactory.newMBeanServer();
-
- server.registerMBean(foo,JMXNamespaces.getNamespaceObjectName("foo"));
- server.registerMBean(joe,JMXNamespaces.getNamespaceObjectName("foo//joe"));
- server.registerMBean(bar,JMXNamespaces.getNamespaceObjectName("foo//bar"));
- final BlockingQueue<ContextObject<String,MBeanServerNotification>> queue =
- new ArrayBlockingQueue<ContextObject<String,MBeanServerNotification>>(20);
-
- final NotificationListener listener = new NotificationListener() {
- public void handleNotification(Notification n, Object handback) {
- if (!(n instanceof MBeanServerNotification)) {
- System.err.println("Error: expected MBeanServerNotification");
- return;
- }
- final MBeanServerNotification mbsn =
- (MBeanServerNotification) n;
-
- // We will pass the namespace name in the handback.
- //
- final String namespace = (String) handback;
- System.out.println("Received " + mbsn.getType() +
- " for MBean " + mbsn.getMBeanName() +
- " from name space " + namespace);
- try {
- queue.offer(context(namespace,mbsn),500,TimeUnit.MILLISECONDS);
- } catch (Exception x) {
- System.err.println("Failed to enqueue received notif: "+mbsn);
- x.printStackTrace();
- }
- }
- };
-
- server.addNotificationListener(JMXNamespaces.insertPath("foo//joe",
- MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//joe");
- server.addNotificationListener(JMXNamespaces.insertPath("foo//bar",
- MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//bar");
- server.createMBean(MLet.class.getName(),
- name("foo//joe//domain:type=MLet"));
- checkQueue(queue,"foo//joe",
- MBeanServerNotification.REGISTRATION_NOTIFICATION);
- server.createMBean(MLet.class.getName(),
- name("foo//bar//domain:type=MLet"));
- checkQueue(queue,"foo//bar",
- MBeanServerNotification.REGISTRATION_NOTIFICATION);
- server.unregisterMBean(
- name("foo//joe//domain:type=MLet"));
- checkQueue(queue,"foo//joe",
- MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
- server.unregisterMBean(
- name("foo//bar//domain:type=MLet"));
- checkQueue(queue,"foo//bar",
- MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
- } catch (RuntimeException x) {
- System.err.println("FAILED: "+x);
- throw x;
- } catch(Exception x) {
- System.err.println("FAILED: "+x);
- throw new RuntimeException("Unexpected exception: "+x,x);
- }
- }
-
-
- private static void checkQueue(
- BlockingQueue<ContextObject<String,MBeanServerNotification>> q,
- String path, String type) {
- try {
- final ContextObject<String,MBeanServerNotification> ctxt =
- q.poll(500,TimeUnit.MILLISECONDS);
- if (ctxt == null)
- throw new RuntimeException("Timeout expired: expected notif from "+
- path +", type="+type);
- if (!ctxt.name.equals(path))
- throw new RuntimeException("expected notif from "+
- path +", got "+ctxt.name);
- if (!ctxt.object.getType().equals(type))
- throw new RuntimeException(ctxt.name+": expected type="+
- type +", got "+ctxt.object.getType());
- if (!ctxt.object.getType().equals(type))
- throw new RuntimeException(ctxt.name+": expected type="+
- type +", got "+ctxt.object.getType());
- if (!ctxt.object.getMBeanName().equals(name("domain:type=MLet")))
- throw new RuntimeException(ctxt.name+": expected MBean=domain:type=MLet"+
- ", got "+ctxt.object.getMBeanName());
- } catch(InterruptedException x) {
- throw new RuntimeException("unexpected interruption: "+x,x);
- }
- }
-
- public static void main(String[] args) {
- simpleTest(args);
- simpleTest2();
- }
-
-}
--- a/jdk/test/javax/management/namespace/NullDomainObjectNameTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +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.
- *
- * 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.
- */
-/*
- * @test NullDomainObjectNameTest.java
- * @summary Test that null domains are correctly handled in namespaces.
- * @author Daniel Fuchs
- * @run clean NullDomainObjectNameTest Wombat WombatMBean
- * @compile -XDignore.symbol.file=true NullDomainObjectNameTest.java
- * @run build NullDomainObjectNameTest Wombat WombatMBean
- * @run main NullDomainObjectNameTest
- */
-
-import com.sun.jmx.namespace.RoutingServerProxy;
-import java.lang.management.ManagementFactory;
-import java.util.Arrays;
-import java.util.logging.Logger;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-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;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * Class NullDomainObjectNameTest
- * @author Sun Microsystems, 2005 - All rights reserved.
- */
-public class NullDomainObjectNameTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(NullDomainObjectNameTest.class.getName());
-
- /** Creates a new instance of NullDomainObjectNameTest */
- public NullDomainObjectNameTest() {
- }
-
- public static class MyWombat
- extends Wombat {
- public MyWombat() throws NotCompliantMBeanException {
- super();
- }
- @Override
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
-
- if (name == null)
- name = new ObjectName(":type=Wombat");
-
- return super.preRegister(server, name);
- }
-
- }
-
- static String failure=null;
-
- public static void testRegister() throws Exception {
- final MBeanServer top = ManagementFactory.getPlatformMBeanServer();
- final MBeanServer sub = MBeanServerFactory.createMBeanServer();
- final JMXServiceURL url = new JMXServiceURL("rmi",null,0);
- final JMXConnectorServer srv =
- JMXConnectorServerFactory.newJMXConnectorServer(url,null,sub);
- srv.start();
-
- try {
-
- // Create a namespace rmi// that points to 'sub' and flows through
- // a JMXRemoteNamespace connected to 'srv'
- // The namespace rmi// will accept createMBean, but not registerMBean.
- //
- final JMXRemoteNamespace rmiHandler = JMXRemoteNamespace.
- newJMXRemoteNamespace(srv.getAddress(),
- null);
- top.registerMBean(rmiHandler,JMXNamespaces.getNamespaceObjectName("rmi"));
- top.invoke(JMXNamespaces.getNamespaceObjectName("rmi"),
- "connect", null, null);
-
- // Create a namespace direct// that points to 'sub' and flows
- // through a direct reference to 'sub'.
- // The namespace direct// will accept createMBean, and registerMBean.
- //
- final JMXNamespace directHandler = new JMXNamespace(sub);
- top.registerMBean(directHandler,
- JMXNamespaces.getNamespaceObjectName("direct"));
-
- // Now cd to each of the created namespace.
- //
- MBeanServer cdrmi = JMXNamespaces.narrowToNamespace(top,"rmi");
- MBeanServer cddirect = JMXNamespaces.narrowToNamespace(top,"direct");
- boolean ok = false;
-
- // Check that calling createMBean with a null domain works
- // for namespace rmi//
- //
- try {
- final ObjectInstance moi1 =
- cdrmi.createMBean(MyWombat.class.getName(),
- new ObjectName(":type=Wombat"));
- System.out.println(moi1.getObjectName().toString()+
- ": created through rmi//");
- assertEquals(moi1.getObjectName().getDomain(),
- cddirect.getDefaultDomain());
- cddirect.unregisterMBean(moi1.getObjectName());
- } catch (MBeanRegistrationException x) {
- System.out.println("Received unexpected exception: " + x);
- failed("Received unexpected exception: " + x);
- }
-
- // Check that calling refgisterMBean with a null domain works
- // for namespace direct//
- //
- try {
- final ObjectInstance moi2 =
- cddirect.registerMBean(new MyWombat(),
- new ObjectName(":type=Wombat"));
- System.out.println(moi2.getObjectName().toString()+
- ": created through direct//");
- assertEquals(moi2.getObjectName().getDomain(),
- cdrmi.getDefaultDomain());
- cdrmi.unregisterMBean(moi2.getObjectName());
- } catch (MBeanRegistrationException x) {
- System.out.println("Received unexpected exception: " + x);
- failed("Received unexpected exception: " + x);
- }
-
- // Now artificially pretend that 'sub' is contained in a faked//
- // namespace.
- //
- RoutingServerProxy proxy =
- new RoutingServerProxy(sub, "", "faked", true);
-
- // These should fail because the ObjectName doesn't start
- // with "faked//"
- try {
- final ObjectInstance moi3 =
- proxy.registerMBean(new MyWombat(),
- new ObjectName(":type=Wombat"));
- System.out.println(moi3.getObjectName().toString()+
- ": created through faked//");
- failed("expected MBeanRegistrationException");
- } catch (MBeanRegistrationException x) {
- System.out.println("Received expected exception: " + x);
- if (!(x.getCause() instanceof IllegalArgumentException)) {
- System.err.println("Bad wrapped exception: "+ x.getCause());
- failed("expected IllegalArgumentException");
- }
- }
-
- // null should work with "faked//"
- final ObjectInstance moi3 =
- proxy.registerMBean(new MyWombat(),null);
- assertEquals(moi3.getObjectName().getDomain(),
- "faked//"+sub.getDefaultDomain());
-
- System.out.println(moi3.getObjectName().toString() +
- ": created through faked//");
-
- // Now check that null is correctly handled (accepted or rejected)
- // in queries for each of the above configs.
- //
- ObjectName wombat = moi3.getObjectName().withDomain(
- moi3.getObjectName().getDomain().substring("faked//".length()));
- ObjectInstance moi = new ObjectInstance(wombat,moi3.getClassName());
-
- System.out.println("Checking queryNames(" +
- "new ObjectName(\":*\"),null) with rmi//");
- assertEquals(cdrmi.queryNames(
- new ObjectName(":*"),null).contains(wombat),true);
- System.out.println("Checking queryNames(" +
- "new ObjectName(\":*\"),null) with direct//");
- assertEquals(cddirect.queryNames(
- new ObjectName(":*"),null).contains(wombat),true);
- System.out.println("Checking queryMBeans(" +
- "new ObjectName(\":*\"),null) with rmi//");
- assertEquals(cdrmi.queryMBeans(
- new ObjectName(":*"),null).contains(moi),true);
- System.out.println("Checking queryMBeans(" +
- "new ObjectName(\":*\"),null) with direct//");
- assertEquals(cddirect.queryMBeans(
- new ObjectName(":*"),null).contains(moi),true);
-
- // These should fail because the ObjectName doesn't start
- // with "faked//"
- try {
- System.out.println("Checking queryNames(" +
- "new ObjectName(\":*\"),null) with faked//");
- assertEquals(proxy.queryNames(
- new ObjectName(":*"),null).
- contains(moi3.getObjectName()),true);
- 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//"
- try {
- System.out.println("Checking queryMBeans(" +
- "new ObjectName(\":*\"),null) with faked//");
- assertEquals(proxy.queryMBeans(
- new ObjectName(":*"),null).contains(moi3),true);
- 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)");
- assertEquals(proxy.queryNames(new ObjectName("faked//*:*"),null).
- contains(moi3.getObjectName()),true);
-
- System.out.println("Checking queryMBeans(faked//*:*,null)");
- assertEquals(proxy.queryMBeans(new ObjectName("faked//*:*"),null).
- contains(moi3),true);
-
- proxy.unregisterMBean(moi3.getObjectName());
-
- // ADD NEW TESTS HERE ^^^
-
- } finally {
- srv.stop();
- }
-
- if (failure != null)
- throw new Exception(failure);
-
-
- }
- private static void assertEquals(Object x, Object y) {
- if (!equal(x, y))
- failed("expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-
- public static void main(String[] args) throws Exception {
- testRegister();
- }
-}
--- a/jdk/test/javax/management/namespace/NullObjectNameTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +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.
- *
- * 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.
- */
-/*
- * @test NullObjectNameTest.java
- * @summary Test that null ObjectName are correctly handled in namespaces.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean NullObjectNameTest Wombat WombatMBean
- * @compile -XDignore.symbol.file=true NullObjectNameTest.java
- * @run build NullObjectNameTest Wombat WombatMBean
- * @run main NullObjectNameTest
- */
-
-import com.sun.jmx.namespace.RoutingServerProxy;
-import java.lang.management.ManagementFactory;
-import java.util.Arrays;
-import java.util.logging.Logger;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-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;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * Class NullObjectNameTest
- * @author Sun Microsystems, 2005 - All rights reserved.
- */
-public class NullObjectNameTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(NullObjectNameTest.class.getName());
-
- /** Creates a new instance of NullObjectNameTest */
- public NullObjectNameTest() {
- }
-
- public static class MyWombat
- extends Wombat {
- public MyWombat() throws NotCompliantMBeanException {
- super();
- }
- @Override
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
-
- if (name == null)
- name = new ObjectName(":type=Wombat");
-
- return super.preRegister(server, name);
- }
-
- }
-
- static String failure=null;
-
- public static void testRegister() throws Exception {
- final MBeanServer top = ManagementFactory.getPlatformMBeanServer();
- final MBeanServer sub = MBeanServerFactory.createMBeanServer();
- final JMXServiceURL url = new JMXServiceURL("rmi",null,0);
- final JMXConnectorServer srv =
- JMXConnectorServerFactory.newJMXConnectorServer(url,null,sub);
- srv.start();
-
- try {
-
- // Create a namespace rmi// that points to 'sub' and flows through
- // a JMXRemoteNamespace connected to 'srv'
- // The namespace rmi// will accept createMBean, but not registerMBean.
- //
- final JMXRemoteNamespace rmiHandler = JMXRemoteNamespace.
- newJMXRemoteNamespace(srv.getAddress(),null);
- top.registerMBean(rmiHandler,JMXNamespaces.getNamespaceObjectName("rmi"));
- top.invoke(JMXNamespaces.getNamespaceObjectName("rmi"),
- "connect", null, null);
-
- // Create a namespace direct// that points to 'sub' and flows
- // through a direct reference to 'sub'.
- // The namespace direct// will accept createMBean, and registerMBean.
- //
- final JMXNamespace directHandler = new JMXNamespace(sub);
- top.registerMBean(directHandler,
- JMXNamespaces.getNamespaceObjectName("direct"));
-
- // Now cd to each of the created namespace.
- //
- MBeanServer cdrmi = JMXNamespaces.narrowToNamespace(top,"rmi");
- MBeanServer cddirect = JMXNamespaces.narrowToNamespace(top,"direct");
- boolean ok = false;
-
- // Check that calling createMBean with a null ObjectName fails
- // gracefully for namespace rmi// (we can't add rmi// to a null
- // ObjectName.
- //
- // TODO: do this test for all createMBean flavors!
- try {
- final ObjectInstance moi1 =
- cdrmi.createMBean(MyWombat.class.getName(),null);
- System.out.println(moi1.getObjectName().toString()+
- ": created through rmi//");
- cddirect.unregisterMBean(moi1.getObjectName());
- failed("expected MBeanRegistrationException");
- } catch (MBeanRegistrationException x) {
- System.out.println("Received expected exception: " + x);
- if (!(x.getCause() instanceof IllegalArgumentException)) {
- System.err.println("Bad wrapped exception: "+ x.getCause());
- failed("expected IllegalArgumentException");
- }
- }
-
- // Check that calling refgisterMBean with a null ObjectName fails
- // gracefully for namespace direct// (we can't add direct// to a null
- // ObjectName.
- //
- try {
- final ObjectInstance moi2 =
- cddirect.registerMBean(new MyWombat(), (ObjectName)null);
- System.out.println(moi2.getObjectName().toString()+
- ": created through direct//");
- cdrmi.unregisterMBean(moi2.getObjectName());
- failed("expected MBeanRegistrationException");
- } catch (MBeanRegistrationException x) {
- System.out.println("Received expected exception: " + x);
- if (!(x.getCause() instanceof IllegalArgumentException)) {
- System.err.println("Bad wrapped exception: "+ x.getCause());
- failed("expected IllegalArgumentException");
- }
- }
-
- // Now artificially pretend that 'sub' is contained in a faked//
- // namespace.
- // We should be able to use 'null' in registerMBean/createMBean in
- // this case.
- //
- RoutingServerProxy proxy =
- new RoutingServerProxy(sub, "", "faked", true);
- final ObjectInstance moi3 =
- proxy.registerMBean(new MyWombat(),null);
- System.out.println(moi3.getObjectName().toString()+
- ": created through faked//");
-
- // Now check that null is correctly handled (accepted or rejected)
- // in queries for each of the above configs.
- //
- ObjectName wombat = moi3.getObjectName().withDomain(
- moi3.getObjectName().getDomain().substring("faked//".length()));
- ObjectInstance moi = new ObjectInstance(wombat,moi3.getClassName());
-
- System.out.println("Checking queryNames(null,null) with rmi//");
- assertEquals(cdrmi.queryNames(null,null).contains(wombat),true);
- System.out.println("Checking queryNames(null,null) with direct//");
- assertEquals(cddirect.queryNames(null,null).contains(wombat),true);
- System.out.println("Checking queryMBeans(null,null) with rmi//");
- assertEquals(cdrmi.queryMBeans(null,null).contains(moi),true);
- System.out.println("Checking queryMBeans(null,null) with direct//");
- assertEquals(cddirect.queryMBeans(null,null).contains(moi),true);
-
- try {
- System.out.println("Checking queryNames(null,null) with faked//");
- assertEquals(proxy.queryNames(null,null).
- contains(moi3.getObjectName()),true);
- failed("queryNames(null,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(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 (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).
- contains(moi3.getObjectName()),true);
-
- System.out.println("Checking queryMBeans(faked//*:*,null)");
- assertEquals(proxy.queryMBeans(new ObjectName("faked//*:*"),null).
- contains(moi3),true);
-
- proxy.unregisterMBean(moi3.getObjectName());
-
- // ADD NEW TESTS HERE ^^^
-
- } finally {
- srv.stop();
- }
-
- if (failure != null)
- throw new Exception(failure);
-
-
- }
- private static void assertEquals(Object x, Object y) {
- if (!equal(x, y))
- failed("expected " + string(x) + "; got " + string(y));
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == y)
- return true;
- if (x == null || y == null)
- return false;
- if (x.getClass().isArray())
- return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
- return x.equals(y);
- }
-
- private static String string(Object x) {
- String s = Arrays.deepToString(new Object[] {x});
- return s.substring(1, s.length() - 1);
- }
-
-
- private static void failed(String why) {
- failure = why;
- new Throwable("FAILED: " + why).printStackTrace(System.out);
- }
-
- public static void main(String[] args) throws Exception {
- testRegister();
- }
-}
--- a/jdk/test/javax/management/namespace/QueryNamesTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,473 +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.
- *
- * 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.
- */
-/*
- *
- * @test QueryNamesTest.java 1.4
- * @summary Test how queryNames works with Namespaces.
- * @author Daniel Fuchs
- * @bug 5072476 6768935
- * @run clean QueryNamesTest Wombat WombatMBean
- * @run build QueryNamesTest Wombat WombatMBean
- * @run main QueryNamesTest
- */
-
-
-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;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.logging.Logger;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMException;
-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;
-
-/**
- * Class QueryNamesTest
- * @author Sun Microsystems, 2005 - All rights reserved.
- */
-public class QueryNamesTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(QueryNamesTest.class.getName());
-
- public static class LocalNamespace
- extends JMXNamespace {
-
- private static MBeanServer check(MBeanServer server) {
- if (server == null)
- throw new IllegalArgumentException("MBeanServer can't be null");
- return server;
- }
-
- public LocalNamespace() {
- this(MBeanServerFactory.createMBeanServer());
- }
-
- public LocalNamespace(MBeanServer server) {
- super(check(server));
- }
-
-
- public static String add(MBeanServerConnection server,
- String nspath)
- throws IOException, JMException {
- server.createMBean(LocalNamespace.class.getName(),
- JMXNamespaces.getNamespaceObjectName(nspath));
- return nspath;
- }
- }
-
- /** Creates a new instance of QueryNamesTest */
- public QueryNamesTest() {
- }
-
- private static String[] namespaces = {
- "greg", "greg//chichille", "greg//chichille//petard",
- "greg//alambic", "greg//alambic//canette",
- "greg//chichille/virgule", "greg//chichille/funeste",
- "greg//chichille/virgule//bidouble",
- "greg//chichille/virgule//bi/double",
- "fran", "fran//gast", "fran//gast//gaf",
- "fran//longtar", "fran//longtar//parcmetre"
- };
-
- private static void createNamespaces(MBeanServer server) throws Exception {
- final LinkedList<String> all = new LinkedList<String>();
- try {
- for (String ns : namespaces)
- all.addFirst(LocalNamespace.add(server,ns));
- } catch (Exception e) {
- removeNamespaces(server,all.toArray(new String[all.size()]));
- throw e;
- }
- }
-
- // Dummy test that checks that all JMXNamespaces are registered,
- // but are not returned by queryNames("*:*");
- //
- private static void checkRegistration(MBeanServer server)
- throws Exception {
- final Set<ObjectName> handlerNames = new HashSet<ObjectName>(namespaces.length);
- for (String ns : namespaces)
- handlerNames.add(JMXNamespaces.getNamespaceObjectName(ns));
- for (ObjectName nh : handlerNames) // check handler registration
- if (!server.isRegistered(nh))
- throw new InstanceNotFoundException("handler "+nh+
- " is not registered");
-
- // global: queryNames("*:*") from top level
- final Set<ObjectName> all1 = server.queryNames(null,null);
- final Set<ObjectName> all2 = server.queryNames(ObjectName.WILDCARD,null);
- if (!all1.equals(all2))
- throw new Exception("queryNames(*:*) != queryNames(null)");
- final Set<ObjectName> common = new HashSet<ObjectName>(all1);
- common.retainAll(handlerNames);
-
- final Set<ObjectName> ref = new HashSet<ObjectName>();
- for (String ns : namespaces) {
- if (!ns.contains(JMXNamespaces.NAMESPACE_SEPARATOR))
- ref.add(JMXNamespaces.getNamespaceObjectName(ns));
- }
- if (!common.equals(ref)) {
- throw new Exception("some handler names were not returned by " +
- "wildcard query - only returned: "+common+
- ", expected: "+ref);
- }
-
- // for each namespace: queryNames("<namespace>//*:*");
- for (String ns : namespaces) {
- final ObjectName pattern = new ObjectName(ns+
- JMXNamespaces.NAMESPACE_SEPARATOR+"*:*");
- final Set<ObjectName> all4 =
- server.queryNames(pattern,null);
- final Set<ObjectName> common4 = new HashSet<ObjectName>(all4);
- common4.retainAll(handlerNames);
-
- final Set<ObjectName> ref4 = new HashSet<ObjectName>();
- for (String ns2 : namespaces) {
- if (! ns2.startsWith(ns+JMXNamespaces.NAMESPACE_SEPARATOR))
- continue;
- if (!ns2.substring(ns.length()+
- JMXNamespaces.NAMESPACE_SEPARATOR.length()).
- contains(JMXNamespaces.NAMESPACE_SEPARATOR))
- ref4.add(JMXNamespaces.getNamespaceObjectName(ns2));
- }
- if (!common4.equals(ref4)) {
- throw new Exception("some handler names were not returned by " +
- "wildcard query on "+pattern+" - only returned: "+common4+
- ", expected: "+ref4);
- }
- }
- }
-
- // Make a Map<parent, direct children>
- private static Map<String,Set<String>> makeNsTree(String[] nslist) {
- final Map<String,Set<String>> nsTree =
- new LinkedHashMap<String,Set<String>>(nslist.length);
- for (String ns : nslist) {
- if (nsTree.get(ns) == null)
- nsTree.put(ns,new LinkedHashSet<String>());
- final String[] elts = ns.split(JMXNamespaces.NAMESPACE_SEPARATOR);
- int last = ns.lastIndexOf(JMXNamespaces.NAMESPACE_SEPARATOR);
- if (last<0) continue;
- while (last > 0 && ns.charAt(last-1) == '/') last--;
- final String parent = ns.substring(0,last);
- if (nsTree.get(parent) == null)
- nsTree.put(parent,new LinkedHashSet<String>());
- nsTree.get(parent).add(ns);
- }
- return nsTree;
- }
-
- private static class Rigolo {
- final static String[] ones = { "a", "e", "i", "o", "u", "y", "ai", "oo",
- "ae", "ey", "ay", "oy", "au", "ou", "eu", "oi", "ei", "ea"};
- final static String[] twos = { "b", "bz", "c", "cz", "ch",
- "ct", "ck", "cs", "d", "ds", "f", "g", "gh", "h", "j", "k", "l", "m",
- "n", "p", "ps", "q", "r", "s", "sh", "t", "v", "w", "x",
- "z"};
- final static String[] threes = {"rr","tt","pp","ss","dd","ff","ll", "mm", "nn",
- "zz", "cc", "bb"};
- final static String[] fours = {"x", "s", "ght", "cks", "rt", "rts", "ghts", "bs",
- "ts", "gg" };
- final static String[] fives = { "br", "bl", "cr", "cn", "cth", "dr",
- "fr", "fl", "cl", "chr", "gr", "gl", "kr", "kh", "pr", "pl", "ph",
- "rh", "sr", "tr", "vr"};
-
- private Random rg = new Random();
-
- private String next(String[] table) {
- return table[rg.nextInt(table.length)];
- }
-
- public String nextName(int max) {
- final Random rg = new Random();
- final int nl = 3 + rg.nextInt(max);
- boolean begin = rg.nextBoolean();
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < nl ; j++) {
- if (begin) {
- sb.append(next(ones));
- } else if (j > 0 && j < nl-1 && rg.nextInt(4)==0) {
- sb.append(next(threes));
- } else if (j < nl-1 && rg.nextInt(3)==0) {
- sb.append(next(fives));
- } else {
- sb.append(next(twos));
- }
- begin = !begin;
- }
- if (!begin && rg.nextInt(2)==0)
- sb.append(next(fours));
- return sb.toString();
- }
-
- private ObjectName getWombatName(String ns, String domain, String name)
- throws MalformedObjectNameException {
- String d = domain;
- if (ns != null && !ns.equals(""))
- d = ns + JMXNamespaces.NAMESPACE_SEPARATOR + domain;
- return new ObjectName(d+":type=Wombat,name="+name);
- }
-
- public Set<ObjectName> nextWombats(String ns)
- throws MalformedObjectNameException {
- final int dcount = 1 + rg.nextInt(5);
- final Set<ObjectName> wombats = new HashSet<ObjectName>();
- for (int i = 0; i < dcount ; i++) {
- final String d = nextName(7);
- final int ncount = 5 + rg.nextInt(20);
- for (int j = 0 ; j<ncount; j++) {
- final String n = nextName(5);
- wombats.add(getWombatName(ns,d,n));
- }
- }
- return wombats;
- }
- }
-
- public static void checkNsQuery(MBeanServer server)
- throws Exception {
- final Map<String,Set<String>> nsTree = makeNsTree(namespaces);
- final Random rg = new Random();
- final Rigolo rigolo = new Rigolo();
- for (String ns : namespaces) {
- final ObjectName name = JMXNamespaces.getNamespaceObjectName(ns);
- final String[] doms =
- (String[])server.getAttribute(name,"Domains");
- final Set<String> subs = new HashSet<String>();
- for (String d : doms) {
- if (d.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) {
- subs.add(ns+JMXNamespaces.NAMESPACE_SEPARATOR+d.substring(0,
- d.length()-JMXNamespaces.NAMESPACE_SEPARATOR.length()));
- }
- }
-
- final Set<String> expectNs = new HashSet<String>(nsTree.get(ns));
-
- if (! subs.containsAll(expectNs))
- throw new Exception("getDomains didn't return all namespaces: "+
- "returned="+subs+", expected="+expectNs);
- if (! expectNs.containsAll(subs))
- throw new Exception("getDomains returned additional namespaces: "+
- "returned="+subs+", expected="+expectNs);
-
- final Set<ObjectName> nsNames = server.queryNames(
- new ObjectName(ns+
- JMXNamespaces.NAMESPACE_SEPARATOR+"*"+
- JMXNamespaces.NAMESPACE_SEPARATOR+":*"),null);
-
- final Set<ObjectName> expect =
- new HashSet<ObjectName>(expectNs.size());
- for (String sub : expectNs) {
- expect.add(JMXNamespaces.getNamespaceObjectName(sub));
- }
-
- if (! nsNames.containsAll(expect))
- throw new Exception("queryNames didn't return all namespaces: "+
- "returned="+nsNames+", expected="+expect);
- if (! expect.containsAll(nsNames))
- throw new Exception("getDomains returned additional namespaces: "+
- "returned="+nsNames+", expected="+expect);
-
- }
- }
-
- private static void addWombats(MBeanServer server, Set<ObjectName> names)
- throws Exception {
- for (ObjectName on : names) {
- if (! server.isRegistered(on)) {
- server.createMBean(Wombat.class.getName(),on);
- System.out.println("A new wombat is born: "+on);
- }
- }
- }
-
- private static void addWombats(MBeanServer server,
- Map<String,Set<ObjectName>> wombats)
- throws Exception {
- for (String ns : wombats.keySet()) {
- addWombats(server,wombats.get(ns));
- }
- }
-
- private static Map<String,Set<ObjectName>> nameWombats()
- throws Exception {
- final Rigolo rigolo = new Rigolo();
- final Map<String,Set<ObjectName>> wombats =
- new HashMap<String,Set<ObjectName>>(namespaces.length);
-
- for (String ns : namespaces) {
- wombats.put(ns,rigolo.nextWombats(ns));
- }
- wombats.put("",rigolo.nextWombats(""));
- return wombats;
- }
-
- private static boolean removeWombats(MBeanServer server,
- Map<String,Set<ObjectName>> wombats) {
- boolean res = true;
- for (String ns : wombats.keySet()) {
- res = res && removeWombats(server,wombats.get(ns));
- }
- return res;
- }
-
- private static boolean removeWombats(MBeanServer server,
- Set<ObjectName> wombats) {
- boolean res = true;
- for (ObjectName on : wombats) {
- try {
- if (server.isRegistered(on))
- server.unregisterMBean(on);
- } catch (Exception x) {
- res = false;
- System.out.println("Failed to remove "+on+": "+x);
- }
- }
- return res;
- }
-
- private static void checkNsPattern(MBeanServer server) throws Exception {
- final List<String> list = new ArrayList<String>();
- for (String s : namespaces) {
- final String[] cmpnt = s.split("//");
- for (int i=0;i<cmpnt.length;i++) {
- final String[] clone = cmpnt.clone();
- if (clone[i].length() < 3) {
- clone[i] = "*";
- } else {
- clone[i] = "?"+cmpnt[i].substring(1, cmpnt[i].length()-2)+"*";
- }
- final StringBuilder sb = new StringBuilder();
- for (int j=0;j<cmpnt.length;j++) {
- sb.append(clone[j]).append("//");
- }
- list.add(sb.toString()+"*:*");
- }
- }
- for (String s : list) {
- final Set<ObjectName> res = new HashSet<ObjectName>();
-
- 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<ObjectInstance> res = new HashSet<ObjectInstance>();
-
- 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();
- Map<String,Set<ObjectName>> wombats = nameWombats();
- createNamespaces(server);
- try {
- addWombats(server,wombats);
- System.out.println("MBeans: " +server.getMBeanCount());
- System.out.println("Visible: " +server.queryNames(null,null).size());
- System.out.println("Domains: " +Arrays.asList(server.getDomains()));
- checkRegistration(server);
- checkNsQuery(server);
- checkNsPattern(server);
- } finally {
- boolean res = true;
- res = res && removeWombats(server, wombats);
- if (!res)
- throw new RuntimeException("failed to cleanup some namespaces");
- }
-
- }
-
- private static boolean removeNamespaces(MBeanServer server) {
- final List<String> l = Arrays.asList(namespaces);
- Collections.reverse(l);
- return removeNamespaces(server, l.toArray(new String[namespaces.length]));
- }
-
- private static boolean removeNamespaces(MBeanServer server, String[] t) {
- boolean success = true;
- for (String ns : t) {
- try {
- server.unregisterMBean(JMXNamespaces.getNamespaceObjectName(ns));
- } catch (Exception x) {
- System.out.println("failed to remove namespace: "+ ns);
- success = false;
- }
- }
- return success;
- }
-
-}
--- a/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,377 +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.
- *
- * 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.
- */
-/*
- *
- * @test RemoveNotificationListenerTest.java 1.8
- * @summary General RemoveNotificationListenerTest test.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean RemoveNotificationListenerTest JMXRemoteTargetNamespace
- * @compile -XDignore.symbol.file=true JMXRemoteTargetNamespace.java
- * @run build RemoveNotificationListenerTest JMXRemoteTargetNamespace
- * @run main/othervm RemoveNotificationListenerTest
- */
-
-import com.sun.jmx.remote.util.EventClientConnection;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-import javax.management.JMException;
-import javax.management.JMX;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXConnectorServerMBean;
-import javax.management.remote.JMXPrincipal;
-import javax.management.remote.JMXServiceURL;
-import javax.security.auth.Subject;
-
-/**
- * Class RemoveNotificationListenerTest
- */
-public class RemoveNotificationListenerTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(RemoveNotificationListenerTest.class.getName());
-
- /** Creates a new instance of RemoveNotificationListenerTest */
- public RemoveNotificationListenerTest() {
- }
-
- public static class SubjectAuthenticator implements JMXAuthenticator {
- final Set<Subject> authorized;
- public SubjectAuthenticator(Subject[] authorized) {
- this.authorized = new HashSet<Subject>(Arrays.asList(authorized));
- }
-
- public Subject authenticate(Object credentials) {
- if (authorized.contains(credentials))
- return (Subject)credentials;
- else
- throw new SecurityException("Subject not authorized: "+credentials);
- }
-
- }
-
- public static interface LongtarMBean {
- public void sendNotification(Object userData)
- throws IOException, JMException;
- }
- public static class Longtar extends NotificationBroadcasterSupport
- implements LongtarMBean {
- public Longtar() {
- super(new MBeanNotificationInfo[] {
- new MBeanNotificationInfo(new String[] {"papillon"},
- "pv","M'enfin???")
- });
- }
-
- public void sendNotification(Object userData)
- throws IOException, JMException {
- final Notification n =
- new Notification("papillon",this,nextseq(),"M'enfin???");
- n.setUserData(userData);
- System.out.println("Sending notification: "+userData);
- sendNotification(n);
- }
-
- private static synchronized long nextseq() {return ++seqnb;}
- private static volatile long seqnb=0;
- }
-
- private static final String NS = JMXNamespaces.NAMESPACE_SEPARATOR;
- private static final String CS = "jmx.rmi:type=JMXConnectorServer";
- private static final String BD = "longtar:type=Longtar";
-
- private static void createNamespace(MBeanServerConnection server,
- String namespace, Subject creator, boolean forwarding)
- throws Exception {
- final MBeanServer sub = MBeanServerFactory.createMBeanServer();
- final JMXServiceURL url = new JMXServiceURL("rmi",null,0);
- final Map<String,Object> smap = new HashMap<String,Object>();
- smap.put(JMXConnectorServer.AUTHENTICATOR,
- new SubjectAuthenticator(new Subject[] {creator}));
- final JMXConnectorServer rmi =
- JMXConnectorServerFactory.newJMXConnectorServer(url,smap,null);
- final ObjectName name = new ObjectName(CS);
- sub.registerMBean(rmi,name);
- rmi.start();
- final Map<String,Object> cmap = new HashMap<String,Object>();
- cmap.put(JMXConnector.CREDENTIALS,creator);
- final Map<String,Object> options = new HashMap<String,Object>(cmap);
- options.put(JMXRemoteTargetNamespace.CREATE_EVENT_CLIENT,"true");
- JMXRemoteTargetNamespace.createNamespace(server,
- namespace,
- rmi.getAddress(),
- options
- );
- server.invoke(JMXNamespaces.getNamespaceObjectName(namespace),
- "connect", null,null);
- }
- private static void closeNamespace(MBeanServerConnection server,
- String namespace) {
- try {
- final ObjectName hname =
- JMXNamespaces.getNamespaceObjectName(namespace);
- if (!server.isRegistered(hname))
- return;
- final ObjectName sname =
- new ObjectName(namespace+NS+CS);
- if (!server.isRegistered(sname))
- return;
- final JMXConnectorServerMBean cs =
- JMX.newMBeanProxy(server,sname,
- JMXConnectorServerMBean.class,true);
- try {
- cs.stop();
- } finally {
- server.unregisterMBean(hname);
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private static Subject newSubject(String[] principals) {
- final Set<Principal> ps = new HashSet<Principal>();
- for (String p:principals) ps.add(new JMXPrincipal(p));
- return new Subject(true,ps,Collections.emptySet(),Collections.emptySet());
- }
-
-
- public static void testSubject() throws Exception {
- final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- final String a = "a";
- final String b = a + NS + "b";
-
- final Subject s1 = newSubject(new String[] {"chichille"});
- final Subject s2 = newSubject(new String[] {"alambic"});
- final Subject s3 = newSubject(new String[] {"virgule"});
- final Subject s4 = newSubject(new String[] {"funeste"});
-
- final JMXServiceURL url = new JMXServiceURL("rmi",null,0);
- final Map<String,Object> smap = new HashMap<String,Object>();
- smap.put(JMXConnectorServer.AUTHENTICATOR,
- new SubjectAuthenticator(new Subject[] {s1}));
- final JMXConnectorServer rmi =
- JMXConnectorServerFactory.newJMXConnectorServer(url,smap,null);
- final ObjectName name = new ObjectName(CS);
- server.registerMBean(rmi,name);
- rmi.start();
-
- try {
-
- final Map<String,Object> map = new HashMap<String,Object>();
- map.put(JMXConnector.CREDENTIALS,s1);
- final JMXConnector c =
- JMXConnectorFactory.connect(rmi.getAddress(),map);
- final MBeanServerConnection mbsorig = c.getMBeanServerConnection();
-
- final MBeanServerConnection mbs =
- EventClientConnection.getEventConnectionFor(mbsorig,null);
-
- createNamespace(mbs,a,s2,true);
- createNamespace(mbs,b,s3,true);
-
- final ObjectName longtar = new ObjectName(b+NS+BD);
-
- mbs.createMBean(Longtar.class.getName(),longtar);
- final LongtarMBean proxy =
- JMX.newMBeanProxy(mbs,longtar,LongtarMBean.class,true);
-
-
- final BlockingQueue<Notification> bbq =
- new ArrayBlockingQueue<Notification>(10);
- final NotificationListener listener1 = new NotificationListener() {
- public void handleNotification(Notification notification,
- Object handback) {
- System.out.println(notification.getSequenceNumber()+": "+
- notification.getMessage());
- bbq.add(notification);
- }
- };
- final NotificationListener listener2 = new NotificationListener() {
- public void handleNotification(Notification notification,
- Object handback) {
- System.out.println(notification.getSequenceNumber()+": "+
- notification.getMessage());
- bbq.add(notification);
- }
- };
-
- final NotificationEmitter ubpdalfdla = (NotificationEmitter)proxy;
- try {
-
- // Add 1 NL, send 1 notif (1)
- ubpdalfdla.addNotificationListener(listener1,null,listener1);
- proxy.sendNotification(new Integer(1));
- // Thread.sleep(180000);
-
- // We should have 1 notif with userdata = 1
- final Notification n1 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n1.getUserData()).intValue() != 1)
- throw new Exception("Expected 1, got"+n1.getUserData());
-
- // remove NL, send 1 notif (2) => we shouldn't receive it
- ubpdalfdla.removeNotificationListener(listener1,null,listener1);
- proxy.sendNotification(new Integer(2));
-
- // add NL, send 1 notif (3)
- ubpdalfdla.addNotificationListener(listener1,null,listener1);
- proxy.sendNotification(new Integer(3));
-
- // we should receive only 1 notif (3)
- final Notification n3 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n3.getUserData()).intValue() != 3)
- throw new Exception("Expected 3, got"+n3.getUserData());
-
- // remove NL, send 1 notif (4) => we shouldn't receive it.
- ubpdalfdla.removeNotificationListener(listener1);
- proxy.sendNotification(new Integer(4));
-
- // add NL, send 1 notif (5).
- ubpdalfdla.addNotificationListener(listener1,null,listener1);
- proxy.sendNotification(new Integer(5));
-
- // next notif in queue should be (5)
- final Notification n5 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n5.getUserData()).intValue() != 5)
- throw new Exception("Expected 5, got"+n5.getUserData());
-
- // add 2 NL, send 1 notif (6)
- ubpdalfdla.addNotificationListener(listener2,null,listener2);
- ubpdalfdla.addNotificationListener(listener2,null,null);
- proxy.sendNotification(new Integer(6));
-
- // We have 3 NL, we should receive (6) 3 times....
- final Notification n61 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n61.getUserData()).intValue() != 6)
- throw new Exception("Expected 6 (#1), got"+n61.getUserData());
- final Notification n62 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n62.getUserData()).intValue() != 6)
- throw new Exception("Expected 6 (#2), got"+n62.getUserData());
- final Notification n63 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n63.getUserData()).intValue() != 6)
- throw new Exception("Expected 6 (#3), got"+n63.getUserData());
-
- // Remove 1 NL, send 1 notif (7)
- ubpdalfdla.removeNotificationListener(listener2,null,null);
- proxy.sendNotification(new Integer(7));
-
- // next notifs in queue should be (7), twice...
- final Notification n71 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n71.getUserData()).intValue() != 7)
- throw new Exception("Expected 7 (#1), got"+n71.getUserData());
- final Notification n72 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n72.getUserData()).intValue() != 7)
- throw new Exception("Expected 7 (#2), got"+n72.getUserData());
-
- // Add 1 NL, send 1 notif (8)
- ubpdalfdla.addNotificationListener(listener2,null,null);
- proxy.sendNotification(new Integer(8));
-
- // Next notifs in queue should be (8), 3 times.
- final Notification n81 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n81.getUserData()).intValue() != 8)
- throw new Exception("Expected 8 (#1), got"+n81.getUserData());
- final Notification n82 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n82.getUserData()).intValue() != 8)
- throw new Exception("Expected 8 (#2), got"+n82.getUserData());
- final Notification n83 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n83.getUserData()).intValue() != 8)
- throw new Exception("Expected 8 (#3), got"+n83.getUserData());
-
- // Remove 2 NL, send 1 notif (9)
- ubpdalfdla.removeNotificationListener(listener2);
- proxy.sendNotification(new Integer(9));
-
- // Next notifs in queue should be (9), 1 time only.
- final Notification n9 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n9.getUserData()).intValue() != 9)
- throw new Exception("Expected 9, got"+n9.getUserData());
-
- // send 1 notif (10)
- proxy.sendNotification(new Integer(10));
-
- // Next notifs in queue should be (10), 1 time only.
- final Notification n10 = bbq.poll(3,TimeUnit.SECONDS);
- // may throw NPE => would indicate a bug.
- if (((Integer)n10.getUserData()).intValue() != 10)
- throw new Exception("Expected 10, got"+n10.getUserData());
-
- ubpdalfdla.removeNotificationListener(listener1);
- mbs.unregisterMBean(longtar);
-
- } finally {
- c.close();
- }
- } finally {
- closeNamespace(server,b);
- closeNamespace(server,a);
- rmi.stop();
- }
-
- }
-
- public static void main(String[] args) throws Exception {
- testSubject();
- }
-
-}
--- a/jdk/test/javax/management/namespace/RoutingServerProxyTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,400 +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.
- *
- * 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.
- */
-
-/*
- * @test RoutingServerProxyTest.java 1.6
- * @summary General RoutingServerProxyTest test.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean RoutingServerProxyTest Wombat WombatMBean
- * @compile -XDignore.symbol.file=true RoutingServerProxyTest.java
- * @run build RoutingServerProxyTest Wombat WombatMBean
- * @run main RoutingServerProxyTest
- */
-
-import com.sun.jmx.namespace.RoutingServerProxy;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMException;
-import javax.management.JMX;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationEmitter;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.StandardEmitterMBean;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.MBeanServerSupport;
-
-/**
- * Class RoutingServerProxyTest
- *
- * @author Sun Microsystems, Inc.
- */
-public class RoutingServerProxyTest {
-
- /**
- * A logger for this class.
- **/
- private static final Logger LOG =
- Logger.getLogger(RoutingServerProxyTest.class.getName());
-
- /**
- * Creates a new instance of RoutingServerProxyTest
- */
- public RoutingServerProxyTest() {
- }
-
- public static class DynamicWombat extends StandardEmitterMBean {
- DynamicWombat(Wombat w) throws NotCompliantMBeanException {
- super(w,WombatMBean.class,w);
- }
-
- @Override
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- final ObjectName myname = ((Wombat)getImplementation()).
- preRegister(server,name);
- return super.preRegister(server,myname);
- }
-
- @Override
- public void postRegister(Boolean registrationDone) {
- try {
- ((Wombat)getImplementation()).
- postRegister(registrationDone);
- } finally {
- super.postRegister(registrationDone);
- }
- }
-
- @Override
- public void preDeregister() throws Exception {
- ((Wombat)getImplementation()).
- preDeregister();
- super.preDeregister();
-
- }
-
- @Override
- public void postDeregister() {
- try {
- ((Wombat)getImplementation()).
- postDeregister();
- } finally {
- super.postDeregister();
- }
- }
- }
-
- public static class VirtualWombatHandler
- extends JMXNamespace {
-
- public static class VirtualWombatRepository
- extends MBeanServerSupport {
-
- final Map<ObjectName, DynamicMBean> bush;
-
- VirtualWombatRepository(Map<ObjectName, DynamicMBean> bush) {
- this.bush = bush;
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return bush.keySet();
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- final DynamicMBean mb = bush.get(name);
- if (mb == null) {
- throw new InstanceNotFoundException(String.valueOf(name));
- }
- return mb;
- }
-
- @Override
- public NotificationEmitter getNotificationEmitterFor(
- ObjectName name) throws InstanceNotFoundException {
- DynamicMBean mbean = getDynamicMBeanFor(name);
- if (mbean instanceof NotificationEmitter) {
- return (NotificationEmitter) mbean;
- }
- return null;
- }
- }
- VirtualWombatRepository bush;
-
- VirtualWombatHandler(Map<ObjectName, DynamicMBean> bush) {
- this(new VirtualWombatRepository(Collections.synchronizedMap(bush)));
- }
-
- private VirtualWombatHandler(VirtualWombatRepository repository) {
- super(repository);
- bush = repository;
- }
-
- @Override
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- final ObjectName myname = super.preRegister(server, name);
- return myname;
- }
-
- @Override
- public void postRegister(Boolean registrationDone) {
- if (!registrationDone.booleanValue()) {
- return;
- }
- final MBeanServer me = JMXNamespaces.narrowToNamespace(getMBeanServer(),
- getObjectName().getDomain());
- for (Map.Entry<ObjectName, DynamicMBean> e : bush.bush.entrySet()) {
- final DynamicMBean obj = e.getValue();
- try {
- if (obj instanceof MBeanRegistration) {
- ((MBeanRegistration) obj).preRegister(me, e.getKey());
- }
- } catch (Exception x) {
- System.err.println("preRegister failed for " +
- e.getKey() + ": " + x);
- bush.bush.remove(e.getKey());
- }
- }
- for (Map.Entry<ObjectName, DynamicMBean> e : bush.bush.entrySet()) {
- final Object obj = e.getValue();
- if (obj instanceof MBeanRegistration) {
- ((MBeanRegistration) obj).postRegister(registrationDone);
- }
- }
- }
-
- @Override
- public void preDeregister() throws Exception {
- for (Map.Entry<ObjectName, DynamicMBean> e : bush.bush.entrySet()) {
- final Object obj = e.getValue();
- if (obj instanceof MBeanRegistration) {
- ((MBeanRegistration) obj).preDeregister();
- }
- }
- }
-
- @Override
- public void postDeregister() {
- for (Map.Entry<ObjectName, DynamicMBean> e : bush.bush.entrySet()) {
- final Object obj = e.getValue();
- if (obj instanceof MBeanRegistration) {
- ((MBeanRegistration) obj).postDeregister();
- }
- }
- }
- }
-
- public static ObjectName getWombatName(String name)
- throws MalformedObjectNameException {
- return ObjectName.getInstance("australian.bush:type=Wombat,name="+name);
- }
-
- public static ObjectName addDir(String dir, ObjectName name)
- throws MalformedObjectNameException {
- return name.withDomain(
- dir+JMXNamespaces.NAMESPACE_SEPARATOR+ name.getDomain());
- }
-
- public static void simpleTest()
- throws JMException, IOException {
- final MBeanServer master = MBeanServerFactory.createMBeanServer();
- final MBeanServer agent1 = MBeanServerFactory.createMBeanServer();
- final Wombat w1 = new Wombat();
- final Wombat w2 = new Wombat();
- final Wombat w3 = new Wombat();
- final Map<ObjectName,DynamicMBean> wombats =
- new ConcurrentHashMap<ObjectName,DynamicMBean>();
- wombats.put(getWombatName("LittleWombat"),
- new DynamicWombat(w2));
- wombats.put(getWombatName("BigWombat"),
- new DynamicWombat(w3));
- final Wombat w4 = new Wombat();
- final Wombat w5 = new Wombat();
-
- final JMXNamespace agent2 =
- new VirtualWombatHandler(wombats);
- agent1.registerMBean(w4,getWombatName("LittleWombat"));
- master.registerMBean(w1,getWombatName("LittleWombat"));
- master.registerMBean(new JMXNamespace(agent1),
- JMXNamespaces.getNamespaceObjectName("south.east"));
- master.registerMBean(agent2,
- JMXNamespaces.getNamespaceObjectName("north"));
- master.registerMBean(w5,addDir("south.east",
- getWombatName("GrandWombat")));
-
- MBeanServer se = null;
-
- try {
- se = JMXNamespaces.narrowToNamespace(master,"south.easht");
- } catch (Exception x) {
- System.out.println("Caught expected exception: "+x);
- }
- if (se != null)
- throw new RuntimeException("Expected exception for "+
- "cd(south.easht)");
- se = JMXNamespaces.narrowToNamespace(master,"south.east");
-
- MBeanServer nth = JMXNamespaces.narrowToNamespace(master,"north");
-
- final ObjectName ln = getWombatName("LittleWombat");
- MBeanInfo mb1 = master.getMBeanInfo(ln);
- MBeanInfo mb2 = se.getMBeanInfo(ln);
- MBeanInfo mb3 = nth.getMBeanInfo(ln);
-
- final WombatMBean grand = JMX.newMBeanProxy(se,
- getWombatName("GrandWombat"),WombatMBean.class);
- final WombatMBean big = JMX.newMBeanProxy(nth,
- getWombatName("BigWombat"),WombatMBean.class);
- grand.getCaption();
- big.getCaption();
- grand.setCaption("I am GrandWombat");
- big.setCaption("I am BigWombat");
-
- final WombatMBean grand2 =
- JMX.newMBeanProxy(master,addDir("south.east",
- getWombatName("GrandWombat")),WombatMBean.class);
- final WombatMBean big2 =
- JMX.newMBeanProxy(master,addDir("north",
- getWombatName("BigWombat")),WombatMBean.class);
- if (!"I am GrandWombat".equals(grand2.getCaption()))
- throw new RuntimeException("bad caption for GrandWombat"+
- grand2.getCaption());
- if (!"I am BigWombat".equals(big2.getCaption()))
- throw new RuntimeException("bad caption for BigWombat"+
- big2.getCaption());
-
-
- final Set<ObjectInstance> northWombats =
- nth.queryMBeans(ObjectName.WILDCARD,null);
- final Set<ObjectInstance> seWombats =
- se.queryMBeans(ObjectName.WILDCARD,null);
- if (!northWombats.equals(
- agent2.getSourceServer().queryMBeans(ObjectName.WILDCARD,null))) {
- throw new RuntimeException("Bad Wombat census in northern territory: got "
- +northWombats+", expected "+
- agent2.getSourceServer().
- queryMBeans(ObjectName.WILDCARD,null));
- }
- if (!seWombats.equals(
- agent1.queryMBeans(ObjectName.WILDCARD,null))) {
- throw new RuntimeException("Bad Wombat census in south east: got "
- +seWombats+", expected "+
- agent1.
- queryMBeans(ObjectName.WILDCARD,null));
- }
-
- final MBeanServer supermaster = MBeanServerFactory.createMBeanServer();
- supermaster.registerMBean(new JMXNamespace(master),
- JMXNamespaces.getNamespaceObjectName("australia"));
- final MBeanServer proxymaster =
- JMXNamespaces.narrowToNamespace(supermaster,"australia");
- final MBeanServer sem =
- JMXNamespaces.narrowToNamespace(proxymaster,"south.east");
- final MBeanServer nthm =
- JMXNamespaces.narrowToNamespace(proxymaster,"north");
- final Set<ObjectInstance> northWombats2 =
- nthm.queryMBeans(ObjectName.WILDCARD,null);
- final Set<ObjectInstance> seWombats2 =
- sem.queryMBeans(ObjectName.WILDCARD,null);
- if (!northWombats2.equals(
- agent2.getSourceServer().queryMBeans(ObjectName.WILDCARD,null))) {
- throw new RuntimeException("Bad Wombat census in " +
- "Australia // North");
- }
- if (!seWombats2.equals(
- agent1.queryMBeans(ObjectName.WILDCARD,null))) {
- throw new RuntimeException("Bad Wombat census in " +
- "Australia // South East");
- }
- final WombatMBean grand3 =
- JMX.newMBeanProxy(supermaster,
- addDir("australia//south.east",
- getWombatName("GrandWombat")),WombatMBean.class);
- final WombatMBean big3 =
- JMX.newMBeanProxy(supermaster,addDir("australia//north",
- getWombatName("BigWombat")),WombatMBean.class);
- if (!"I am GrandWombat".equals(grand3.getCaption()))
- throw new RuntimeException("bad caption for " +
- "australia//south.east//GrandWombat"+
- grand3.getCaption());
- if (!"I am BigWombat".equals(big3.getCaption()))
- throw new RuntimeException("bad caption for " +
- "australia//north//BigWombat"+
- big3.getCaption());
- final WombatMBean grand4 =
- JMX.newMBeanProxy(sem,
- getWombatName("GrandWombat"),WombatMBean.class);
- final WombatMBean big4 =
- JMX.newMBeanProxy(nthm,
- getWombatName("BigWombat"),WombatMBean.class);
- if (!"I am GrandWombat".equals(grand4.getCaption()))
- throw new RuntimeException("bad caption for " +
- "[australia//south.east//] GrandWombat"+
- grand4.getCaption());
- if (!"I am BigWombat".equals(big4.getCaption()))
- throw new RuntimeException("bad caption for " +
- "[australia//north//] BigWombat"+
- big4.getCaption());
-
- if (!(nthm instanceof RoutingServerProxy))
- throw new AssertionError("expected RoutingServerProxy for nthm");
- if (!(sem instanceof RoutingServerProxy))
- throw new AssertionError("expected RoutingServerProxy for sem");
-
- if (!"australia//north".equals((
- (RoutingServerProxy)nthm).getSourceNamespace()))
- throw new RuntimeException("north territory should be in australia");
- if (!"australia//south.east".equals((
- (RoutingServerProxy)sem).getSourceNamespace()))
- throw new RuntimeException("south east territory should be in australia");
-
- }
-
- public static void main(String[] args) {
- try {
- simpleTest();
- } catch (Exception x) {
- System.err.println("SimpleTest failed: "+x);
- throw new RuntimeException(x);
- }
- }
-
-}
--- a/jdk/test/javax/management/namespace/SerialParamProcessorTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,572 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test SerialParamProcessorTest.java 1.8
- * @summary General SerialParamProcessorTest test.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean SerialParamProcessorTest Wombat WombatMBean
- * @compile -XDignore.symbol.file=true SerialParamProcessorTest.java
- * @run build SerialParamProcessorTest Wombat WombatMBean
- * @run main SerialParamProcessorTest
- */
-
-import com.sun.jmx.namespace.serial.RewritingProcessor;
-import java.beans.ConstructorProperties;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import javax.management.AttributeChangeNotification;
-import javax.management.AttributeList;
-import javax.management.JMException;
-import javax.management.Notification;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-
-/**
- * Class SerialParamProcessorTest
- *
- * @author Sun Microsystems, Inc.
- */
-public class SerialParamProcessorTest {
-
- /**
- * Creates a new instance of SerialParamProcessorTest
- */
- public SerialParamProcessorTest() {
- }
-
- public static class MyCompositeData implements Serializable {
- private static final long serialVersionUID = 3186492415099133506L;
- public MyCompositeData(ObjectName foobar,ObjectName absolute,
- long count, String name) {
- this(foobar,absolute,count,name,new ObjectName[]{foobar,absolute});
- }
- @ConstructorProperties(value={"fooBar","absolute","count","name",
- "allNames"})
- public MyCompositeData(ObjectName foobar,ObjectName absolute,
- long count, String name, ObjectName[] allnames) {
- this.foobar = foobar;
- this.absolute = absolute;
- this.count = count;
- this.name = name;
- this.allnames = allnames;
- }
- ObjectName foobar,absolute,allnames[];
- long count;
- String name;
- public ObjectName getFooBar() {
- return foobar;
- }
- public ObjectName getAbsolute() {
- return absolute;
- }
- public ObjectName[] getAllNames() {
- return allnames;
- }
- public long getCount() {
- return count;
- }
- public String getName() {
- return name;
- }
- private Object[] toArray() {
- final Object[] props = {
- getName(),getFooBar(),getAbsolute(),getAllNames(),getCount()
- };
- return props;
- }
- @Override
- public boolean equals(Object o) {
- if (o instanceof MyCompositeData)
- return Arrays.deepEquals(toArray(),
- ((MyCompositeData)o).toArray());
- return false;
- }
- @Override
- public int hashCode() {
- return Arrays.deepHashCode(toArray());
- }
- }
-
- public static interface MyMXBean {
- public Map<String,MyCompositeData> getAll();
- public MyCompositeData lookup(String name);
- public void put(String name, MyCompositeData data);
- public MyCompositeData remove(String name);
- }
-
- public static class My implements MyMXBean {
- Map<String,MyCompositeData> datas =
- new HashMap<String,MyCompositeData>();
- public Map<String,MyCompositeData> getAll() {
- return datas;
- }
- public MyCompositeData lookup(String name) {
- return datas.get(name);
- }
- public void put(String name, MyCompositeData data) {
- datas.put(name,data);
- }
- public MyCompositeData remove(String name) {
- return datas.remove(name);
- }
- }
-
- public static class BandicootClass implements Serializable {
- private static final long serialVersionUID = -5494055748633966355L;
- public final Object gloups;
- public BandicootClass(Object gloups) {
- this.gloups = gloups;
- }
- private Object[] toArray() {
- final Object[] one = {gloups};
- return one;
- }
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof BandicootClass)) return false;
- final Object[] one = {gloups};
- return Arrays.deepEquals(toArray(),((BandicootClass)obj).toArray());
- }
- @Override
- public int hashCode() {
- if (gloups == null) return 0;
- return Arrays.deepHashCode(toArray());
- }
- }
-
- // Need this to override equals.
- public static class BandicootNotification extends Notification {
- private static final long serialVersionUID = 664758643764049001L;
- public BandicootNotification(String type, Object source, long seq) {
- super(type,source,seq,0L,"");
- }
- private Object[] toArray() {
- final Object[] vals = {getMessage(),getSequenceNumber(),
- getSource(),getTimeStamp(),getType(),getUserData()};
- return vals;
- }
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof BandicootNotification)) return false;
- return Arrays.deepEquals(toArray(),
- ((BandicootNotification)o).toArray());
- }
- @Override
- public int hashCode() {
- return Arrays.deepHashCode(toArray());
- }
-
- }
-
- // Need this to override equals.
- public static class BandicootAttributeChangeNotification
- extends AttributeChangeNotification {
- private static final long serialVersionUID = -1392435607144396125L;
- public BandicootAttributeChangeNotification(Object source,
- long seq, long time, String msg, String name, String type,
- Object oldv, Object newv) {
- super(source,seq,time,msg,name,type,oldv,newv);
- }
- private Object[] toArray() {
- final Object[] vals = {getMessage(),getSequenceNumber(),
- getSource(),getTimeStamp(),getType(),getUserData(),
- getAttributeName(), getAttributeType(),getNewValue(),
- getOldValue()};
- return vals;
- }
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof BandicootAttributeChangeNotification))
- return false;
- return Arrays.deepEquals(toArray(),
- ((BandicootAttributeChangeNotification)o).toArray());
- }
- @Override
- public int hashCode() {
- return Arrays.deepHashCode(toArray());
- }
- @Override
- public String toString() {
- final StringBuilder b = new StringBuilder();
- b.append(this.getClass().getName()).append(": ");
- b.append("[type=").append(getType()).append("]");
- b.append("[source=").append(getSource()).append("]");
- b.append("[message=").append(getMessage()).append("]");
- b.append("[sequence=").append(getSequenceNumber()).append("]");
-
- b.append("[attribute=").append(getAttributeName()).append("]");
- b.append("[class=").append(getAttributeType()).append("]");
- b.append("[oldvalue=").append(getOldValue()).append("]");
- b.append("[newvalue=").append(getNewValue()).append("]");
-
- b.append("[time=").append(getTimeStamp()).append("]");
- b.append("[data=").append(getUserData()).append("]");
- return b.toString();
- }
- }
-
- private static void addToList(Object[] foos, List<Object> foolist) {
- final ArrayList<Object> fal = new ArrayList<Object>(foos.length);
- for (Object f : foos) {
- if (f.getClass().isArray()) {
- foolist.add(new BandicootClass(f));
- fal.add(new BandicootClass(f));
- } else {
- foolist.add(f);
- fal.add(f);
- }
- }
- foolist.add(new BandicootClass(foos));
- foolist.add(fal);
- }
-
- public static void testSerial(String msg, Object foo, Object bar,
- RewritingProcessor procForFoo,
- RewritingProcessor procForBar, List<Object> foolist,
- List<Object> barlist, boolean recurse) {
- System.err.println(msg+" Testing serial - "+foo.getClass().getName());
- final Object bar1 = procForFoo.rewriteInput(foo);
- final Object foo1 = procForFoo.rewriteOutput(bar);
- final Object bar2 = procForFoo.rewriteInput(foo1);
- final Object foo2 = procForFoo.rewriteOutput(bar1);
-
- final Object bar3 = procForBar.rewriteOutput(foo);
- final Object foo3 = procForBar.rewriteInput(bar);
- final Object bar4 = procForBar.rewriteOutput(foo3);
- final Object foo4 = procForBar.rewriteInput(bar3);
-
- final Object bar5 = procForFoo.rewriteInput(foo3);
- final Object foo5 = procForFoo.rewriteOutput(bar3);
-
- final Object bar6 = procForBar.rewriteOutput(foo1);
- final Object foo6 = procForBar.rewriteInput(bar1);
-
- final Object[] foos = {foo, foo1, foo2, foo3, foo4, foo5, foo6};
- final Object[] bars = {bar, bar1, bar2, bar3, bar4, bar5, bar6};
-
- final Object[] foot = { foo };
- final Object[] bart = { bar };
- for (int j=1;j<foos.length;j++) {
- final Object[] foox = { foos[j] };
- final Object[] barx = { bars[j] };
- if (!Arrays.deepEquals(foot,foox)) {
- System.err.println(msg+" foo"+j+" "+foos[j]+" != "+foo);
- throw new RuntimeException(msg+" foo"+j+" != foo");
- }
- if (!Arrays.deepEquals(bart,barx)) {
- System.err.println(msg+" bar"+j+" "+bars[j]+" != "+bar);
- throw new RuntimeException(msg+" bar"+j+" != bar");
- }
-
- }
- if (recurse) {
- testSerial("Array: " + msg,foos,bars,procForFoo,
- procForBar,foolist,barlist,false);
- addToList(foos,foolist);
- addToList(bars,barlist);
- }
- }
- public static void testSerial(Object[][] objects,
- RewritingProcessor procForFoo,
- RewritingProcessor procForBar) {
- int i=0;
- final List<Object> foolist = new LinkedList<Object>();
- final List<Object> barlist = new LinkedList<Object>();
- for (Object[] row : objects) {
- i++;
- Object foo = row[0];
- Object bar = row[1];
- String msg1 = "[" +foo.getClass().getName() + "] step " +
- i +": ";
-
- testSerial(msg1,foo,bar,procForFoo,procForBar,foolist,barlist,true);
-
- final BandicootClass kfoo = new BandicootClass(foo);
- final BandicootClass kbar = new BandicootClass(bar);
-
- String msg2 = "[" +kfoo.getClass().getName() + "] step " +
- i +": ";
- testSerial(msg2,kfoo,kbar,procForFoo,procForBar,foolist,barlist,true);
- }
- String msg31 = "foo[] and bar[]: ";
- testSerial(msg31,foolist.toArray(),barlist.toArray(),
- procForFoo,procForBar,foolist,barlist,false);
-
- String msg3 = "foolist and barlist: ";
- testSerial(msg3,new LinkedList<Object>(foolist),
- new LinkedList<Object>(barlist),
- procForFoo,procForBar,foolist,barlist,false);
-
- final BandicootClass kfoolist = new BandicootClass(foolist);
- final BandicootClass kbarlist = new BandicootClass(barlist);
- String msg4 = "kfoolist and kbarlist: ";
- testSerial(msg4,kfoolist,kbarlist,procForFoo,procForBar,foolist,barlist,false);
- }
-
- /**
- * The idea of this method is to convert {@code foo} things into
- * {@code bar} things...
- * @param foo the string to replace.
- * @param bar the replacement for {@code foo}
- * ({@code foo} becomes {@code bar}).
- * @param sfoo a string that may contain {@code foo}, that will be embedded
- * in non-replaceable parts of the domain in order to attempt to
- * trick the replacement logic.
- * @param sbar a string that may contain {@code bar}, that will be embedded
- * in non-replaceable parts of the domain in order to attempt to
- * trick the replacement logic.
- **/
- public static void doSerialTest(String foo, String bar, String sfoo,
- String sbar) {
- try {
- final RewritingProcessor procForFoo = RewritingProcessor.
- newRewritingProcessor(foo,bar);
- final RewritingProcessor procForBar =RewritingProcessor.
- newRewritingProcessor(bar,foo);
- final String foop = (foo.isEmpty())?foo:foo+"//";
- final String pfoo = (foo.isEmpty())?foo:"//"+foo;
- final String barp = (bar.isEmpty())?bar:bar+"//";
- final String pbar = (bar.isEmpty())?bar:"//"+bar;
- final String sfoop = (sfoo.isEmpty())?sfoo:sfoo+"//";
- final String psfoo = (sfoo.isEmpty())?sfoo:"//"+sfoo;
- final String sbarp = (sbar.isEmpty())?sbar:sbar+"//";
- final String psbar = (sbar.isEmpty())?sbar:"//"+sbar;
-
- // A trick to avoid writing Open Data by hand...
- final My tricks = new My();
-
- // A treat to automagically convert trick things into Open Data.
- final StandardMBean treats =
- new StandardMBean(tricks,MyMXBean.class,true);
-
- // datas[i][0] is expected to be transformed in datas[i][1]
- //
- final MyCompositeData[][] datas = {
- { // this foo thing:
- new MyCompositeData(new ObjectName(foop+sbarp+"x:y=z"),
- new ObjectName("//"+foop+sbarp+"x:y=z"),1,sfoop+sbarp+"foobar"),
- // should be transformed into this bar thing:
- new MyCompositeData(new ObjectName(barp+sbarp+"x:y=z"),
- new ObjectName("//"+foop+sbarp+"x:y=z"),1,sfoop+sbarp+"foobar"),
- },
- { // this foo thing:
- new MyCompositeData(new ObjectName(foop+sfoop+"x:y=z"),
- new ObjectName("//"+foop+sfoop+"x:y=z"),1,sfoop+sbarp+"barfoo"),
- // should be transformed into this bar thing:
- new MyCompositeData(new ObjectName(barp+sfoop+"x:y=z"),
- new ObjectName("//"+foop+sfoop+"x:y=z"),1,sfoop+sbarp+"barfoo"),
- }
- };
-
- // objects[i][0] is expected to be transformed into objects[i][1]
- //
- final Object[][] objects = new Object[][] {
- {new Long(1), new Long(1)},
- {
- new ObjectName(foop+sbarp+"x:y=z"),
- new ObjectName(barp+sbarp+"x:y=z")
- },
- {
- new ObjectName(foop+sfoop+"x:y=z"),
- new ObjectName(barp+sfoop+"x:y=z")
- },
- {
- new ObjectName("//"+foop+sbarp+"x:y=z"),
- new ObjectName("//"+foop+sbarp+"x:y=z"),
- },
- {
- new ObjectName("//"+foop+sfoop+"x:y=z"),
- new ObjectName("//"+foop+sfoop+"x:y=z")
- },
- {
- foop+sbarp+"x:y=z",foop+sbarp+"x:y=z"
- },
- {
- foop+sfoop+"x:y=z",foop+sfoop+"x:y=z"
- },
- {
- barp+sbarp+"x:y=z",barp+sbarp+"x:y=z"
- },
- {
- barp+sfoop+"x:y=z",barp+sfoop+"x:y=z"
- },
- {
- new BandicootNotification("test",new ObjectName(foop+sfoop+"x:y=z"),1L),
- new BandicootNotification("test",new ObjectName(barp+sfoop+"x:y=z"),1L),
- },
- {
- new BandicootNotification("test",new ObjectName("//"+foop+sfoop+"x:y=z"),2L),
- new BandicootNotification("test",new ObjectName("//"+foop+sfoop+"x:y=z"),2L),
- },
- {
- new BandicootAttributeChangeNotification(
- new ObjectName(foop+sfoop+"x:y=z"),1L,2L,"blah","attrname",
- ObjectName.class.getName(),
- new ObjectName(foop+sfoop+"x:y=old"),
- new ObjectName(foop+sfoop+"x:y=new")),
- new BandicootAttributeChangeNotification(
- new ObjectName(barp+sfoop+"x:y=z"),1L,2L,"blah","attrname",
- ObjectName.class.getName(),
- new ObjectName(barp+sfoop+"x:y=old"),
- new ObjectName(barp+sfoop+"x:y=new")),
- },
- {
- new BandicootAttributeChangeNotification(
- new ObjectName("//"+foop+sfoop+"x:y=z"),1L,2L,"blah","attrname",
- ObjectName.class.getName(),
- new ObjectName("//"+foop+sfoop+"x:y=old"),
- new ObjectName(foop+sfoop+"x:y=new")),
- new BandicootAttributeChangeNotification(
- new ObjectName("//"+foop+sfoop+"x:y=z"),1L,2L,"blah","attrname",
- ObjectName.class.getName(),
- new ObjectName("//"+foop+sfoop+"x:y=old"),
- new ObjectName(barp+sfoop+"x:y=new")),
- }
- };
-
- // List that will merge datas & objects & datas converted to open
- // types...
- //
- final List<Object[]> list = new ArrayList<Object[]>();
-
- // Add all objects...
- //
- list.addAll(Arrays.asList(objects));
-
- // Build Map<String,MyCompositeData> with datas[i][0] (cfoo)
- //
- for (int i=0;i<datas.length;i++) {
- tricks.put(sfoop+sbarp+"x"+i,datas[i][0]);
- }
-
- // Let MXBean convert Map<String,MyCompositeData> to TabularData
- // (foo things)
- final Object cfoo = treats.getAttribute("All");
- final AttributeList afoo = treats.getAttributes(new String[] {"All"});
-
- // Build Map<String,MyCompositeData> with datas[i][1] (cbar)
- //
- for (int i=0;i<datas.length;i++) {
- tricks.remove(sfoop+sbarp+"x"+i);
- tricks.put(sfoop+sbarp+"x"+i,datas[i][1]);
- }
-
- // Let MXBean convert Map<String,MyCompositeData> to TabularData
- // (bar things)
- final Object cbar = treats.getAttribute("All");
- final AttributeList abar = treats.getAttributes(new String[] {"All"});
-
- // Add all datas to list
- for (int i=0;i<datas.length;i++) {
- list.add(datas[i]);
- }
-
- // Add converted TabularDatas to list
- list.add(new Object[] {cfoo,cbar});
-
- // Add AttributeList containing TabularData to list
- list.add(new Object[] {afoo,abar});
-
- // Add Arrays of the above to list...
- list.add(new Object[] {new Object[] {cfoo,afoo,1L},
- new Object[] {cbar,abar,1L}});
-
- // Add MBeanInfo...
- list.add(new Object[] {treats.getMBeanInfo(),treats.getMBeanInfo()});
-
- // No ready to test conversion of all foo things into bar things.
- //
- testSerial(list.toArray(new Object[list.size()][]),
- procForFoo,procForBar);
- } catch (JMException x) {
- throw new RuntimeException(x);
- }
- }
-
- public static void aaaTest() {
- System.err.println("\n--------------------- aaaTest ----------------");
- System.err.println("---------------- 'foo' becomes 'bar' ---------\n");
- doSerialTest("foo","bar","foo","bar");
- }
-
- public static void aabTest() {
- System.err.println("\n--------------------- aabTest ----------------");
- System.err.println("---------- 'foo//bar' becomes 'bar//foo' -----\n");
- doSerialTest("foo//bar","bar//foo","foo","bar");
- }
-
- public static void aacTest() {
- System.err.println("\n----------------- aacTest --------------------");
- System.err.println("------------ 'foo//bar' becomes '' -----------\n");
- doSerialTest("foo//bar","","foo","bar");
- }
-
- public static void aadTest() {
- System.err.println("\n----------------- aadTest --------------------");
- System.err.println("----------- '' becomes 'bar//foo' ------------\n");
- doSerialTest("","bar//foo","","bar//foo");
- }
-
- public static void aaeTest() {
- System.err.println("\n----------------- aaeTest --------------------");
- System.err.println("----------------- '' becomes '' --------------\n");
- doSerialTest("","","foo","bar//foo");
- }
-
- // Let's be wild...
- public static void aafTest() {
- System.err.println("\n----------------- aafTest --------------------");
- System.err.println("----------- '' becomes '' -- (bis) -----------\n");
- doSerialTest("","","","");
- }
- public static void aagTest() {
- System.err.println("\n----------------- aagTest --------------------");
- System.err.println("----------- foobar becomes foobar ------------\n");
- doSerialTest("foobar","foobar","foobar","foobar");
- }
-
- // TODO add test with descriptor, MBeanInfo, Open Types, etc...
- public static void main(String[] args) {
- aaaTest();
- aabTest();
- aacTest();
- aadTest();
- aaeTest();
- aafTest();
- aagTest();
-
- // TODO: add a test case to test *exactly* the serialization
- // of Notification and AttributeChangeNotification, and not of
- // a subclass of these.
- // This will involve implementing some hack, because we
- // can't use equals() to compare the results.
- }
-}
--- a/jdk/test/javax/management/namespace/SourceNamespaceTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +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.
- *
- * 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.
- */
-/*
- *
- * @test SourceNamespaceTest.java
- * @summary Test how queryNames works with Namespaces.
- * @bug 5072476
- * @author Daniel Fuchs
- * @run clean SourceNamespaceTest Wombat WombatMBean
- * @run build SourceNamespaceTest Wombat WombatMBean
- * @run main SourceNamespaceTest
- */
-
-
-import javax.management.JMException;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-
-/**
- * A simple test to test the source directory parameter...
- * @author dfuchs
- */
-public class SourceNamespaceTest {
-
-
- public static void localTest() throws JMException {
- final JMXNamespace adir =
- new JMXNamespace(MBeanServerFactory.newMBeanServer());
-
- // put a wombat in adir...
- final Wombat w1 = new Wombat();
- final ObjectName wn1 = new ObjectName("wilderness:type=Wombat,name=gloups");
- adir.getSourceServer().registerMBean(w1,wn1);
-
- // register adir
- final MBeanServer server = MBeanServerFactory.newMBeanServer();
- server.registerMBean(adir, JMXNamespaces.getNamespaceObjectName("adir"));
-
- if (! (server.isRegistered(JMXNamespaces.insertPath("adir", wn1))))
- throw new RuntimeException("Test failed: " +
- JMXNamespaces.insertPath("adir", wn1) + " not found");
-
- System.out.println("Wombat gloups correctly registered...");
-
- // put another wombat in adir...
- final Wombat w2 = new Wombat();
- final ObjectName wn2 =
- new ObjectName("wilderness:type=Wombat,name=pasgloups");
- server.registerMBean(w2,JMXNamespaces.insertPath("adir", wn2));
-
- if (! (server.isRegistered(JMXNamespaces.insertPath("adir", wn2))))
- throw new RuntimeException("Test failed: " +
- JMXNamespaces.insertPath("adir", wn2) + " not found");
-
- System.out.println("Wombat pasgloups correctly registered...");
-
-
- // make an alias
- final JMXNamespace alias = new JMXNamespace(
- JMXNamespaces.narrowToNamespace(server,"adir"));
- server.registerMBean(alias,
- JMXNamespaces.getNamespaceObjectName("alias"));
-
- if (! (server.isRegistered(JMXNamespaces.insertPath("alias", wn1))))
- throw new RuntimeException("Test failed: " +
- JMXNamespaces.insertPath("alias", wn1) + " not found");
-
- System.out.println("Wombat gloups accessible through alias...");
-
- if (! (server.isRegistered(JMXNamespaces.insertPath("alias", wn2))))
- throw new RuntimeException("Test failed: " +
- JMXNamespaces.insertPath("alias", wn2) + " not found");
-
- System.out.println("Wombat pasgloups accessible through alias...");
-
- final WombatMBean wp2 = JMX.newMBeanProxy(server,
- JMXNamespaces.insertPath("alias",wn2), WombatMBean.class);
- System.out.println(JMXNamespaces.insertPath("alias",wn2).toString()
- +" says: "+wp2.getCaption());
-
- // We're going to make another alias, but register it in a different
- // MBeanServer. This is to make sure that source server and target
- // server are not mixed up.
- //
- final MBeanServer server2 = MBeanServerFactory.newMBeanServer();
- final JMXNamespace alias2 = new JMXNamespace(
- JMXNamespaces.narrowToNamespace(server,"adir"));
- server2.registerMBean(alias2,
- JMXNamespaces.getNamespaceObjectName("alias2"));
-
-
- if (! (server2.isRegistered(JMXNamespaces.insertPath("alias2", wn1))))
- throw new RuntimeException("Test failed: " +
- JMXNamespaces.insertPath("alias2", wn1) + " not found");
-
- System.out.println("Wombat gloups accessible through alias2...");
-
- if (! (server2.isRegistered(JMXNamespaces.insertPath("alias2", wn2))))
- throw new RuntimeException("Test failed: " +
- JMXNamespaces.insertPath("alias2", wn2) + " not found");
-
- System.out.println("Wombat pasgloups accessible through alias...");
-
- final WombatMBean wp22 = JMX.newMBeanProxy(server2,
- JMXNamespaces.insertPath("alias2",wn2), WombatMBean.class);
- System.out.println(JMXNamespaces.insertPath("alias2",wn2).toString()
- +" says: "+wp22.getCaption());
-
-
-
- }
-
- public static void main(String[] args) throws Exception {
- localTest();
- }
-
-}
--- a/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,569 +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.
- *
- * 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.
- */
-
-/*
- * @test VirtualMBeanNotifTest.java
- * @bug 5108776
- * @build VirtualMBeanNotifTest Wombat WombatMBean
- * @run main VirtualMBeanNotifTest
- * @summary Test that Virtual MBeans can be implemented and emit notifs.
- * @author Daniel Fuchs
- */
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
-import javax.management.Attribute;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.RuntimeOperationsException;
-import javax.management.StandardMBean;
-import javax.management.event.EventSubscriber;
-import javax.management.namespace.VirtualEventManager;
-import javax.management.namespace.MBeanServerSupport;
-
-public class VirtualMBeanNotifTest {
-
- /**
- * An invocation handler that can implement DynamicMBean,
- * NotificationBroadcaster, NotificationEmitter.
- * The invocation handler works by forwarding all calls received from
- * the implemented interfaces through a wrapped MBeanServer object.
- */
- public static class DynamicWrapper
- implements InvocationHandler {
-
- /**
- * Inserts an additional class at the head of a signature array.
- * @param first The first class in the signature
- * @param rest The other classes in the signature
- * @return A signature array, of length rest.length+1.
- */
- static Class[] concat(Class first, Class... rest) {
- if (rest == null || rest.length == 0) {
- return new Class[] { first };
- }
- final Class[] sig = new Class[rest.length+1];
- sig[0] = first;
- System.arraycopy(rest, 0, sig, 1, rest.length);
- return sig;
- }
-
- /**
- * Inserts an additional object at the head of a parameters array.
- * @param first The first object in the parameter array.
- * @param rest The other objects in the parameter array.
- * @return A parameter array, of length rest.length+1.
- */
- static Object[] concat(Object first, Object... rest) {
- if (rest == null || rest.length == 0) {
- return new Object[] { first };
- }
- final Object[] params = new Object[rest.length+1];
- params[0] = first;
- System.arraycopy(rest, 0, params, 1, rest.length);
- return params;
- }
-
- /**
- * These two sets are used to check that all methods from
- * implemented interfaces are mapped.
- * unmapped is the set of methods that couldn't be mapped.
- * mapped is the set of methods that could be mapped.
- */
- final static Set<Method> unmapped = new HashSet<Method>();
- final static Set<Method> mapped = new HashSet<Method>();
-
- /**
- * For each method define in one of the interfaces intf, tries
- * to find a corresponding method in the reference class ref, where
- * the method in ref has the same name, and takes an additional
- * ObjectName as first parameter.
- *
- * So for instance, if ref is MBeanServer and intf is {DynamicMBean}
- * the result map is:
- * DynamicMBean.getAttribute -> MBeanServer.getAttribute
- * DynamicMBean.setAttribute -> MBeanServer.setAttribute
- * etc...
- * If a method was mapped, it is additionally added to 'mapped'
- * If a method couldn't be mapped, it is added to 'unmmapped'.
- * In our example above, DynamicMBean.getNotificationInfo will end
- * up in 'unmapped'.
- *
- * @param ref The reference class - to which calls will be forwarded
- * with an additional ObjectName parameter inserted.
- * @param intf The proxy interface classes - for which we must find an
- * equivalent in 'ref'
- * @return A map mapping the methods from intfs to the method of ref.
- */
- static Map<Method,Method> makeMapFor(Class<?> ref, Class<?>... intf) {
- final Map<Method,Method> map = new HashMap<Method,Method>();
- for (Class<?> clazz : intf) {
- for (Method m : clazz.getMethods()) {
- try {
- final Method m2 =
- ref.getMethod(m.getName(),
- concat(ObjectName.class,m.getParameterTypes()));
- map.put(m,m2);
- mapped.add(m);
- } catch (Exception x) {
- unmapped.add(m);
- }
- }
- }
- return map;
- }
-
- /**
- * Tries to map all methods from DynamicMBean.class and
- * NotificationEmitter.class to their equivalent in MBeanServer.
- * This should be all the methods except
- * DynamicMBean.getNotificationInfo.
- */
- static final Map<Method,Method> mbeanmap =
- makeMapFor(MBeanServer.class,DynamicMBean.class,
- NotificationEmitter.class);
- /**
- * Tries to map all methods from DynamicMBean.class and
- * NotificationEmitter.class to an equivalent in DynamicWrapper.
- * This time only DynamicMBean.getNotificationInfo will be mapped.
- */
- static final Map<Method,Method> selfmap =
- makeMapFor(DynamicWrapper.class,DynamicMBean.class,
- NotificationEmitter.class);
-
- /**
- * Now check that we have mapped all methods.
- */
- static {
- unmapped.removeAll(mapped);
- if (unmapped.size() > 0)
- throw new ExceptionInInitializerError("Couldn't map "+ unmapped);
- }
-
- /**
- * The wrapped MBeanServer to which everything is delegated.
- */
- private final MBeanServer server;
-
- /**
- * The name of the MBean we're proxying.
- */
- private final ObjectName name;
- DynamicWrapper(MBeanServer server, ObjectName name) {
- this.server=server;
- this.name=name;
- }
-
- /**
- * Creates a new proxy for the given MBean. Implements
- * NotificationEmitter/NotificationBroadcaster if the proxied
- * MBean also does.
- * @param name the name of the proxied MBean
- * @param server the wrapped server
- * @return a DynamicMBean proxy
- * @throws javax.management.InstanceNotFoundException
- */
- public static DynamicMBean newProxy(ObjectName name, MBeanServer server)
- throws InstanceNotFoundException {
- if (server.isInstanceOf(name,
- NotificationEmitter.class.getName())) {
- // implements NotificationEmitter
- return (DynamicMBean)
- Proxy.newProxyInstance(
- DynamicWrapper.class.getClassLoader(),
- new Class[] {NotificationEmitter.class,
- DynamicMBean.class},
- new DynamicWrapper(server, name));
- }
- if (server.isInstanceOf(name,
- NotificationBroadcaster.class.getName())) {
- // implements NotificationBroadcaster
- return (DynamicMBean)
- Proxy.newProxyInstance(
- DynamicWrapper.class.getClassLoader(),
- new Class[] {NotificationBroadcaster.class,
- DynamicMBean.class},
- new DynamicWrapper(server, name));
- }
- // Only implements DynamicMBean.
- return (DynamicMBean)
- Proxy.newProxyInstance(
- DynamicWrapper.class.getClassLoader(),
- new Class[] {DynamicMBean.class},
- new DynamicWrapper(server, name));
- }
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // Look for a method on this class (takes precedence)
- final Method self = selfmap.get(method);
- if (self != null)
- return call(this,self,concat(name,args));
-
- // no method found on this class, look for the same method
- // on the wrapped MBeanServer
- final Method mbean = mbeanmap.get(method);
- if (mbean != null)
- return call(server,mbean,concat(name,args));
-
- // This isn't a method that can be forwarded to MBeanServer.
- // If it's a method from Object, call it on this.
- if (method.getDeclaringClass().equals(Object.class))
- return call(this,method,args);
- throw new NoSuchMethodException(method.getName());
- }
-
- // Call a method using reflection, unwraps invocation target exceptions
- public Object call(Object handle, Method m, Object[] args)
- throws Throwable {
- try {
- return m.invoke(handle, args);
- } catch (InvocationTargetException x) {
- throw x.getCause();
- }
- }
-
- // this method is called when DynamicMBean.getNotificationInfo() is
- // called. This is the method that should be mapped in
- // 'selfmap'
- public MBeanNotificationInfo[] getNotificationInfo(ObjectName name)
- throws JMException {
- return server.getMBeanInfo(name).getNotifications();
- }
- }
-
- /**
- * Just so that we can call the same test twice but with two
- * different implementations of VirtualMBeanServerSupport.
- */
- public static interface MBeanServerWrapperFactory {
- public MBeanServer wrapMBeanServer(MBeanServer wrapped);
- }
-
- /**
- * A VirtualMBeanServerSupport that wrapps an MBeanServer and does not
- * use VirtualEventManager.
- */
- public static class VirtualMBeanServerTest
- extends MBeanServerSupport {
-
- final MBeanServer wrapped;
-
- public VirtualMBeanServerTest(MBeanServer wrapped) {
- this.wrapped=wrapped;
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(final ObjectName name)
- throws InstanceNotFoundException {
- if (wrapped.isRegistered(name))
- return DynamicWrapper.newProxy(name,wrapped);
- throw new InstanceNotFoundException(String.valueOf(name));
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return wrapped.queryNames(null, null);
- }
-
- public final static MBeanServerWrapperFactory factory =
- new MBeanServerWrapperFactory() {
-
- public MBeanServer wrapMBeanServer(MBeanServer wrapped) {
- return new VirtualMBeanServerTest(wrapped);
- }
- @Override
- public String toString() {
- return VirtualMBeanServerTest.class.getName();
- }
- };
- }
-
- /**
- * A VirtualMBeanServerSupport that wrapps an MBeanServer and
- * uses a VirtualEventManager.
- */
- public static class VirtualMBeanServerTest2
- extends VirtualMBeanServerTest {
-
- final EventSubscriber sub;
- final NotificationListener nl;
- final VirtualEventManager mgr;
-
- /**
- * We use an EventSubscriber to subscribe for all notifications from
- * the wrapped MBeanServer, and publish them through a
- * VirtualEventManager. Not a very efficient way of doing things.
- * @param wrapped
- */
- public VirtualMBeanServerTest2(MBeanServer wrapped) {
- super(wrapped);
- this.sub = EventSubscriber.getEventSubscriber(wrapped);
- this.mgr = new VirtualEventManager();
- this.nl = new NotificationListener() {
- public void handleNotification(Notification notification, Object handback) {
- mgr.publish((ObjectName)notification.getSource(), notification);
- }
- };
- try {
- sub.subscribe(ObjectName.WILDCARD, nl, null, null);
- } catch (RuntimeException x) {
- throw x;
- } catch (Exception x) {
- throw new IllegalStateException("can't subscribe for notifications!");
- }
- }
-
- @Override
- public NotificationEmitter
- getNotificationEmitterFor(ObjectName name)
- throws InstanceNotFoundException {
- final DynamicMBean mbean = getDynamicMBeanFor(name);
- if (mbean instanceof NotificationEmitter)
- return mgr.getNotificationEmitterFor(name);
- return null;
- }
-
- public final static MBeanServerWrapperFactory factory =
- new MBeanServerWrapperFactory() {
-
- public MBeanServer wrapMBeanServer(MBeanServer wrapped) {
- return new VirtualMBeanServerTest2(wrapped);
- }
- @Override
- public String toString() {
- return VirtualMBeanServerTest2.class.getName();
- }
- };
- }
-
-
- public static void test(MBeanServerWrapperFactory factory) throws Exception {
- final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-
- // names[] are NotificationEmitters
- final ObjectName[] emitters = new ObjectName[2];
- // shields[] have been shielded by wrapping them in a StandardMBean,
- // so although the resource is an MBean that implements
- // NotificationEmitter, the registered MBean (the wrapper) doesn't.
- final ObjectName[] shielded = new ObjectName[2];
-
- final List<ObjectName> registered = new ArrayList<ObjectName>(4);
-
- try {
- // register two MBeans before wrapping
- server.registerMBean(new Wombat(),
- emitters[0] = new ObjectName("bush:type=Wombat,name=wom"));
- registered.add(emitters[0]);
-
- // we shield the second MBean in a StandardMBean so that it does
- // not appear as a NotificationEmitter.
- server.registerMBean(
- new StandardMBean(new Wombat(), WombatMBean.class),
- shielded[0] = new ObjectName("bush:type=Wombat,name=womshield"));
- registered.add(shielded[0]);
-
- final MBeanServer vserver = factory.wrapMBeanServer(server);
-
- // register two other MBeans after wrapping
- server.registerMBean(new Wombat(),
- emitters[1] = new ObjectName("bush:type=Wombat,name=bat"));
- registered.add(emitters[1]);
-
- // we shield the second MBean in a StandardMBean so that it does
- // not appear as a NotificationEmitter.
- server.registerMBean(
- new StandardMBean(new Wombat(), WombatMBean.class),
- shielded[1] = new ObjectName("bush:type=Wombat,name=batshield"));
- registered.add(shielded[1]);
-
- // Call test with this config - we have two wombats who broadcast
- // notifs (emitters) and two wombats who don't (shielded).
- test(vserver, emitters, shielded);
-
- System.out.println("*** Test passed for: " + factory);
- } finally {
- // Clean up the platform mbean server for the next test...
- for (ObjectName n : registered) {
- try {
- server.unregisterMBean(n);
- } catch (Exception x) {
- x.printStackTrace();
- }
- }
- }
- }
-
- /**
- * Perform the actual test.
- * @param vserver A virtual MBeanServerSupport implementation
- * @param emitters Names of NotificationBroadcaster MBeans
- * @param shielded Names of non NotificationBroadcaster MBeans
- * @throws java.lang.Exception
- */
- public static void test(MBeanServer vserver, ObjectName[] emitters,
- ObjectName[] shielded) throws Exception {
-
- // To catch exception in NotificationListener
- final List<Exception> fail = new CopyOnWriteArrayList<Exception>();
-
- // A queue of received notifications
- final BlockingQueue<Notification> notifs =
- new ArrayBlockingQueue<Notification>(50);
-
- // A notification listener that puts the notification it receives
- // in the queue.
- final NotificationListener handler = new NotificationListener() {
-
- public void handleNotification(Notification notification,
- Object handback) {
- try {
- notifs.put(notification);
- } catch (Exception x) {
- fail.add(x);
- }
- }
- };
-
- // A list of attribute names for which we might receive an
- // exception. If an exception is received when getting these
- // attributes - the test will not fail.
- final List<String> exceptions = Arrays.asList( new String[] {
- "UsageThresholdCount","UsageThreshold","UsageThresholdExceeded",
- "CollectionUsageThresholdCount","CollectionUsageThreshold",
- "CollectionUsageThresholdExceeded"
- });
-
- // This is just a sanity check. Get all attributes of all MBeans.
- for (ObjectName n : vserver.queryNames(null, null)) {
- final MBeanInfo m = vserver.getMBeanInfo(n);
- for (MBeanAttributeInfo mba : m.getAttributes()) {
- // System.out.println(n+":");
- Object val;
- try {
- val = vserver.getAttribute(n, mba.getName());
- } catch (Exception x) {
- // only accept exception for those attributes that
- // have a valid reason to fail...
- if (exceptions.contains(mba.getName())) val = x;
- else throw new Exception("Failed to get " +
- mba.getName() + " from " + n,x);
- }
- // System.out.println("\t "+mba.getName()+": "+ val);
- }
- }
-
- // The actual tests. Register for notifications with notif emitters
- for (ObjectName n : emitters) {
- vserver.addNotificationListener(n, handler, null, n);
- }
-
- // Trigger the emission of notifications, check that we received them.
- for (ObjectName n : emitters) {
- vserver.setAttribute(n,
- new Attribute("Caption","I am a new wombat!"));
- final Notification notif = notifs.poll(4, TimeUnit.SECONDS);
- if (!notif.getSource().equals(n))
- throw new Exception("Bad source for "+ notif);
- if (fail.size() > 0)
- throw new Exception("Failed to handle notif",fail.remove(0));
- }
-
- // Check that we didn't get more notifs than expected
- if (notifs.size() > 0)
- throw new Exception("Extra notifications in queue: "+notifs);
-
- // Check that if the MBean doesn't exist, we get InstanceNotFound.
- try {
- vserver.addNotificationListener(new ObjectName("toto:toto=toto"),
- handler, null, null);
- throw new Exception("toto:toto=toto doesn't throw INFE");
- } catch (InstanceNotFoundException x) {
- System.out.println("Received "+x+" as expected.");
- }
-
- // For those MBeans that shouldn't be NotificationEmitters, check that
- // we get IllegalArgumentException
- for (ObjectName n : shielded) {
- try {
- vserver.addNotificationListener(n, handler, null, n);
- } catch (RuntimeOperationsException x) {
- System.out.println("Received "+x+" as expected.");
- System.out.println("Cause is: "+x.getCause());
- if (!(x.getCause() instanceof IllegalArgumentException))
- throw new Exception("was expecting IllegalArgumentException cause. Got "+x.getCause(),x);
- }
- }
-
- // Sanity check. Remove our listeners.
- for (ObjectName n : emitters) {
- vserver.removeNotificationListener(n, handler, null, n);
- }
-
- // That's it.
- // Sanity check: we shouldn't have received any new notif.
- if (notifs.size() > 0)
- throw new Exception("Extra notifications in queue: "+notifs);
- // The NotifListener shouldn't have logged any new exception.
- if (fail.size() > 0)
- throw new Exception("Failed to handle notif",fail.remove(0));
- }
-
- public static void main(String[] args) throws Exception {
- // test with a regular MBeanServer (no VirtualMBeanServerSupport)
- final MBeanServerWrapperFactory identity =
- new MBeanServerWrapperFactory() {
- public MBeanServer wrapMBeanServer(MBeanServer wrapped) {
- return wrapped;
- }
- };
- test(identity);
- // test with no EventManager
- test(VirtualMBeanServerTest.factory);
- // test with VirtualEventManager
- test(VirtualMBeanServerTest2.factory);
- }
-}
--- a/jdk/test/javax/management/namespace/VirtualMBeanTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,409 +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.
- *
- * 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.
- */
-
-/*
- * @test VirtualMBeanTest.java
- * @bug 5108776 5072476
- * @summary Test that Virtual MBeans can be implemented and emit notifs.
- * @author Eamonn McManus
- */
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MalformedObjectNameException;
-import javax.management.Notification;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.RuntimeOperationsException;
-import javax.management.SendNotification;
-import javax.management.StandardEmitterMBean;
-import javax.management.StandardMBean;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.VirtualEventManager;
-import javax.management.namespace.MBeanServerSupport;
-import javax.management.timer.TimerMBean;
-
-// In this test, we check that the two main use case types for
-// MBeanServerSupport work correctly:
-// (1) as a special-purpose implementation of MBeanServer for a fixed number
-// of MBeans (e.g. for QueryNotificationFilter)
-// (2) as an MBeanServer supporting Virtual MBeans.
-// In each case we are particularly interested in the notification behaviour.
-// We check that the behaviour is correct when calling addNotificationListener
-// (a) for an MBean that does not exist; (b) for an MBean that does exist but
-// is not a NotificationEmitter; and (c) for an MBean that exists and is
-// a NotificationEmitter. We also check the degenerate and usual case
-// where the MBeanServerSupport subclass does not support notifications
-// at all.
-//
-// Each subclass will have an MBean called test:type=NotEmitter that
-// does not support addNotificationListener. If it also has MBeans called
-// test:type=Emitter,* then they are expected to support addNL. No subclass
-// will have any other MBeans, so in particular no subclass will have
-// test:type=Nonexistent.
-//
-public class VirtualMBeanTest {
- static final ObjectName
- nonExistentName, notEmitterName, emitterName1, emitterName2;
- static {
- try {
- nonExistentName = new ObjectName("test:type=NonExistent");
- notEmitterName = new ObjectName("test:type=NotEmitter");
- emitterName1 = new ObjectName("test:type=Emitter,id=1");
- emitterName2 = new ObjectName("test:type=Emitter,id=2");
- } catch (MalformedObjectNameException e) {
- throw new AssertionError(e);
- }
- }
-
- static final StandardMBean.Options wrappedVisible = new StandardMBean.Options();
- static {
- wrappedVisible.setWrappedObjectVisible(true);
- }
-
- public static interface NothingMBean {}
- public static class Nothing implements NothingMBean {}
- public static class NothingNBS extends NotificationBroadcasterSupport
- implements NothingMBean {}
-
- // Class that has hardwired MBeans test:type=NotEmitter,
- // test:type=Broadcaster, and test:type=Emitter.
- private static class HardwiredMBS extends MBeanServerSupport
- implements SendNotification {
- private final DynamicMBean notEmitter =
- new StandardMBean(new Nothing(), NothingMBean.class, wrappedVisible);
- private final StandardEmitterMBean emitter1, emitter2;
- {
- NothingNBS nnbs1 = new NothingNBS();
- emitter1 = new StandardEmitterMBean(
- nnbs1, NothingMBean.class, wrappedVisible, nnbs1);
- NothingNBS nnbs2 = new NothingNBS();
- emitter2 = new StandardEmitterMBean(
- nnbs2, NothingMBean.class, wrappedVisible, nnbs2);
- }
-
- private final Map<ObjectName, DynamicMBean> map =
- new TreeMap<ObjectName, DynamicMBean>();
- {
- map.put(notEmitterName, notEmitter);
- map.put(emitterName1, emitter1);
- map.put(emitterName2, emitter2);
- }
-
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- DynamicMBean mbean = map.get(name);
- if (mbean != null)
- return mbean;
- else
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return map.keySet();
- }
-
- @Override
- public String toString() {
- return "Hardwired MBeanServerSupport";
- }
-
- public void sendNotification(Notification notification) {
- emitter1.sendNotification(notification);
- emitter2.sendNotification(notification);
- }
- }
-
- // Class that has the notEmitter MBean but not either of the others, so does
- // not support listeners.
- private static class VirtualMBSWithoutListeners
- extends MBeanServerSupport {
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (name.equals(notEmitterName)) {
- return new StandardMBean(
- new Nothing(), NothingMBean.class, wrappedVisible);
- } else
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return Collections.singleton(notEmitterName);
- }
-
- @Override
- public String toString() {
- return "Virtual MBeanServerSupport without listener support";
- }
- }
-
- // Class that has the notEmitter and emitter MBeans as Virtual MBeans, using
- // VirtualEventManager to handle listeners for the emitter MBean. We
- // implement the broadcaster MBean (which is a NotificationBroadcaster but
- // not a NotificationEmitter) even though it's very hard to imagine a real
- // use case where that would happen.
- private static class VirtualMBSWithListeners
- extends MBeanServerSupport implements SendNotification {
- private final VirtualEventManager vem = new VirtualEventManager();
-
- private static final List<ObjectName> names =
- Arrays.asList(notEmitterName, emitterName1, emitterName2);
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (names.contains(name)) {
- return new StandardMBean(
- new Nothing(), NothingMBean.class, wrappedVisible);
- } else
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- public NotificationEmitter getNotificationEmitterFor(
- ObjectName name) throws InstanceNotFoundException {
- if (name.equals(emitterName1) || name.equals(emitterName2))
- return vem.getNotificationEmitterFor(name);
- else if (name.equals(notEmitterName))
- return null;
- else
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return new TreeSet<ObjectName>(Arrays.asList(notEmitterName, emitterName2));
- }
-
- @Override
- public String toString() {
- return "Virtual MBeanServerSupport with listener support";
- }
-
- public void sendNotification(Notification notification) {
- vem.publish(emitterName1, notification);
- vem.publish(emitterName2, notification);
- }
- }
-
- private static final MBeanServer[] vmbsss = {
- new HardwiredMBS(),
- new VirtualMBSWithoutListeners(),
- new VirtualMBSWithListeners(),
- };
-
- public static void main(String[] args) throws Exception {
- Exception lastEx = null;
- for (MBeanServer vmbs : vmbsss) {
- String testName = "\"" + vmbs + "\"";
- System.out.println("===Test " + testName + "===");
- try {
- test(vmbs);
- } catch (Exception e) {
- System.out.println(
- "===Test " + testName + " failed with exception " + e);
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- e.printStackTrace(pw);
- pw.flush();
- String es = sw.toString();
- System.out.println("......" + es.replace("\n", "\n......"));
- lastEx = e;
- }
- }
- if (lastEx != null)
- throw lastEx;
- System.out.println("TEST PASSED");
- }
-
- private static class NothingListener implements NotificationListener {
- public void handleNotification(Notification notification,
- Object handback) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
- }
-
- private static class QueueListener implements NotificationListener {
- final BlockingQueue<Notification> queue =
- new ArrayBlockingQueue<Notification>(10);
-
- public void handleNotification(Notification notification,
- Object handback) {
- queue.add(notification);
- }
- }
-
- private static void test(MBeanServer vmbs) throws Exception {
- MBeanServer mmbs = MBeanServerFactory.newMBeanServer();
- ObjectName namespaceName = new ObjectName("test//:type=JMXNamespace");
- JMXNamespace namespace = new JMXNamespace(vmbs);
- mmbs.registerMBean(namespace, namespaceName);
- MBeanServer mbs = JMXNamespaces.narrowToNamespace(mmbs, "test");
-
- Set<ObjectName> names = mbs.queryNames(null, null);
- //names.remove(new ObjectName(":type=JMXNamespace"));
-
- // Make sure that notEmitterName exists according to query...
- System.out.println("Checking query");
- if (!names.contains(notEmitterName))
- throw new Exception("Bad query result: " + names);
-
- // ...and according to getMBeanInfo
- System.out.println("Checking getMBeanInfo(" + notEmitterName + ")");
- MBeanInfo mbi = mbs.getMBeanInfo(notEmitterName);
- if (mbi.getNotifications().length > 0)
- throw new Exception("notEmitter has NotificationInfo");
-
- // Make sure we get the right exception for getMBeanInfo on a
- // non-existent MBean
- System.out.println("Checking getMBeanInfo on a non-existent MBean");
- try {
- mbi = mbs.getMBeanInfo(nonExistentName);
- throw new Exception("getMBI succeeded but should not have");
- } catch (InstanceNotFoundException e) {
- }
-
- // Make sure we get the right exception for addNotificationListener on a
- // non-existent MBean
- System.out.println(
- "Checking addNotificationListener on a non-existent MBean");
- try {
- mbs.addNotificationListener(
- nonExistentName, new NothingListener(), null, null);
- throw new Exception("addNL succeeded but should not have");
- } catch (InstanceNotFoundException e) {
- }
-
- // Make sure we get the right exception for isInstanceOf on a
- // non-existent MBean
- System.out.println(
- "Checking isInstanceOf on a non-existent MBean");
- for (Class<?> c : new Class<?>[] {
- Object.class, NotificationBroadcaster.class, NotificationEmitter.class,
- }) {
- try {
- boolean is = mbs.isInstanceOf(nonExistentName, c.getName());
- throw new Exception(
- "isInstanceOf " + c.getName() +
- " succeeded but should not have");
- } catch (InstanceNotFoundException e) {
- }
- }
-
- // Make sure isInstanceOf works correctly for classes without special
- // treatment
- System.out.println(
- "Checking isInstanceOf on normal classes");
- for (ObjectName name : names) {
- boolean isNothing = mbs.isInstanceOf(name, NothingMBean.class.getName());
- if (!isNothing) {
- throw new Exception("isInstanceOf " + NothingMBean.class.getName() +
- " returned false, should be true");
- }
- boolean isTimer = mbs.isInstanceOf(name, TimerMBean.class.getName());
- if (isTimer) {
- throw new Exception("isInstanceOf " + TimerMBean.class.getName() +
- " returned true, should be false");
- }
- }
-
- // Make sure that addNL on notEmitterName gets the right exception
- System.out.println("Checking addNL on non-broadcaster");
- try {
- mbs.addNotificationListener(
- notEmitterName, new NothingListener(), null, null);
- throw new Exception("addNL succeeded but should not have");
- } catch (RuntimeOperationsException e) {
- if (!(e.getCause() instanceof IllegalArgumentException))
- throw new Exception("Wrong exception from addNL", e);
- }
-
- if (!(vmbs instanceof SendNotification)) {
- System.out.println("Not testing notifications for this implementation");
- return;
- }
-
- QueueListener qListener = new QueueListener();
-
- System.out.println("Testing addNL on emitters");
- mbs.addNotificationListener(emitterName1, qListener, null, null);
- mbs.addNotificationListener(emitterName2, qListener, null, null);
-
- System.out.println("Testing that listeners work");
- Notification notif = new Notification("notif.type", "source", 0L);
-
- ((SendNotification) vmbs).sendNotification(notif);
- testListeners(qListener, "notif.type", 2);
-
- System.out.println("Testing 2-arg removeNL on emitter1");
- mbs.removeNotificationListener(emitterName1, qListener);
-
- ((SendNotification) vmbs).sendNotification(notif);
- testListeners(qListener, "notif.type", 1);
-
- System.out.println("Testing 4-arg removeNL on emitter2");
- mbs.removeNotificationListener(emitterName2, qListener, null, null);
-
- ((SendNotification) vmbs).sendNotification(notif);
- testListeners(qListener, "notif.type", 0);
- }
-
- private static void testListeners(
- QueueListener qListener, String expectedNotifType, int expectedNotifs)
- throws Exception {
- for (int i = 1; i <= expectedNotifs; i++) {
- Notification rNotif = qListener.queue.poll(1, TimeUnit.SECONDS);
- if (rNotif == null)
- throw new Exception("Notification " + i + " never arrived");
- if (!rNotif.getType().equals(expectedNotifType))
- throw new Exception("Wrong type notif: " + rNotif.getType());
- }
- Notification xNotif = qListener.queue.poll(10, TimeUnit.MILLISECONDS);
- if (xNotif != null)
- throw new Exception("Extra notif: " + xNotif);
- }
-}
--- a/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +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.
- *
- * 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.
- */
-
-/*
- *
- * @test VirtualNamespaceQueryTest.java
- * @summary General VirtualNamespaceQueryTest test.
- * @author Daniel Fuchs
- * @bug 5072476
- * @run clean VirtualNamespaceQueryTest Wombat WombatMBean
- * NamespaceController NamespaceControllerMBean
- * JMXRemoteTargetNamespace
- * @compile -XDignore.symbol.file=true VirtualNamespaceQueryTest.java
- * Wombat.java WombatMBean.java
- * NamespaceController.java NamespaceControllerMBean.java
- * JMXRemoteTargetNamespace.java
- * @run main VirtualNamespaceQueryTest
- */
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.NotificationEmitter;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.MBeanServerSupport;
-
-/**
- *
- * @author dfuchs
- */
-public class VirtualNamespaceQueryTest {
- public static class WombatRepository extends MBeanServerSupport {
- final Wombat wombat;
- final StandardMBean mbean;
- final ObjectName wombatName;
-
- public WombatRepository(ObjectName wombatName) {
- try {
- wombat = new Wombat();
- mbean = wombat;
- this.wombatName = wombatName;
- wombat.preRegister(null,wombatName);
- } catch (Exception x) {
- throw new IllegalArgumentException(x);
- }
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (wombatName.equals(name)) return mbean;
- else throw new InstanceNotFoundException(String.valueOf(name));
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- final Set<ObjectName> res = Collections.singleton(wombatName);
- return res;
- }
-
- @Override
- public NotificationEmitter getNotificationEmitterFor(
- ObjectName name) throws InstanceNotFoundException {
- DynamicMBean mb = getDynamicMBeanFor(name);
- if (mb instanceof NotificationEmitter)
- return (NotificationEmitter)mb;
- return null;
- }
- }
- public static class WombatNamespace extends JMXNamespace {
- public WombatNamespace(ObjectName wombatName) {
- super(new WombatRepository(wombatName));
- }
- }
-
- public static void simpleTest() throws Exception {
- final MBeanServer server = MBeanServerFactory.newMBeanServer();
- final ObjectName wombatName = new ObjectName("burrow:type=Wombat");
- final JMXNamespace ns = new WombatNamespace(wombatName);
- server.registerMBean(ns, JMXNamespaces.getNamespaceObjectName("wombats"));
- final Set<ObjectName> dirs =
- server.queryNames(new ObjectName("wombats//*//:type=JMXNamespace"),
- wombatName);
- System.out.println("all dirs: "+dirs);
- if (dirs.size()>0)
- throw new RuntimeException("Unexpected ObjectNames returned: "+dirs);
-
- final ObjectInstance inst = NamespaceController.createInstance(server);
- final NamespaceControllerMBean controller =
- JMX.newMBeanProxy(server, inst.getObjectName(),
- NamespaceControllerMBean.class);
- final String[] dirNames = controller.findNamespaces(null,null,2);
- System.err.println(Arrays.toString(dirNames));
- }
-
- public static void main(String[] args) throws Exception {
- simpleTest();
- }
-}
--- a/jdk/test/javax/management/namespace/VirtualPropsTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 5108776 5072476
- * @summary Test the properties use case for Virtual MBeans that is documented
- * in MBeanServerSupport.
- * @author Eamonn McManus
- */
-
-import java.lang.management.ManagementFactory;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.Notification;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.VirtualEventManager;
-import javax.management.namespace.MBeanServerSupport;
-
-public class VirtualPropsTest {
- public static interface PropertyMBean {
- public String getValue();
- }
-
- public static class PropsMBS extends MBeanServerSupport {
- private static ObjectName newObjectName(String name) {
- try {
- return new ObjectName(name);
- } catch (MalformedObjectNameException e) {
- throw new AssertionError(e);
- }
- }
-
- public static class PropertyImpl implements PropertyMBean {
- private final String name;
-
- public PropertyImpl(String name) {
- this.name = name;
- }
-
- public String getValue() {
- return System.getProperty(name);
- }
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- ObjectName namePattern = newObjectName(
- "com.example:type=Property,name=\"*\"");
- if (!namePattern.apply(name))
- throw new InstanceNotFoundException(name);
-
- String propName = ObjectName.unquote(name.getKeyProperty("name"));
- if (System.getProperty(propName) == null)
- throw new InstanceNotFoundException(name);
- PropertyMBean propMBean = new PropertyImpl(propName);
- return new StandardMBean(propMBean, PropertyMBean.class, false);
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- Set<ObjectName> names = new TreeSet<ObjectName>();
- Properties props = System.getProperties();
- for (String propName : props.stringPropertyNames()) {
- ObjectName objectName = newObjectName(
- "com.example:type=Property,name=" +
- ObjectName.quote(propName));
- names.add(objectName);
- }
- return names;
- }
-
- private final VirtualEventManager vem = new VirtualEventManager();
-
- @Override
- public NotificationEmitter getNotificationEmitterFor(
- ObjectName name) throws InstanceNotFoundException {
- getDynamicMBeanFor(name); // check that the name is valid
- return vem.getNotificationEmitterFor(name);
- }
-
- public void propertyChanged(String name, String newValue) {
- ObjectName objectName = newObjectName(
- "com.example:type=Property,name=" + ObjectName.quote(name));
- Notification n = new Notification(
- "com.example.property.changed", objectName, 0L,
- "Property " + name + " changed");
- n.setUserData(newValue);
- vem.publish(objectName, n);
- }
- }
-
- static class QueueListener implements NotificationListener {
- BlockingQueue<Notification> q = new ArrayBlockingQueue<Notification>(10);
- public void handleNotification(Notification notification,
- Object handback) {
- q.add(notification);
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mmbs = ManagementFactory.getPlatformMBeanServer();
- String namespace = "props";
- PropsMBS pmbs = new PropsMBS();
- Object namespaceMBean = new JMXNamespace(pmbs);
- mmbs.registerMBean(namespaceMBean, new ObjectName(
- namespace + "//:type=JMXNamespace"));
- MBeanServer mbs = JMXNamespaces.narrowToNamespace(mmbs, namespace);
-
- Properties props = System.getProperties();
-
- int nprops = props.stringPropertyNames().size();
- if (nprops != mbs.getMBeanCount()) {
- throw new Exception(String.format("Properties: %d; MBeans: %d",
- nprops, mbs.getMBeanCount()));
- }
-
- for (String propName : props.stringPropertyNames()) {
- ObjectName propObjectName = new ObjectName(
- "com.example:type=Property,name=" + ObjectName.quote(propName));
- PropertyMBean propProx = JMX.newMBeanProxy(
- mbs, propObjectName, PropertyMBean.class);
- String propValue = propProx.getValue();
- String realPropValue = props.getProperty(propName);
- if (!realPropValue.equals(propValue)) {
- throw new Exception(String.format("Property %s: value is \"%s\"; " +
- "mbean says \"%s\"", propName, realPropValue, propValue));
- }
- }
-
- ObjectName fooPropObjectName =
- new ObjectName("com.example:type=Property,name=\"java.home\"");
- QueueListener ql = new QueueListener();
- mbs.addNotificationListener(fooPropObjectName, ql, null, null);
- pmbs.propertyChanged("java.home", "bar");
- Notification n = ql.q.poll(1, TimeUnit.SECONDS);
- if (n == null)
- throw new Exception("Notif didn't arrive");
- if (!"bar".equals(n.getUserData()))
- throw new Exception("Bad user data: " + n.getUserData());
-
- System.out.println("TEST PASSED");
- }
-}
--- a/jdk/test/javax/management/namespace/Wombat.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +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.
- *
- * 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.
- */
-
-import java.util.Random;
-import java.util.Set;
-import javax.management.AttributeChangeNotification;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-
-
-/**
- * Dynamic MBean based on StandardMBean
- * Class Wombat
- * Wombat Description
- * @author dfuchs
- */
-public class Wombat extends StandardMBean
- implements WombatMBean, NotificationEmitter, MBeanRegistration {
-
- /**
- * Attribute : Caption
- */
- private String caption = "I'm a wombat";
-
- private final long MAX_SEED = 36000;
- private final long seed;
- private final long period;
- private volatile int mood = 0;
-
- public int getMood() {
- final long degree = seed + (System.currentTimeMillis()/period)%MAX_SEED;
- final double angle = ((double)degree)/100;
- mood = (int)(100.0*Math.sin(angle));
- return mood;
- }
-
- public Wombat() throws NotCompliantMBeanException {
- this(WombatMBean.class);
- }
-
- public Wombat(Class<? extends WombatMBean> clazz)
- throws NotCompliantMBeanException {
- super(clazz);
- final Random r = new Random();
- seed = ((r.nextLong() % MAX_SEED) + MAX_SEED)%MAX_SEED;
- period = 200 + (((r.nextLong()%80)+80)%80)*10;
- }
-
- /**
- * Next are the methods to compute MBeanInfo.
- * You shouldn't update these methods.
- */
- @Override
- protected String getDescription(MBeanInfo info) {
- return "Wombats are strange beasts. You will find them down under " +
- "and in some computer programms.";
- }
-
- @Override
- protected String getDescription(MBeanAttributeInfo info) {
- String description = null;
- if (info.getName().equals("Caption")) {
- description = "A simple caption to describe a wombat";
- }
- if (info.getName().equals("Mood")) {
- description = "This Wombat's mood on a [-100,+100] scale."+
- " -100 means that this wombat is very angry.";
- }
- return description;
- }
-
- @Override
- protected String getDescription(MBeanOperationInfo op,
- MBeanParameterInfo param,
- int sequence) {
- return null;
- }
-
- @Override
- protected String getParameterName(MBeanOperationInfo op,
- MBeanParameterInfo param,
- int sequence) {
- return null;
- }
-
- @Override
- protected String getDescription(MBeanOperationInfo info) {
- String description = null;
- return description;
- }
-
- @Override
- public MBeanInfo getMBeanInfo() {
- MBeanInfo mbinfo = super.getMBeanInfo();
- return new MBeanInfo(mbinfo.getClassName(),
- mbinfo.getDescription(),
- mbinfo.getAttributes(),
- mbinfo.getConstructors(),
- mbinfo.getOperations(),
- getNotificationInfo());
- }
-
- /**
- * Get A simple caption to describe a wombat
- */
- public synchronized String getCaption() {
- return caption;
- }
-
- /**
- * Set A simple caption to describe a wombat
- */
- public void setCaption(String value) {
- final String oldValue;
- synchronized (this) {
- oldValue = caption;
- caption = value;
- }
- final AttributeChangeNotification notif =
- new AttributeChangeNotification(objectName,
- getNextSeqNumber(),
- System.currentTimeMillis(),
- "Caption changed","Caption",
- String.class.getName(),oldValue,value);
- broadcaster.sendNotification(notif);
- }
-
- /**
- * MBeanNotification support
- * You shouldn't update these methods
- */
- public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {
- broadcaster.addNotificationListener(listener, filter, handback);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return new MBeanNotificationInfo[] {
- new MBeanNotificationInfo(new String[] {
- AttributeChangeNotification.ATTRIBUTE_CHANGE},
- javax.management.AttributeChangeNotification.class.getName(),
- "Sent when the caption changes")
- };
- }
-
- public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(listener);
- }
-
- public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
- broadcaster.removeNotificationListener(listener, filter, handback);
- }
-
- private synchronized long getNextSeqNumber() {
- return seqNumber++;
- }
-
- private long seqNumber;
-
- private final NotificationBroadcasterSupport broadcaster = new NotificationBroadcasterSupport();
-
- /**
- * Allows the MBean to perform any operations it needs before being
- * registered in the MBean server. If the name of the MBean is not
- * specified, the MBean can provide a name for its registration. If
- * any exception is raised, the MBean will not be registered in the
- * MBean server.
- * @param server The MBean server in which the MBean will be registered.
- * @param name The object name of the MBean. This name is null if the
- * name parameter to one of the createMBean or registerMBean methods in
- * the MBeanServer interface is null. In that case, this method must
- * return a non-null ObjectName for the new MBean.
- * @return The name under which the MBean is to be registered. This value
- * must not be null. If the name parameter is not null, it will usually
- * but not necessarily be the returned value.
- * @throws Exception This exception will be caught by the MBean server and
- * re-thrown as an MBeanRegistrationException.
- */
- @Override
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- objectName = name;
- mbeanServer = server;
- return super.preRegister(server, name);
- }
-
- /**
- * Allows the MBean to perform any operations needed after having
- * been registered in the MBean server or after the registration has
- * failed.
- * @param registrationDone Indicates wether or not the MBean has been
- * successfully registered in the MBean server. The value false means
- * that the registration has failed.
- */
- @Override
- public void postRegister(Boolean registrationDone) {
- super.postRegister(registrationDone);
- }
-
- /**
- * Allows the MBean to perform any operations it needs before being
- * unregistered by the MBean server.
- * @throws Exception This exception will be caught by the MBean server and
- * re-thrown as an MBeanRegistrationException.
- */
- @Override
- public void preDeregister() throws Exception {
- super.preDeregister();
- }
-
- /**
- * Allows the MBean to perform any operations needed after having been
- * unregistered in the MBean server.
- */
- @Override
- public void postDeregister() {
- super.postDeregister();
- }
-
- public Set<ObjectName> listMatching(ObjectName pattern) {
- return mbeanServer.queryNames(pattern, null);
- }
-
- private MBeanServer mbeanServer;
-
- private ObjectName objectName;
-}
--- a/jdk/test/javax/management/namespace/WombatMBean.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.
- *
- * 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.
- */
-
-import java.util.Set;
-import javax.management.ObjectName;
-
-/**
- * Interface WombatMBean
- * Wombat Description
- * @author dfuchs
- */
-public interface WombatMBean
-{
- /**
- * This Wombat's mood on a [-100,+100] scale.
- * -100 means that this wombat is very angry.
- * @return The wombat's mood.
- */
- public int getMood();
-
- /**
- * Get A simple caption to describe a wombat
- */
- public String getCaption();
-
- /**
- * Set A simple caption to describe a wombat
- */
- public void setCaption(String value);
-
- /**
- * List matching MBeans in the same server.
- * @param pattern an ObjectName pattern or null.
- * @return A list of matching MBeans.
- */
- public Set<ObjectName> listMatching(ObjectName pattern);
-
-}
--- a/jdk/test/javax/management/namespace/namespace.policy Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-grant codebase "file:/-" {
- permission java.util.PropertyPermission "jmx.wait", "read";
- permission java.util.PropertyPermission "jmx.rmi.port", "read";
- permission java.net.SocketPermission "*", "accept,connect,resolve";
- permission java.security.SecurityPermission "*";
-
- // Attribute Caption: allow get everywhere
- // ==================
-
- // allow getAttribute(*:*,Caption) in all MBeanServers
- permission javax.management.MBeanPermission "#Caption", "getAttribute";
- // allow getAttribute(*:*,Caption) in all namespaces recursively.
- permission javax.management.namespace.JMXNamespacePermission "Caption",
- "getAttribute";
-
- // Attribute Mood: allow get only in MBeanServers named rmi*
- // ===============
-
- // allow to get attribute Mood of Wombat MBeans only in namespaces
- // whose name match rmi*, wherever they are.
- // for this we need two permissions:
- permission javax.management.namespace.JMXNamespacePermission
- "*::Mood[**//rmi*//wombat:*]",
- "getAttribute";
- permission javax.management.namespace.JMXNamespacePermission
- "*::Mood[rmi*//wombat:*]",
- "getAttribute";
-
- // allow to get attribute mood in any MBeanServer whose name starts with
- // rmi
- permission javax.management.MBeanPermission "rmi*::#Mood",
- "getAttribute";
-
- // Attribute UUID:
- // ===============
-
- // allow to get attribute "UUID" everywhere.
- permission javax.management.namespace.JMXNamespacePermission
- "*::UUID[*//**//:*]",
- "getAttribute";
- permission javax.management.MBeanPermission
- "#UUID[*//:*]",
- "getAttribute";
-
-
-
- // Let getMBeanInfo and queryNames through everywhere...
- //
- permission javax.management.namespace.JMXNamespacePermission "[]",
- "getMBeanInfo,queryNames";
- permission javax.management.MBeanPermission "*",
- "getMBeanInfo,queryNames";
-
- // special permission for all wombats:
- //
- permission javax.management.namespace.JMXNamespacePermission
- "[**//*:type=Wombat,*]",
- "getObjectInstance,isInstanceOf,queryMBeans";
- permission javax.management.MBeanPermission "[*:type=Wombat,*]",
- "getObjectInstance,isInstanceOf,queryMBeans";
-
- // allow JMXNamespace::getDefaultDomain
- permission javax.management.namespace.JMXNamespacePermission
- "*::DefaultDomain",
- "getAttribute";
-
- // These permissions are required to connect visualvm.
- //
- permission javax.management.MBeanPermission "default::[java.lang:*]",
- "getObjectInstance,isInstanceOf,getAttribute,getMBeanInfo,queryNames,queryMBeans";
- permission javax.management.MBeanPermission "root::",
- "isInstanceOf,queryNames,queryMBeans,getAttribute,getMBeanInfo,getObjectInstance,getDomains";
- permission javax.management.namespace.JMXNamespacePermission
- "[**//JMImplementation:type=MBeanServerDelegate]",
- "addNotificationListener,removeNotificationListener,isInstanceOf,queryNames,queryMBeans,getAttribute,getMBeanInfo,getObjectInstance";
- permission javax.management.MBeanPermission
- "javax.management.MBeanServerDelegate",
- "addNotificationListener,removeNotificationListener,isInstanceOf,queryNames,queryMBeans,getAttribute,getMBeanInfo,getObjectInstance";
-
- // Thread monitoring
- permission java.lang.management.ManagementPermission "monitor";
- permission javax.management.MBeanPermission "*::sun.management.*#*[java.lang:*]", "invoke";
-};
-
-
--- a/jdk/test/javax/management/notification/SupportClearTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright 2005 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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6336980
- * @summary test 2 new methods: isListenedTo() and clear()
- * @author Shanliang JIANG
- * @run clean SupportClearTest
- * @run build SupportClearTest
- * @run main SupportClearTest
- */
-
-import javax.management.*;
-
-public class SupportClearTest {
- private static boolean received = false;
-
- public static void main(String[] args) throws Exception {
- System.out.println(">>> test 2 new methods: isListenedTo() and clear().");
-
- final NotificationListener listener = new NotificationListener() {
- public void handleNotification(Notification n, Object hb) {
- received = true;
- }
- };
-
- final NotificationBroadcasterSupport broadcaster =
- new NotificationBroadcasterSupport();
-
- System.out.println(">>> testing the method \"isListenedTo\"...");
- if (broadcaster.isListenedTo()) {
- throw new RuntimeException(
- "Bad implementation of the method \"isListenedTo\"!");
- }
-
- broadcaster.addNotificationListener(listener, null, null);
-
- if (!broadcaster.isListenedTo()) {
- throw new RuntimeException(
- "Bad implementation of the method \"isListenedTo\"!");
- }
-
- System.out.println(">>> testing the method \"clear\"...");
- broadcaster.removeAllNotificationListeners();
- if (broadcaster.isListenedTo()) {
- throw new RuntimeException(
- "Bad implementation of the method \"clear\"!");
- }
-
- broadcaster.sendNotification(new Notification("", "", 1L));
-
- if (received) {
- throw new RuntimeException(
- "Bad implementation of the method \"clear\"!");
- }
-
- System.out.println(">>> PASSED!");
- }
-}
--- a/jdk/test/javax/management/openmbean/CompositeDataToMapTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6750472 6752563
- * @summary Test CompositeDataSupport.toMap.
- * @author Eamonn McManus
- * @run main/othervm -ea CompositeDataToMapTest
- */
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-
-public class CompositeDataToMapTest {
- private static class IdentityInvocationHandler implements InvocationHandler {
- private final Object wrapped;
-
- public IdentityInvocationHandler(Object wrapped) {
- this.wrapped = wrapped;
- }
-
- public Object invoke(Object proxy, Method m, Object[] args)
- throws Throwable {
- try {
- return m.invoke(wrapped, args);
- } catch (InvocationTargetException e) {
- throw e.getCause();
- }
- }
- }
-
- private static <T> T wrap(T x, Class<T> intf) {
- InvocationHandler ih = new IdentityInvocationHandler(x);
- return intf.cast(Proxy.newProxyInstance(
- intf.getClassLoader(), new Class<?>[] {intf}, ih));
- }
-
- public static void main(String[] args) throws Exception {
- if (!CompositeDataToMapTest.class.desiredAssertionStatus())
- throw new AssertionError("Must be run with -ea");
-
- CompositeType emptyCT = new CompositeType(
- "empty", "empty", new String[0], new String[0], new OpenType<?>[0]);
- CompositeData emptyCD = new CompositeDataSupport(
- emptyCT, Collections.<String, Object>emptyMap());
- assert CompositeDataSupport.toMap(emptyCD).isEmpty() :
- "Empty CD produces empty Map";
-
- CompositeData emptyCD2 = new CompositeDataSupport(
- emptyCT, new String[0], new Object[0]);
- assert emptyCD.equals(emptyCD2) : "Empty CD can be constructed two ways";
-
- CompositeType namedNumberCT = new CompositeType(
- "NamedNumber", "NamedNumber",
- new String[] {"name", "number"},
- new String[] {"name", "number"},
- new OpenType<?>[] {SimpleType.STRING, SimpleType.INTEGER});
- Map<String, Object> namedNumberMap = new HashMap<String, Object>();
- namedNumberMap.put("name", "Deich");
- namedNumberMap.put("number", 10);
- CompositeData namedNumberCD = new CompositeDataSupport(
- namedNumberCT, namedNumberMap);
- assert CompositeDataSupport.toMap(namedNumberCD).equals(namedNumberMap) :
- "Map survives passage through CompositeData";
-
- namedNumberCD = wrap(namedNumberCD, CompositeData.class);
- assert CompositeDataSupport.toMap(namedNumberCD).equals(namedNumberMap) :
- "Map survives passage through wrapped CompositeData";
-
- namedNumberMap = CompositeDataSupport.toMap(namedNumberCD);
- namedNumberMap.put("name", "Ceathar");
- namedNumberMap.put("number", 4);
- namedNumberCD = new CompositeDataSupport(namedNumberCT, namedNumberMap);
- assert CompositeDataSupport.toMap(namedNumberCD).equals(namedNumberMap) :
- "Modified Map survives passage through CompositeData";
-
- try {
- namedNumberMap = CompositeDataSupport.toMap(null);
- assert false : "Null toMap arg provokes exception";
- } catch (Exception e) {
- assert e instanceof IllegalArgumentException :
- "Exception for null toMap arg is IllegalArgumentException";
- }
- }
-}
--- a/jdk/test/javax/management/openmbean/GenericMBeanExceptionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6456269
- * @summary Test GenericMBeanException
- * @author Eamonn McManus
- */
-
-import java.beans.ConstructorProperties;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import javax.management.GenericMBeanException;
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.MXBeanMapping;
-import javax.management.openmbean.MXBeanMappingFactory;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class GenericMBeanExceptionTest {
- private static volatile String failure = null;
-
- public static interface ThrowerMBean {
- public void throwGeneric() throws GenericMBeanException;
- public void throwGeneric(Throwable cause) throws GenericMBeanException;
- public void throwGeneric(String errorCode) throws GenericMBeanException;
- public void throwGeneric(CompositeData userData) throws GenericMBeanException;
- public void throwGeneric(String errorCode, CompositeData userData)
- throws GenericMBeanException;
- public void throwGeneric(String errorCode, CompositeData userData, Throwable cause)
- throws GenericMBeanException;
- }
-
- public static class Thrower implements ThrowerMBean {
-
- public void throwGeneric() throws GenericMBeanException {
- throw new GenericMBeanException("Message");
- }
-
- public void throwGeneric(Throwable cause) throws GenericMBeanException {
- throw new GenericMBeanException("Message", cause);
- }
-
- public void throwGeneric(String errorCode) throws GenericMBeanException {
- throw new GenericMBeanException("Message", errorCode, null);
- }
-
- public void throwGeneric(CompositeData userData) throws GenericMBeanException {
- throw new GenericMBeanException("Message", null, userData);
- }
-
- public void throwGeneric(String errorCode, CompositeData userData)
- throws GenericMBeanException {
- throw new GenericMBeanException("Message", errorCode, userData);
- }
-
- public void throwGeneric(String errorCode, CompositeData userData,
- Throwable cause) throws GenericMBeanException {
- throw new GenericMBeanException("Message", errorCode, userData, cause);
- }
- }
-
- public static class Payload {
- private final int severity;
- private final String subsystem;
-
- @ConstructorProperties({"severity", "subsystem"})
- public Payload(int severity, String subsystem) {
- this.severity = severity;
- this.subsystem = subsystem;
- }
-
- public int getSeverity() {
- return severity;
- }
-
- public String getSubsystem() {
- return subsystem;
- }
-
- @Override
- public boolean equals(Object x) {
- if (!(x instanceof Payload))
- return false;
- Payload p = (Payload) x;
- return (severity == p.severity &&
- (subsystem == null) ?
- p.subsystem == null : subsystem.equals(p.subsystem));
- }
-
- @Override
- public int hashCode() {
- return severity + subsystem.hashCode();
- }
-
- @Override
- public String toString() {
- return "Payload{severity: " + severity + ", subsystem: " + subsystem + "}";
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = new ObjectName("test:type=Thrower");
- Thrower thrower = new Thrower();
- mbs.registerMBean(thrower, name);
-
- if (args.length > 0) {
- System.out.println("Attach client now, hit return to exit");
- System.in.read();
- return;
- }
-
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
- url, null, mbs);
- cs.start();
- JMXServiceURL addr = cs.getAddress();
-
- JMXConnector cc = JMXConnectorFactory.connect(addr);
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
-
- ThrowerMBean throwerProxy = JMX.newMBeanProxy(mbsc, name, ThrowerMBean.class);
-
- Payload payload = new Payload(5, "modular modulizer");
- MXBeanMapping payloadMapping = MXBeanMappingFactory.DEFAULT.mappingForType(
- Payload.class, MXBeanMappingFactory.DEFAULT);
- CompositeData userData = (CompositeData)
- payloadMapping.toOpenValue(payload);
- Throwable cause = new IllegalArgumentException("Badness");
-
- Object[][] testCases = {
- {},
- {"code1"},
- {userData},
- {"code2", userData},
- {(String) null, userData},
- {"code99", userData, cause},
- {(String) null, userData, cause},
- };
-
- for (Object[] testCase : testCases) {
- System.out.println("Test case: " + testCaseString(testCase));
-
- // Find which ThrowerMBean method it corresponds to
- Method testMethod = null;
-search:
- for (Method m : ThrowerMBean.class.getMethods()) {
- Class<?>[] paramTypes = m.getParameterTypes();
- if (paramTypes.length != testCase.length)
- continue;
- for (int i = 0; i < paramTypes.length; i++) {
- if (testCase[i] != null && !paramTypes[i].isInstance(testCase[i]))
- continue search;
- }
- testMethod = m;
- }
-
- if (testMethod == null) {
- throw new Exception("TEST ERROR: no method corresponds: " +
- testCaseString(testCase));
- }
-
- try {
- testMethod.invoke(throwerProxy, testCase);
- fail("Did not throw exception", testCase);
- continue;
- } catch (InvocationTargetException e) {
- Throwable iteCause = e.getCause();
- if (!(iteCause instanceof GenericMBeanException)) {
- iteCause.printStackTrace(System.out);
- fail("Threw wrong exception " + iteCause, testCase);
- continue;
- }
- GenericMBeanException ge = (GenericMBeanException) iteCause;
- if (!ge.getMessage().equals("Message"))
- fail("Wrong message: " + ge.getMessage(), testCase);
-
- Class<?>[] paramTypes = testMethod.getParameterTypes();
- for (int i = 0; i < paramTypes.length; i++) {
- Class<?> paramType = paramTypes[i];
-
- if (paramType == Throwable.class) { // cause
- Throwable geCause = ge.getCause();
- if (!(geCause instanceof IllegalArgumentException))
- fail("Wrong cause: " + geCause, testCase);
- else if (!geCause.getMessage().equals("Badness"))
- fail("Wrong cause message: " + geCause.getMessage(), testCase);
- } else if (paramType == String.class) { // errorCode
- String errorCode = ge.getErrorCode();
- String expectedErrorCode =
- (testCase[i] == null) ? "" : (String) testCase[i];
- if (!expectedErrorCode.equals(errorCode))
- fail("Wrong error code: " + ge.getErrorCode(), testCase);
- } else if (paramType == CompositeData.class) { // userData
- CompositeData userData2 = ge.getUserData();
- if (!userData.equals(userData2))
- fail("Wrong userData: " + userData2, testCase);
- Payload payload2 = (Payload) payloadMapping.fromOpenValue(userData2);
- if (!payload.equals(payload2))
- fail("Wrong payload: " + payload2, testCase);
- } else
- throw new Exception("TEST ERROR: unknown parameter type: " + paramType);
- }
- }
- }
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static String testCaseString(Object[] testCase) {
- StringBuilder sb = new StringBuilder("[");
- String sep = "";
- for (Object x : testCase) {
- sb.append(sep);
- String xs = (x instanceof CompositeData) ?
- compositeDataString((CompositeData) x) : String.valueOf(x);
- sb.append(xs);
- sep = ", ";
- }
- sb.append("]");
- return sb.toString();
- }
-
- private static String compositeDataString(CompositeData cd) {
- StringBuilder sb = new StringBuilder("CompositeData{");
- CompositeType ct = cd.getCompositeType();
- String sep = "";
- for (String key : ct.keySet()) {
- sb.append(sep).append(key).append(": ").append(cd.get(key));
- sep = ", ";
- }
- sb.append("}");
- return sb.toString();
- }
-
- private static void fail(String why, Object[] testCase) {
- fail(testCaseString(testCase) + ": " + why);
- }
-
- private static void fail(String why) {
- failure = why;
- System.out.println("FAIL: " + why);
- }
-}
--- a/jdk/test/javax/management/query/QueryDottedAttrTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +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.
- *
- * 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.
- */
-
-/*
- * @test QueryDottedAttrTest
- * @bug 6602310
- * @summary Test that Query.attr can understand a.b etc.
- * @author Eamonn McManus
- */
-
-import java.beans.ConstructorProperties;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Collections;
-import java.util.Set;
-import javax.management.AttributeNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.Query;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.StandardMBean;
-
-public class QueryDottedAttrTest {
- public static class Complex {
- private final double re, im;
-
- @ConstructorProperties({"real", "imaginary"})
- public Complex(double re, double im) {
- this.re = re;
- this.im = im;
- }
-
- public double getRe() {
- return re;
- }
-
- public double getIm() {
- return im;
- }
- }
-
- public static interface Intf {
- Complex getComplex();
- int[] getIntArray();
- String[] getStringArray();
- }
-
- public static class Impl implements Intf {
- public Complex getComplex() {
- return new Complex(1.0, 1.0);
- }
-
- public int[] getIntArray() {
- return new int[] {1, 2, 3};
- }
-
- public String[] getStringArray() {
- return new String[] {"one", "two", "three"};
- }
- }
-
- public static interface TestMBean extends Intf {}
-
- public static class Test extends Impl implements TestMBean {}
-
- public static interface TestMXBean extends Intf {}
-
- public static class TestMX extends Impl implements TestMXBean {}
-
- public static class AttrWithDot extends StandardMBean {
- public <T> AttrWithDot(Object impl, Class<T> intf) {
- super(intf.cast(impl), intf, (intf == TestMXBean.class));
- }
-
- public Object getAttribute(String attribute)
- throws AttributeNotFoundException, MBeanException, ReflectionException {
- if (attribute.equals("Complex.re"))
- return 2.0;
- else
- return super.getAttribute(attribute);
- }
- }
-
- private static final boolean[] booleans = {false, true};
-
- private static final QueryExp[] alwaysTrueQueries = {
- Query.eq(Query.attr("IntArray.length"), Query.value(3)),
- Query.eq(Query.attr("StringArray.length"), Query.value(3)),
- Query.eq(Query.attr("Complex.im"), Query.value(1.0)),
- };
-
- private static final QueryExp[] alwaysFalseQueries = {
- Query.eq(Query.attr("IntArray.length"), Query.value("3")),
- Query.eq(Query.attr("IntArray.length"), Query.value(2)),
- Query.eq(Query.attr("Complex.im"), Query.value(-1.0)),
- Query.eq(Query.attr("Complex.xxx"), Query.value(0)),
- };
-
- private static final QueryExp[] attrWithDotTrueQueries = {
- Query.eq(Query.attr("Complex.re"), Query.value(2.0)),
- };
-
- private static final QueryExp[] attrWithDotFalseQueries = {
- Query.eq(Query.attr("Complex.re"), Query.value(1.0)),
- };
-
- private static String failure;
-
- public static void main(String[] args) throws Exception {
- ObjectName name = new ObjectName("a:b=c");
- for (boolean attrWithDot : booleans) {
- for (boolean mx : booleans) {
- String what =
- (mx ? "MXBean" : "Standard MBean") +
- (attrWithDot ? " having attribute with dot in its name" : "");
- System.out.println("Testing " + what);
- Class<?> intf = mx ? TestMXBean.class : TestMBean.class;
- Object impl = mx ? new TestMX() : new Test();
- if (attrWithDot)
- impl = new AttrWithDot(impl, intf);
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- mbs.registerMBean(impl, name);
- boolean ismx = "true".equals(
- mbs.getMBeanInfo(name).getDescriptor().getFieldValue("mxbean"));
- if (mx != ismx)
- fail("MBean should " + (mx ? "" : "not ") + "be MXBean");
- test(mbs, name, alwaysTrueQueries, true);
- test(mbs, name, alwaysFalseQueries, false);
- test(mbs, name, attrWithDotTrueQueries, attrWithDot);
- test(mbs, name, attrWithDotFalseQueries, !attrWithDot);
- }
- }
- if (failure != null)
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static void test(
- MBeanServer mbs, ObjectName name, QueryExp[] queries, boolean expect)
- throws Exception {
- for (QueryExp query : queries) {
- // Serialize and deserialize the query to ensure that its
- // serialization is correct
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(query);
- oout.close();
- ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
- ObjectInputStream oin = new ObjectInputStream(bin);
- query = (QueryExp) oin.readObject();
- Set<ObjectName> names = mbs.queryNames(null, query);
- if (names.isEmpty()) {
- if (expect)
- fail("Query is false but should be true: " + query);
- } else if (names.equals(Collections.singleton(name))) {
- if (!expect)
- fail("Query is true but should be false: " + query);
- } else {
- fail("Query returned unexpected set: " + names);
- }
- }
- }
-
- private static void fail(String msg) {
- failure = msg;
- System.out.println("..." + msg);
- }
-}
--- a/jdk/test/javax/management/query/QueryExpStringTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/query/QueryExpStringTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -31,10 +31,6 @@
* @run main QueryExpStringTest
*/
-// This test is mostly obsolete, since we now have Query.fromString.
-// The test includes its own parser, from which Query.fromString was derived.
-// The parsers are not identical and the one here is no longer maintained.
-
import java.util.*;
import javax.management.*;
--- a/jdk/test/javax/management/query/QueryNotifFilterTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +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.
- *
- * 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.
- */
-
-/*
- * @test QueryNotifFilterTest
- * @bug 6610917
- * @summary Test the QueryNotificationFilter class
- * @author Eamonn McManus
- */
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.AttributeChangeNotification;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.Query;
-import javax.management.QueryEval;
-import javax.management.QueryExp;
-import javax.management.QueryNotificationFilter;
-
-public class QueryNotifFilterTest {
- private static class Case {
- final Notification notif;
- final QueryExp query;
- final boolean expect;
- final Class<? extends Notification> notifClass;
- Case(Notification notif, String query, boolean expect) {
- this(notif, query, notif.getClass(), expect);
- }
- Case(Notification notif, String query,
- Class<? extends Notification> notifClass, boolean expect) {
- this(notif, Query.fromString(query), notifClass, expect);
- }
- Case(Notification notif, QueryExp query, boolean expect) {
- this(notif, query, notif.getClass(), expect);
- }
- Case(Notification notif, QueryExp query,
- Class<? extends Notification> notifClass, boolean expect) {
- this.notif = notif;
- this.query = query;
- this.expect = expect;
- this.notifClass = notifClass;
- }
- }
-
- /* In principle users can create their own implementations of QueryExp
- * and use them with QueryNotificationFilter. If they do so, then
- * they can call any MBeanServer method. Not all of those methods
- * will work with the special MBeanServer we concoct to analyze a
- * Notification, but some will, including some that are not called
- * by the standard queries. So we check each of those cases too.
- */
- private static class ExoticCase {
- final Notification trueNotif;
- final Notification falseNotif;
- final QueryExp query;
- ExoticCase(Notification trueNotif, Notification falseNotif, QueryExp query) {
- this.trueNotif = trueNotif;
- this.falseNotif = falseNotif;
- this.query = query;
- }
- }
-
- private static abstract class ExoticQuery
- extends QueryEval implements QueryExp {
- private final String queryString;
- ExoticQuery(String queryString) {
- this.queryString = queryString;
- }
- abstract boolean apply(MBeanServer mbs, ObjectName name) throws Exception;
- //@Override - doesn't override in JDK5
- public boolean apply(ObjectName name) {
- try {
- return apply(getMBeanServer(), name);
- } catch (Exception e) {
- e.printStackTrace(System.out);
- return false;
- }
- }
- @Override
- public String toString() {
- return queryString;
- }
- }
-
- private static ObjectName makeObjectName(String s) {
- try {
- return new ObjectName(s);
- } catch (MalformedObjectNameException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static class CustomNotification extends Notification {
- public CustomNotification(String type, Object source, long seqNo) {
- super(type, source, seqNo);
- }
-
- public String getName() {
- return "claude";
- }
-
- public boolean isInteresting() {
- return true;
- }
- }
-
- private static final Notification simpleNotif =
- new Notification("mytype", "source", 0L);
- private static final Notification attrChangeNotif =
- new AttributeChangeNotification(
- "x", 0L, 0L, "msg", "AttrName", "int", 2, 3);
- private static final ObjectName testObjectName = makeObjectName("a:b=c");
- private static final Notification sourcedNotif =
- new Notification("mytype", testObjectName, 0L);
- private static final Notification customNotif =
- new CustomNotification("mytype", testObjectName, 0L);
-
- private static final Case[] testCases = {
- new Case(simpleNotif, "Type = 'mytype'", true),
- new Case(simpleNotif, "Type = 'mytype'",
- Notification.class, true),
- new Case(simpleNotif, "Type = 'mytype'",
- AttributeChangeNotification.class, false),
- new Case(simpleNotif, "Type != 'mytype'", false),
- new Case(simpleNotif, "Type = 'somethingelse'", false),
- new Case(attrChangeNotif, "AttributeName = 'AttrName'", true),
- new Case(attrChangeNotif,
- "instanceof 'javax.management.AttributeChangeNotification'",
- true),
- new Case(attrChangeNotif,
- "instanceof 'javax.management.Notification'",
- true),
- new Case(attrChangeNotif,
- "instanceof 'javax.management.relation.MBeanServerNotification'",
- false),
- new Case(attrChangeNotif,
- "class = 'javax.management.AttributeChangeNotification'",
- true),
- new Case(attrChangeNotif,
- "javax.management.AttributeChangeNotification#AttributeName = 'AttrName'",
- true),
- new Case(sourcedNotif,
- testObjectName,
- true),
- new Case(sourcedNotif,
- makeObjectName("a*:b=*"),
- true),
- new Case(sourcedNotif,
- makeObjectName("a*:c=*"),
- false),
- new Case(customNotif, "Name = 'claude'", true),
- new Case(customNotif, "Name = 'tiddly'", false),
- new Case(customNotif, "Interesting = true", true),
- new Case(customNotif, "Interesting = false", false),
- };
-
- private static final ExoticCase[] exoticTestCases = {
- new ExoticCase(
- simpleNotif, new Notification("notmytype", "source", 0L),
- new ExoticQuery("getAttributes") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- List<Attribute> attrs = mbs.getAttributes(
- name, new String[] {"Type", "Source"}).asList();
- return (attrs.get(0).equals(new Attribute("Type", "mytype")) &&
- attrs.get(1).equals(new Attribute("Source", "source")));
- }
- }),
- new ExoticCase(
- new Notification("mytype", "source", 0L) {},
- simpleNotif,
- new ExoticQuery("getClassLoaderFor") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- return (mbs.getClassLoaderFor(name) ==
- this.getClass().getClassLoader());
- }
- }),
- new ExoticCase(
- sourcedNotif, simpleNotif,
- new ExoticQuery("getDomains") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- return Arrays.equals(mbs.getDomains(),
- new String[] {testObjectName.getDomain()});
- }
- }),
- new ExoticCase(
- simpleNotif, attrChangeNotif,
- new ExoticQuery("getMBeanInfo") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- MBeanInfo mbi = mbs.getMBeanInfo(name);
- // If we ever add a constructor to Notification then
- // we will have to change the 4 below.
- if (mbi.getOperations().length > 0 ||
- mbi.getConstructors().length != 4 ||
- mbi.getNotifications().length > 0)
- return false;
- Set<String> expect = new HashSet<String>(
- Arrays.asList(
- "Class", "Message", "SequenceNumber", "Source",
- "TimeStamp", "Type", "UserData"));
- Set<String> actual = new HashSet<String>();
- for (MBeanAttributeInfo mbai : mbi.getAttributes())
- actual.add(mbai.getName());
- return actual.equals(expect);
- }
- }),
- new ExoticCase(
- simpleNotif, attrChangeNotif,
- new ExoticQuery("getObjectInstance") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- ObjectInstance oi = mbs.getObjectInstance(name);
- return oi.getClassName().equals(Notification.class.getName());
- }
- }),
- new ExoticCase(
- sourcedNotif, simpleNotif,
- new ExoticQuery("queryNames") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- Set<ObjectName> names = mbs.queryNames(null,
- Query.eq(Query.attr("Type"), Query.value("mytype")));
- return names.equals(Collections.singleton(testObjectName));
- }
- }),
- new ExoticCase(
- sourcedNotif, simpleNotif,
- new ExoticQuery("queryMBeans") {
- boolean apply(MBeanServer mbs, ObjectName name)
- throws Exception {
- Set<ObjectInstance> insts = mbs.queryMBeans(null,
- Query.eq(Query.attr("Type"), Query.value("mytype")));
- if (insts.size() != 1)
- return false;
- ObjectInstance inst = insts.iterator().next();
- return (inst.getObjectName().equals(testObjectName) &&
- inst.getClassName().equals(Notification.class.getName()));
- }
- }),
- };
-
- private static enum Test {
- QUERY_EXP("query"), STRING("string"), STRING_PLUS_CLASS("string with class");
- private final String name;
- Test(String name) {
- this.name = name;
- }
- @Override
- public String toString() {
- return name;
- }
- }
-
- public static void main(String[] args) throws Exception {
- boolean allok = true;
- for (Case testCase : testCases) {
- for (Test test : Test.values()) {
- QueryNotificationFilter nf;
- String queryString;
- switch (test) {
- case QUERY_EXP: {
- QueryExp inst = Query.isInstanceOf(
- Query.value(testCase.notifClass.getName()));
- QueryExp and = Query.and(inst, testCase.query);
- queryString = Query.toString(and);
- nf = new QueryNotificationFilter(and);
- break;
- }
- case STRING: {
- String s = "instanceof '" + testCase.notifClass.getName() + "'";
- queryString = s + " and " + Query.toString(testCase.query);
- nf = new QueryNotificationFilter(queryString);
- break;
- }
- case STRING_PLUS_CLASS:
- queryString = null;
- nf = new QueryNotificationFilter(
- testCase.notifClass, Query.toString(testCase.query));
- break;
- default:
- throw new AssertionError();
- }
- boolean accept = nf.isNotificationEnabled(testCase.notif);
- if (queryString != null) {
- queryString = Query.toString(Query.fromString(queryString));
- if (!queryString.equals(Query.toString(nf.getQuery()))) {
- System.out.println("FAIL: query string mismatch: expected " +
- "\"" + queryString + "\", got \"" +
- Query.toString(nf.getQuery()));
- allok = false;
- }
- }
- boolean ok = (accept == testCase.expect);
- System.out.println((ok ? "pass" : "FAIL") + ": " +
- testCase.query + " (" + test + ")");
- allok &= ok;
- }
- }
- for (ExoticCase testCase : exoticTestCases) {
- NotificationFilter nf = new QueryNotificationFilter(testCase.query);
- for (boolean expect : new boolean[] {true, false}) {
- Notification n = expect ? testCase.trueNotif : testCase.falseNotif;
- boolean accept = nf.isNotificationEnabled(n);
- boolean ok = (accept == expect);
- System.out.println((ok ? "pass" : "FAIL") + ": " +
- testCase.query + ": " + n);
- allok &= ok;
- }
- }
- if (!allok)
- throw new Exception("TEST FAILED");
- }
-}
--- a/jdk/test/javax/management/query/QueryParseTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,781 +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.
- *
- * 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.
- */
-
-/*
- * @test QueryParseTest
- * @bug 6602310 6604768
- * @summary Test Query.fromString and Query.toString.
- * @author Eamonn McManus
- */
-
-import java.util.Collections;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.Query;
-import javax.management.QueryExp;
-
-public class QueryParseTest {
- // In this table, each string constant corresponds to a test case.
- // The objects following the string up to the next string are MBeans.
- // Each MBean must implement ExpectedValue to return true or false
- // according as it should return that value for the query parsed
- // from the given string. The test will parse the string into a
- // a query and verify that the MBeans return the expected value
- // for that query. Then it will convert the query back into a string
- // and into a second query, and check that the MBeans return the
- // expected value for that query too. The reason we need to do all
- // this is that the spec talks about "equivalent queries", and gives
- // the implementation wide scope to rearrange queries. So we cannot
- // just compare string values.
- //
- // We could also write an implementation-dependent test that knew what
- // the strings look like, and that would have to be changed if the
- // implementation changed. But the approach here is cleaner.
- //
- // To simplify the creation of MBeans, most use the expectTrue or
- // expectFalse methods. The parameters of these methods end up in
- // attributes called "A", "B", "C", etc.
- private static final Object[] queryTests = {
- // RELATIONS
-
- "A < B",
- expectTrue(1, 2), expectTrue(1.0, 2.0), expectTrue("one", "two"),
- expectTrue(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY),
- expectFalse(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY),
- expectFalse(1, 1), expectFalse(1.0, 1.0), expectFalse("one", "one"),
- expectFalse(2, 1), expectFalse(2.0, 1.0), expectFalse("two", "one"),
- expectFalse(Double.NaN, Double.NaN),
-
- "One = two",
- expectTrueOneTwo(1, 1), expectTrueOneTwo(1.0, 1.0),
- expectFalseOneTwo(1, 2), expectFalseOneTwo(2, 1),
-
- "A <= B",
- expectTrue(1, 1), expectTrue(1, 2), expectTrue("one", "one"),
- expectTrue("one", "two"),
- expectFalse(2, 1), expectFalse("two", "one"),
- expectFalse(Double.NaN, Double.NaN),
-
- "A >= B",
- expectTrue(1, 1), expectTrue(2, 1), expectTrue("two", "one"),
- expectFalse(1, 2), expectFalse("one", "two"),
-
- "A > B",
- expectTrue(2, 1), expectTrue("two", "one"),
- expectFalse(2, 2), expectFalse(1, 2), expectFalse(1.0, 2.0),
- expectFalse("one", "two"),
-
- "A <> B",
- expectTrue(1, 2), expectTrue("foo", "bar"),
- expectFalse(1, 1), expectFalse("foo", "foo"),
-
- "A != B",
- expectTrue(1, 2), expectTrue("foo", "bar"),
- expectFalse(1, 1), expectFalse("foo", "foo"),
-
- // PARENTHESES
-
- "(((A))) = (B)",
- expectTrue(1, 1), expectFalse(1, 2),
-
- "(A = B)",
- expectTrue(1, 1), expectFalse(1, 2),
-
- "(((A = (B))))",
- expectTrue(1, 1), expectFalse(1, 2),
-
- // INTEGER LITERALS
-
- "A = 1234567890123456789",
- expectTrue(1234567890123456789L), expectFalse(123456789L),
-
- "A = +1234567890123456789",
- expectTrue(1234567890123456789L), expectFalse(123456789L),
-
- "A = -1234567890123456789",
- expectTrue(-1234567890123456789L), expectFalse(-123456789L),
-
-
- "A = + 1234567890123456789",
- expectTrue(1234567890123456789L), expectFalse(123456789L),
-
- "A = - 1234567890123456789",
- expectTrue(-1234567890123456789L), expectFalse(-123456789L),
-
- "A = " + Long.MAX_VALUE,
- expectTrue(Long.MAX_VALUE), expectFalse(Long.MIN_VALUE),
-
- "A = " + Long.MIN_VALUE,
- expectTrue(Long.MIN_VALUE), expectFalse(Long.MAX_VALUE),
-
- // DOUBLE LITERALS
-
- "A = 0.0",
- expectTrue(0.0), expectFalse(1.0),
-
- "A = 0.0e23",
- expectTrue(0.0), expectFalse(1.0),
-
- "A = 1.2e3",
- expectTrue(1.2e3), expectFalse(1.2),
-
- "A = +1.2",
- expectTrue(1.2), expectFalse(-1.2),
-
- "A = 1.2e+3",
- expectTrue(1.2e3), expectFalse(1.2),
-
- "A = 1.2e-3",
- expectTrue(1.2e-3), expectFalse(1.2),
-
- "A = 1.2E3",
- expectTrue(1.2e3), expectFalse(1.2),
-
- "A = -1.2e3",
- expectTrue(-1.2e3), expectFalse(1.2),
-
- "A = " + Double.MAX_VALUE,
- expectTrue(Double.MAX_VALUE), expectFalse(Double.MIN_VALUE),
-
- "A = " + -Double.MAX_VALUE,
- expectTrue(-Double.MAX_VALUE), expectFalse(-Double.MIN_VALUE),
-
- "A = " + Double.MIN_VALUE,
- expectTrue(Double.MIN_VALUE), expectFalse(Double.MAX_VALUE),
-
- "A = " + -Double.MIN_VALUE,
- expectTrue(-Double.MIN_VALUE), expectFalse(-Double.MAX_VALUE),
-
- Query.toString( // A = Infinity -> A = (1.0/0.0)
- Query.eq(Query.attr("A"), Query.value(Double.POSITIVE_INFINITY))),
- expectTrue(Double.POSITIVE_INFINITY),
- expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
-
- Query.toString( // A = -Infinity -> A = (-1.0/0.0)
- Query.eq(Query.attr("A"), Query.value(Double.NEGATIVE_INFINITY))),
- expectTrue(Double.NEGATIVE_INFINITY),
- expectFalse(0.0), expectFalse(Double.POSITIVE_INFINITY),
-
- Query.toString( // A < NaN -> A < (0.0/0.0)
- Query.lt(Query.attr("A"), Query.value(Double.NaN))),
- expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
- expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN),
-
- Query.toString( // A >= NaN -> A < (0.0/0.0)
- Query.geq(Query.attr("A"), Query.value(Double.NaN))),
- expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
- expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN),
-
- // STRING LITERALS
-
- "A = 'blim'",
- expectTrue("blim"), expectFalse("blam"),
-
- "A = 'can''t'",
- expectTrue("can't"), expectFalse("cant"), expectFalse("can''t"),
-
- "A = '''blim'''",
- expectTrue("'blim'"), expectFalse("'blam'"),
-
- "A = ''",
- expectTrue(""), expectFalse((Object) null),
-
- // BOOLEAN LITERALS
-
- "A = true",
- expectTrue(true), expectFalse(false), expectFalse((Object) null),
-
- "A = TRUE",
- expectTrue(true), expectFalse(false),
-
- "A = TrUe",
- expectTrue(true), expectFalse(false),
-
- "A = false",
- expectTrue(false), expectFalse(true),
-
- "A = fAlSe",
- expectTrue(false), expectFalse(true),
-
- "A = \"true\"", // An attribute called "true"
- expectFalse(true), expectFalse(false), expectFalse("\"true\""),
- newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.2}, true),
- newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.3}, false),
-
- "A = \"False\"",
- expectFalse(true), expectFalse(false), expectFalse("\"False\""),
- newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.2}, true),
- newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.3}, false),
-
- // ARITHMETIC
-
- "A + B = 10",
- expectTrue(4, 6), expectFalse(3, 8),
-
- "A + B = 'blim'",
- expectTrue("bl", "im"), expectFalse("bl", "am"),
-
- "A - B = 10",
- expectTrue(16, 6), expectFalse(16, 3),
-
- "A * B = 10",
- expectTrue(2, 5), expectFalse(3, 3),
-
- "A / B = 10",
- expectTrue(70, 7), expectTrue(70.0, 7), expectFalse(70.01, 7),
-
- "A + B + C = 10",
- expectTrue(2, 3, 5), expectFalse(2, 4, 8),
-
- "A+B+C=10",
- expectTrue(2, 3, 5), expectFalse(2, 4, 8),
-
- "A + B + C + D = 10",
- expectTrue(1, 2, 3, 4), expectFalse(2, 3, 4, 5),
-
- "A + (B + C) = 10",
- expectTrue(2, 3, 5), expectFalse(2, 4, 8),
-
- // It is not correct to rearrange A + (B + C) as A + B + C
- // (which means (A + B) + C), because of overflow.
- // In particular Query.toString must not do this.
- "A + (B + C) = " + Double.MAX_VALUE, // ensure no false associativity
- expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE),
- expectFalse(-Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE),
-
- "A * (B * C) < " + Double.MAX_VALUE, // same test for multiplication
- expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE),
- expectFalse(Double.MIN_VALUE, Double.MAX_VALUE, Double.MAX_VALUE),
-
- "A * B + C = 10",
- expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
-
- "A*B+C=10",
- expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
-
- "(A * B) + C = 10",
- expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
-
- "A + B * C = 10",
- expectTrue(1, 3, 3), expectTrue(2, 2, 4), expectFalse(1, 2, 3),
-
- "A - B * C = 10",
- expectTrue(16, 2, 3), expectFalse(15, 2, 2),
-
- "A + B / C = 10",
- expectTrue(5, 15, 3), expectFalse(5, 16, 4),
-
- "A - B / C = 10",
- expectTrue(16, 12, 2), expectFalse(15, 10, 3),
-
- "A * (B + C) = 10",
- expectTrue(2, 2, 3), expectFalse(1, 2, 3),
-
- "A / (B + C) = 10",
- expectTrue(70, 4, 3), expectFalse(70, 3, 5),
-
- "A * (B - C) = 10",
- expectTrue(2, 8, 3), expectFalse(2, 3, 8),
-
- "A / (B - C) = 10",
- expectTrue(70, 11, 4), expectFalse(70, 4, 11),
-
- "A / B / C = 10",
- expectTrue(140, 2, 7), expectFalse(100, 5, 5),
-
- "A / (B / C) = 10",
- expectTrue(70, 14, 2), expectFalse(70, 10, 7),
-
- // LOGIC
-
- "A = B or C = D",
- expectTrue(1, 1, 2, 3), expectTrue(1, 2, 3, 3), expectTrue(1, 1, 2, 2),
- expectFalse(1, 2, 3, 4), expectFalse("!", "!!", "?", "??"),
-
- "A = B and C = D",
- expectTrue(1, 1, 2, 2),
- expectFalse(1, 1, 2, 3), expectFalse(1, 2, 3, 3),
-
- "A = 1 and B = 2 and C = 3",
- expectTrue(1, 2, 3), expectFalse(1, 2, 4),
-
- "A = 1 or B = 2 or C = 3",
- expectTrue(1, 2, 3), expectTrue(1, 0, 0), expectTrue(0, 0, 3),
- expectFalse(2, 3, 4),
-
- // grouped as (a and b) or (c and d)
- "A = 1 AND B = 2 OR C = 3 AND D = 4",
- expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4),
- expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1),
-
- "(A = 1 AND B = 2) OR (C = 3 AND D = 4)",
- expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4),
- expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1),
-
- "(A = 1 or B = 2) AND (C = 3 or C = 4)",
- expectTrue(1, 1, 3, 3), expectTrue(2, 2, 4, 4), expectTrue(1, 2, 3, 4),
- expectFalse(1, 2, 1, 2), expectFalse(3, 4, 3, 4),
-
- // LIKE
-
- "A like 'b*m'",
- expectTrue("blim"), expectTrue("bm"),
- expectFalse(""), expectFalse("blimmo"), expectFalse("mmm"),
-
- "A not like 'b*m'",
- expectFalse("blim"), expectFalse("bm"),
- expectTrue(""), expectTrue("blimmo"), expectTrue("mmm"),
-
- "A like 'b?m'",
- expectTrue("bim"), expectFalse("blim"),
-
- "A like '*can''t*'",
- expectTrue("can't"),
- expectTrue("I'm sorry Dave, I'm afraid I can't do that"),
- expectFalse("cant"), expectFalse("can''t"),
-
- "A like '\\**\\*'",
- expectTrue("*blim*"), expectTrue("**"),
- expectFalse("blim"), expectFalse("*asdf"), expectFalse("asdf*"),
-
- "A LIKE '%*_?'",
- expectTrue("%blim_?"), expectTrue("%_?"), expectTrue("%blim_!"),
- expectFalse("blim"), expectFalse("blim_"),
- expectFalse("_%"), expectFalse("??"), expectFalse(""), expectFalse("?"),
-
- Query.toString(
- Query.initialSubString(Query.attr("A"), Query.value("*?%_"))),
- expectTrue("*?%_tiddly"), expectTrue("*?%_"),
- expectFalse("?%_tiddly"), expectFalse("*!%_"), expectFalse("*??_"),
- expectFalse("*?%!"), expectFalse("*?%!tiddly"),
-
- Query.toString(
- Query.finalSubString(Query.attr("A"), Query.value("*?%_"))),
- expectTrue("tiddly*?%_"), expectTrue("*?%_"),
- expectFalse("tiddly?%_"), expectFalse("*!%_"), expectFalse("*??_"),
- expectFalse("*?%!"), expectFalse("tiddly*?%!"),
-
- // BETWEEN
-
- "A between B and C",
- expectTrue(1, 1, 2), expectTrue(2, 1, 2), expectTrue(2, 1, 3),
- expectFalse(3, 1, 2), expectFalse(0, 1, 2), expectFalse(2, 3, 1),
- expectTrue(1.0, 0.0, 2.0), expectFalse(2.0, 0.0, 1.0),
- expectTrue(0.0, 0.0, 0.0), expectTrue(1.0, 0.0, 1.0),
- expectTrue(1.0, 0.0, Double.POSITIVE_INFINITY),
- expectFalse(1.0, Double.NEGATIVE_INFINITY, 0.0),
- expectFalse(false, false, true), expectFalse(true, false, true),
- expectTrue("jim", "fred", "sheila"), expectFalse("fred", "jim", "sheila"),
-
- "A between B and C and 1+2=3",
- expectTrue(2, 1, 3), expectFalse(2, 3, 1),
-
- "A not between B and C",
- expectTrue(1, 2, 3), expectFalse(2, 1, 3),
-
- // IN
-
- "A in (1, 2, 3)",
- expectTrue(1), expectTrue(2), expectTrue(3),
- expectFalse(0), expectFalse(4),
-
- "A in (1)",
- expectTrue(1), expectFalse(0),
-
- "A in (1.2, 3.4)",
- expectTrue(1.2), expectTrue(3.4), expectFalse(0.0),
-
- "A in ('foo', 'bar')",
- expectTrue("foo"), expectTrue("bar"), expectFalse("baz"),
-
- "A in ('foo', 'bar') and 'bl'+'im'='blim'",
- expectTrue("foo"), expectTrue("bar"), expectFalse("baz"),
-
- "A in (B, C, D)", // requires fix for CR 6604768
- expectTrue(1, 1, 2, 3), expectFalse(1, 2, 3, 4),
-
- "A not in (B, C, D)",
- expectTrue(1, 2, 3, 4), expectFalse(1, 1, 2, 3),
-
- // QUOTING
-
- "\"LIKE\" = 1 and \"NOT\" = 2 and \"INSTANCEOF\" = 3 and " +
- "\"TRUE\" = 4 and \"FALSE\" = 5",
- newTester(
- new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"},
- new Object[] {1, 2, 3, 4, 5},
- true),
- newTester(
- new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"},
- new Object[] {5, 4, 3, 2, 1},
- false),
-
- "\"\"\"woo\"\"\" = 5",
- newTester(new String[] {"\"woo\""}, new Object[] {5}, true),
- newTester(new String[] {"\"woo\""}, new Object[] {4}, false),
- expectFalse(),
-
- // INSTANCEOF
-
- "instanceof '" + Tester.class.getName() + "'",
- expectTrue(),
-
- "instanceof '" + String.class.getName() + "'",
- expectFalse(),
-
- // LIKE OBJECTNAME
-
- // The test MBean is registered as a:b=c
- "like 'a:b=c'", expectTrue(),
- "like 'a:*'", expectTrue(),
- "like '*:b=c'", expectTrue(),
- "like 'a:b=*'", expectTrue(),
- "like 'a:b=?'", expectTrue(),
- "like 'd:b=c'", expectFalse(),
- "like 'a:b=??*'", expectFalse(),
- "like 'a:b=\"can''t\"'", expectFalse(),
-
- // QUALIFIED ATTRIBUTE
-
- Tester.class.getName() + "#A = 5",
- expectTrue(5), expectFalse(4),
-
- Tester.class.getName() + " # A = 5",
- expectTrue(5), expectFalse(4),
-
- Tester.class.getSuperclass().getName() + "#A = 5",
- expectFalse(5),
-
- DynamicMBean.class.getName() + "#A = 5",
- expectFalse(5),
-
- Tester.class.getName() + "#A = 5",
- new Tester(new String[] {"A"}, new Object[] {5}, false) {},
- // note the little {} at the end which means this is a subclass
- // and therefore QualifiedAttributeValue should return false.
-
- MBeanServerDelegate.class.getName() + "#SpecificationName LIKE '*'",
- new Wrapped(new MBeanServerDelegate(), true),
- new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
-
- // DOTTED ATTRIBUTE
-
- "A.canonicalName = '" +
- MBeanServerDelegate.DELEGATE_NAME.getCanonicalName() + "'",
- expectTrue(MBeanServerDelegate.DELEGATE_NAME),
- expectFalse(ObjectName.WILDCARD),
-
- "A.class.name = 'java.lang.String'",
- expectTrue("blim"), expectFalse(95), expectFalse((Object) null),
-
- "A.canonicalName like 'JMImpl*:*'",
- expectTrue(MBeanServerDelegate.DELEGATE_NAME),
- expectFalse(ObjectName.WILDCARD),
-
- "A.true = 'blim'",
- new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true),
- new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false),
-
- "\"A.true\" = 'blim'",
- new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true),
- new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false),
-
- MBeanServerDelegate.class.getName() +
- "#SpecificationName.class.name = 'java.lang.String'",
- new Wrapped(new MBeanServerDelegate(), true),
- new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
-
- MBeanServerDelegate.class.getName() +
- " # SpecificationName.class.name = 'java.lang.String'",
- new Wrapped(new MBeanServerDelegate(), true),
- new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
-
- // CLASS
-
- "class = '" + Tester.class.getName() + "'",
- expectTrue(),
- new Wrapped(new MBeanServerDelegate(), false),
-
- "Class = '" + Tester.class.getName() + "'",
- expectTrue(),
- new Wrapped(new MBeanServerDelegate(), false),
- };
-
- private static final String[] incorrectQueries = {
- "", " ", "25", "()", "(a = b", "a = b)", "a.3 = 5",
- "a = " + Long.MAX_VALUE + "0",
- "a = " + Double.MAX_VALUE + "0",
- "a = " + Double.MIN_VALUE + "0",
- "a = 12a5", "a = 12e5e5", "a = 12.23.34",
- "a = 'can't'", "a = 'unterminated", "a = 'asdf''",
- "a = \"oops", "a = \"oops\"\"",
- "a like 5", "true or false",
- "a ! b", "? = 3", "a = @", "a##b",
- "a between b , c", "a between and c",
- "a in b, c", "a in 23", "a in (2, 3", "a in (2, 3x)",
- "a like \"foo\"", "a like b", "a like 23",
- "like \"foo\"", "like b", "like 23", "like 'a:b'",
- "5 like 'a'", "'a' like '*'",
- "a not= b", "a not = b", "a not b", "a not b c",
- "a = +b", "a = +'b'", "a = +true", "a = -b", "a = -'b'",
- "a#5 = b", "a#'b' = c",
- "a instanceof b", "a instanceof 17", "a instanceof",
- // "a like 'oops\\'", "a like '[oops'",
- // We don't check the above because Query.match doesn't. If LIKE
- // rejected bad patterns then there would be some QueryExp values
- // that could not be converted to a string and back.
-
- // Check that -Long.MIN_VALUE is an illegal constant. This is one more
- // than Long.MAX_VALUE and, like the Java language, we only allow it
- // if it is the operand of unary minus.
- "a = " + Long.toString(Long.MIN_VALUE).substring(1),
- };
-
- public static void main(String[] args) throws Exception {
- int nexti;
- String failed = null;
-
- System.out.println("TESTING CORRECT QUERY STRINGS");
- for (int i = 0; i < queryTests.length; i = nexti) {
- for (nexti = i + 1; nexti < queryTests.length; nexti++) {
- if (queryTests[nexti] instanceof String)
- break;
- }
- if (!(queryTests[i] instanceof String))
- throw new Exception("Test bug: should be string: " + queryTests[i]);
-
- String qs = (String) queryTests[i];
- System.out.println("Test: " + qs);
-
- QueryExp qe = Query.fromString(qs);
- String qes = Query.toString(qe);
- System.out.println("...parses to: " + qes);
- final QueryExp[] queries;
- if (qes.equals(qs))
- queries = new QueryExp[] {qe};
- else {
- QueryExp qe2 = Query.fromString(qes);
- String qes2 = Query.toString(qe2);
- System.out.println("...which parses to: " + qes2);
- if (qes.equals(qes2))
- queries = new QueryExp[] {qe};
- else
- queries = new QueryExp[] {qe, qe2};
- }
-
- for (int j = i + 1; j < nexti; j++) {
- Object mbean;
- if (queryTests[j] instanceof Wrapped)
- mbean = ((Wrapped) queryTests[j]).mbean();
- else
- mbean = queryTests[j];
- boolean expect = ((ExpectedValue) queryTests[j]).expectedValue();
- for (QueryExp qet : queries) {
- boolean actual = runQuery(qet, mbean);
- boolean ok = (expect == actual);
- System.out.println(
- "..." + mbean + " -> " + actual +
- (ok ? " (OK)" : " ####INCORRECT####"));
- if (!ok)
- failed = qs;
- }
- }
- }
-
- System.out.println();
- System.out.println("TESTING INCORRECT QUERY STRINGS");
- for (String s : incorrectQueries) {
- try {
- QueryExp qe = Query.fromString(s);
- System.out.println("###DID NOT GET ERROR:### \"" + s + "\"");
- failed = s;
- } catch (IllegalArgumentException e) {
- String es = (e.getClass() == IllegalArgumentException.class) ?
- e.getMessage() : e.toString();
- System.out.println("OK: exception for \"" + s + "\": " + es);
- }
- }
-
- if (failed == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: Last failure: " + failed);
- }
-
- private static boolean runQuery(QueryExp qe, Object mbean)
- throws Exception {
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- ObjectName name = new ObjectName("a:b=c");
- mbs.registerMBean(mbean, name);
- Set<ObjectName> names = mbs.queryNames(new ObjectName("a:*"), qe);
- if (names.isEmpty())
- return false;
- if (names.equals(Collections.singleton(name)))
- return true;
- throw new Exception("Unexpected query result set: " + names);
- }
-
- private static interface ExpectedValue {
- public boolean expectedValue();
- }
-
- private static class Wrapped implements ExpectedValue {
- private final Object mbean;
- private final boolean expect;
-
- Wrapped(Object mbean, boolean expect) {
- this.mbean = mbean;
- this.expect = expect;
- }
-
- Object mbean() {
- return mbean;
- }
-
- public boolean expectedValue() {
- return expect;
- }
- }
-
- private static class Tester implements DynamicMBean, ExpectedValue {
- private final AttributeList attributes;
- private final boolean expectedValue;
-
- Tester(AttributeList attributes, boolean expectedValue) {
- this.attributes = attributes;
- this.expectedValue = expectedValue;
- }
-
- Tester(String[] names, Object[] values, boolean expectedValue) {
- this(makeAttributeList(names, values), expectedValue);
- }
-
- private static AttributeList makeAttributeList(
- String[] names, Object[] values) {
- if (names.length != values.length)
- throw new Error("Test bug: names and values different length");
- AttributeList list = new AttributeList();
- for (int i = 0; i < names.length; i++)
- list.add(new Attribute(names[i], values[i]));
- return list;
- }
-
- public Object getAttribute(String attribute)
- throws AttributeNotFoundException {
- for (Attribute a : attributes.asList()) {
- if (a.getName().equals(attribute))
- return a.getValue();
- }
- throw new AttributeNotFoundException(attribute);
- }
-
- public void setAttribute(Attribute attribute) {
- throw new UnsupportedOperationException();
- }
-
- public AttributeList getAttributes(String[] attributes) {
- AttributeList list = new AttributeList();
- for (String attribute : attributes) {
- try {
- list.add(new Attribute(attribute, getAttribute(attribute)));
- } catch (AttributeNotFoundException e) {
- // OK: ignore, per semantics of getAttributes
- }
- }
- return list;
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- throw new UnsupportedOperationException();
- }
-
- public Object invoke(String actionName, Object[] params, String[] signature) {
- throw new UnsupportedOperationException();
- }
-
- public MBeanInfo getMBeanInfo() {
- MBeanAttributeInfo mbais[] = new MBeanAttributeInfo[attributes.size()];
- for (int i = 0; i < mbais.length; i++) {
- Attribute attr = attributes.asList().get(i);
- String name = attr.getName();
- Object value = attr.getValue();
- String type =
- ((value == null) ? new Object() : value).getClass().getName();
- mbais[i] = new MBeanAttributeInfo(
- name, type, name, true, false, false);
- }
- return new MBeanInfo(
- getClass().getName(), "descr", mbais, null, null, null);
- }
-
- public boolean expectedValue() {
- return expectedValue;
- }
-
- @Override
- public String toString() {
- return attributes.toString();
- }
- }
-
- // Method rather than field, to avoid circular init dependencies
- private static String[] abcd() {
- return new String[] {"A", "B", "C", "D"};
- }
-
- private static String[] onetwo() {
- return new String[] {"One", "two"};
- }
-
- private static Object expectTrue(Object... attrs) {
- return newTester(abcd(), attrs, true);
- }
-
- private static Object expectFalse(Object... attrs) {
- return newTester(abcd(), attrs, false);
- }
-
- private static Object expectTrueOneTwo(Object... attrs) {
- return newTester(onetwo(), attrs, true);
- }
-
- private static Object expectFalseOneTwo(Object... attrs) {
- return newTester(onetwo(), attrs, false);
- }
-
- private static Object newTester(String[] names, Object[] attrs, boolean expect) {
- AttributeList list = new AttributeList();
- for (int i = 0; i < attrs.length; i++)
- list.add(new Attribute(names[i], attrs[i]));
- return new Tester(list, expect);
- }
-}
--- a/jdk/test/javax/management/remote/mandatory/connection/CloseServerTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/connection/CloseServerTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003 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
@@ -31,16 +31,11 @@
* @run main CloseServerTest
*/
-import com.sun.jmx.remote.util.EnvHelp;
import java.net.MalformedURLException;
+import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rmi.RMIConnectorServer;
public class CloseServerTest {
private static final String[] protocols = {"rmi", "iiop", "jmxmp"};
@@ -136,54 +131,40 @@
server.stop();
- List<Map<String, String>> envs = Arrays.asList(
- Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false"),
- Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "true"));
-
- for (Map<String, String> env : envs) {
- System.out.println(
- ">>>>>>>> " + RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE +
- " = " + env.get(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE));
+ // with a client listener, but close the server first
+ System.out.println(">>> Open, start a server, create a client, add a listener, close the server then the client.");
+ server = JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs);
+ server.start();
- // with a client listener, but close the server first
- System.out.println(">>> Open, start a server, create a client, " +
- "add a listener, close the server then the client.");
- server = JMXConnectorServerFactory.newJMXConnectorServer(u, env, mbs);
- server.start();
+ addr = server.getAddress();
+ client = JMXConnectorFactory.newJMXConnector(addr, null);
+ client.connect(null);
- addr = server.getAddress();
- client = JMXConnectorFactory.newJMXConnector(addr, null);
- client.connect(null);
+ mserver = client.getMBeanServerConnection();
+ mserver.addNotificationListener(delegateName, dummyListener, null, null);
- mserver = client.getMBeanServerConnection();
- mserver.addNotificationListener(delegateName, dummyListener, null, null);
+ server.stop();
- server.stop();
-
- try {
- client.close();
- } catch (Exception e) {
- // ok, it is because the server has been closed.
- }
+ try {
+ client.close();
+ } catch (Exception e) {
+ // ok, it is because the server has been closed.
+ }
- // with a client listener, but close the client first
- System.out.println(">>> Open, start a server, create a client, " +
- "add a listener, close the client then the server.");
- server = JMXConnectorServerFactory.newJMXConnectorServer(u, env, mbs);
- server.start();
+ // with a client listener, but close the client first
+ System.out.println(">>> Open, start a server, create a client, add a listener, close the client then the server.");
+ server = JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs);
+ server.start();
- addr = server.getAddress();
- client = JMXConnectorFactory.newJMXConnector(addr, null);
- client.connect(null);
+ addr = server.getAddress();
+ client = JMXConnectorFactory.newJMXConnector(addr, null);
+ client.connect(null);
- mserver = client.getMBeanServerConnection();
- mserver.addNotificationListener(delegateName, dummyListener, null, null);
+ mserver = client.getMBeanServerConnection();
+ mserver.addNotificationListener(delegateName, dummyListener, null, null);
- client.close();
- server.stop();
- }
+ client.close();
+ server.stop();
} catch (MalformedURLException e) {
System.out.println(">>> Skipping unsupported URL " + u);
return true;
--- a/jdk/test/javax/management/remote/mandatory/connection/DeadLockTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/connection/DeadLockTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2004 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
@@ -37,7 +37,6 @@
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rmi.RMIConnectorServer;
public class DeadLockTest {
private static final String[] protocols = {"rmi", "iiop", "jmxmp"};
@@ -73,9 +72,6 @@
// disable the client ping
env.put("jmx.remote.x.client.connection.check.period", "0");
- // ensure we are not internally using the Event Service on the server
- env.put(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
-
try {
u = new JMXServiceURL(proto, null, 0);
server = JMXConnectorServerFactory.newJMXConnectorServer(u, env, mbs);
--- a/jdk/test/javax/management/remote/mandatory/connection/IdleTimeoutTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/connection/IdleTimeoutTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2006 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
@@ -50,8 +50,6 @@
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import com.sun.jmx.remote.util.EnvHelp;
-import java.util.Collections;
-import javax.management.remote.rmi.RMIConnectorServer;
public class IdleTimeoutTest {
public static void main(String[] args) throws Exception {
@@ -90,13 +88,8 @@
private static long getIdleTimeout(MBeanServer mbs, JMXServiceURL url)
throws Exception {
- // If the connector server is using the Event Service, then connections
- // never time out. This is by design.
- Map<String, String> env =
- Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
server.start();
try {
url = server.getAddress();
@@ -171,7 +164,6 @@
Map idleMap = new HashMap();
idleMap.put(EnvHelp.SERVER_CONNECTION_TIMEOUT, new Long(timeout));
- idleMap.put(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
JMXConnectorServer server =
JMXConnectorServerFactory.newJMXConnectorServer(url,idleMap,mbs);
--- a/jdk/test/javax/management/remote/mandatory/connection/RMIExitTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIExitTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -35,8 +35,6 @@
import java.net.MalformedURLException;
import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
@@ -49,7 +47,6 @@
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.rmi.RMIConnectorServer;
/**
* VM shutdown hook. Test that the hook is called less than 5 secs
@@ -85,15 +82,12 @@
public static void main(String[] args) {
System.out.println("Start test");
Runtime.getRuntime().addShutdownHook(new TimeChecker());
- test(false);
- test(true);
+ test();
exitStartTime = System.currentTimeMillis();
System.out.println("End test");
}
- private static void test(boolean eventService) {
- System.out.println(
- "---testing with" + (eventService ? "" : "out") + " Event Service");
+ private static void test() {
try {
JMXServiceURL u = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer server;
@@ -112,11 +106,8 @@
}
};
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
server = JMXConnectorServerFactory.newJMXConnectorServer(u,
- env,
+ null,
mbs);
server.start();
--- a/jdk/test/javax/management/remote/mandatory/connection/ReconnectTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/connection/ReconnectTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2004 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
@@ -33,10 +33,10 @@
import java.util.*;
import java.net.MalformedURLException;
+import java.io.IOException;
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rmi.RMIConnectorServer;
public class ReconnectTest {
private static final String[] protocols = {"rmi", "iiop", "jmxmp"};
@@ -48,7 +48,6 @@
String timeout = "1000";
env.put("jmx.remote.x.server.connection.timeout", timeout);
env.put("jmx.remote.x.client.connection.check.period", timeout);
- env.put(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
}
public static void main(String[] args) throws Exception {
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/CloseConnectionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-/*
- * Copyright 2003-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.
- *
- * 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.
- */
-
-
-/*
- * @test
- * @bug 6332907
- * @summary test the ability for connector server to close individual connections
- * @author Shanliang JIANG
- * @run clean CloseConnectionTest
- * @run build CloseConnectionTest
- * @run main CloseConnectionTest
- */
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.management.MBeanServerFactory;
-
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-
-public class CloseConnectionTest {
-
- public static void main(String[] args) throws Exception {
- System.out.println(">>> Test the ability for connector server to close " +
- "individual connections.");
-
- final String[] protos = new String[]{"rmi", "iiop", "jmxmp"};
- for (String p : protos) {
- System.out.println("\n>>> Testing the protocol " + p);
- JMXServiceURL addr = new JMXServiceURL(p, null, 0);
- System.out.println(">>> Creating a JMXConnectorServer on " + addr);
- JMXConnectorServer server = null;
- try {
- server = JMXConnectorServerFactory.newJMXConnectorServer(addr,
- null,
- MBeanServerFactory.createMBeanServer());
- } catch (Exception e) {
- System.out.println(">>> Skip the protocol: " + p);
- continue;
- }
-
- test1(server);
- test2(server);
-
- server.stop();
- }
-
- System.out.println(">>> Bye bye!");
- }
-
- private static void test1(JMXConnectorServer server) throws Exception {
- try {
- server.closeConnection("toto");
- // not started, known id
- throw new RuntimeException("An IllegalArgumentException is not thrown.");
- } catch (IllegalStateException e) {
- System.out.println(">>> Test1: Got expected IllegalStateException: " + e);
- }
-
- server.start();
- System.out.println(">>>Test1 Started the server on " + server.getAddress());
-
- try {
- server.closeConnection("toto");
- throw new RuntimeException("An IllegalArgumentException is not thrown.");
- } catch (IllegalArgumentException e) {
- System.out.println(">> Test1: Got expected IllegalArgumentException: " + e);
- }
-
- MyListener listener = new MyListener();
- server.addNotificationListener(listener, null, null);
-
- System.out.println(">>> Test1: Connecting a client to the server ...");
- final JMXConnector conn = JMXConnectorFactory.connect(server.getAddress());
- conn.getMBeanServerConnection().getDefaultDomain();
- final String id1 = conn.getConnectionId();
-
- listener.wait(JMXConnectionNotification.OPENED, timeout);
-
- System.out.println(">>> Test1: Closing the connection: " + conn.getConnectionId());
- server.closeConnection(id1);
- listener.wait(JMXConnectionNotification.CLOSED, timeout);
-
- System.out.println(">>> Test1: Using again the connector whose connection " +
- "should be closed by the server, it should reconnect " +
- "automatically to the server and get a new connection id.");
- conn.getMBeanServerConnection().getDefaultDomain();
- final String id2 = conn.getConnectionId();
- listener.wait(JMXConnectionNotification.OPENED, timeout);
-
- if (id1.equals(id2)) {
- throw new RuntimeException("Failed, the first client connection is not closed.");
- }
-
- System.out.println(">>> Test1: Greate, we get a new connection id " + id2 +
- ", the first one is closed as expected.");
-
- System.out.println(">>> Test1: Closing the client.");
- conn.close();
- System.out.println(">>> Test1: Stopping the server.");
- server.removeNotificationListener(listener);
- }
-
- private static void test2(JMXConnectorServer server) throws Exception {
- System.out.println(">>> Test2 close a connection before " +
- "the client can use it...");
- final Killer killer = new Killer(server);
- server.addNotificationListener(killer, null, null);
-
- System.out.println(">>> Test2 Connecting a client to the server ...");
- final JMXConnector conn;
- try {
- conn = JMXConnectorFactory.connect(server.getAddress());
- throw new RuntimeException(">>> Failed, do not receive an " +
- "IOException telling the connection is refused.");
- } catch (IOException ioe) {
- System.out.println(">>> Test2 got expected IOException: "+ioe);
- }
- }
-
- private static class MyListener implements NotificationListener {
- public void handleNotification(Notification n, Object hb) {
- if (n instanceof JMXConnectionNotification) {
- synchronized (received) {
- received.add((JMXConnectionNotification) n);
- received.notify();
- }
- }
- }
-
- public JMXConnectionNotification wait(String type, long timeout)
- throws Exception {
- JMXConnectionNotification waited = null;
- long toWait = timeout;
- long deadline = System.currentTimeMillis() + timeout;
- synchronized (received) {
- while (waited == null && toWait > 0) {
- received.wait(toWait);
- for (JMXConnectionNotification n : received) {
- if (type.equals(n.getType())) {
- waited = n;
- break;
- }
- }
- received.clear();
- toWait = deadline - System.currentTimeMillis();
- }
- }
-
- if (waited == null) {
- throw new RuntimeException("Do not receive expected notification " + type);
- } else {
- System.out.println(">>> Received expected notif: "+type+
- " "+waited.getConnectionId());
- }
-
- return waited;
- }
-
- final List<JMXConnectionNotification> received =
- new ArrayList<JMXConnectionNotification>();
- }
-
- private static class Killer implements NotificationListener {
- public Killer(JMXConnectorServer server) {
- this.server = server;
- }
- public void handleNotification(Notification n, Object hb) {
- if (n instanceof JMXConnectionNotification) {
- if (JMXConnectionNotification.OPENED.equals(n.getType())) {
- final JMXConnectionNotification cn =
- (JMXConnectionNotification)n;
- try {
- System.out.println(">>> Killer: close the connection "+
- cn.getConnectionId());
- server.closeConnection(cn.getConnectionId());
- } catch (Exception e) {
- // impossible?
- e.printStackTrace();
- System.exit(1);
- }
- }
- }
- }
-
- private final JMXConnectorServer server;
- }
-
- private static final long timeout = 6000;
-}
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/ForwarderChainTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +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.
- *
- * 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.
- */
-
-import java.util.NoSuchElementException;
-import java.util.Random;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerFactory;
-import javax.management.remote.IdentityMBeanServerForwarder;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-
-/*
- * @test
- * @bug 6218920
- * @summary Tests manipulation of MBeanServerForwarder chains.
- * @author Eamonn McManus
- */
-import javax.management.remote.rmi.RMIConnectorServer;
-
-public class ForwarderChainTest {
- private static final TestMBeanServerForwarder[] forwarders =
- new TestMBeanServerForwarder[10];
- static {
- for (int i = 0; i < forwarders.length; i++)
- forwarders[i] = new TestMBeanServerForwarder(i);
- }
-
- private static class TestMBeanServerForwarder
- extends IdentityMBeanServerForwarder {
- private final int index;
- volatile int defaultDomainCount;
-
- TestMBeanServerForwarder(int index) {
- this.index = index;
- }
-
- @Override
- public String getDefaultDomain() {
- defaultDomainCount++;
- return super.getDefaultDomain();
- }
-
- @Override
- public String toString() {
- return "forwarders[" + index + "]";
- }
- }
-
- private static String failure;
-
- public static void main(String[] args) throws Exception {
-
- System.out.println("===Test with newly created, unattached server===");
-
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
- JMXConnectorServer cs = new RMIConnectorServer(url, null);
- test(cs, null);
-
- System.out.println("===Test with server attached to MBS===");
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- cs = new RMIConnectorServer(url, null, mbs);
- test(cs, mbs);
-
- System.out.println("===Remove any leftover forwarders===");
- MBeanServerForwarder systemMBSF = cs.getSystemMBeanServerForwarder();
- // Real code would just do systemMBSF.setMBeanServer(mbs).
- while (true) {
- MBeanServer xmbs = systemMBSF.getMBeanServer();
- if (!(xmbs instanceof MBeanServerForwarder))
- break;
- cs.removeMBeanServerForwarder((MBeanServerForwarder) xmbs);
- }
- expectChain(cs, "U", mbs);
-
- System.out.println("===Ensure forwarders are called===");
- cs.setMBeanServerForwarder(forwarders[0]);
- systemMBSF.setMBeanServer(forwarders[1]);
- forwarders[1].setMBeanServer(forwarders[0]);
- expectChain(cs, "1U0", mbs);
- cs.start();
- if (forwarders[0].defaultDomainCount != 0 ||
- forwarders[1].defaultDomainCount != 0) {
- fail("defaultDomainCount not zero");
- }
- JMXServiceURL addr = cs.getAddress();
- JMXConnector cc = JMXConnectorFactory.connect(addr);
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
- mbsc.getDefaultDomain();
- cc.close();
- cs.stop();
- for (boolean system : new boolean[] {false, true}) {
- TestMBeanServerForwarder mbsf = system ? forwarders[1] : forwarders[0];
- if (mbsf.defaultDomainCount != 1) {
- fail((system ? "System" : "User") + " forwarder called " +
- mbsf.defaultDomainCount + " times");
- }
- }
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception("TEST FAILED: " + failure);
- }
-
- private static void test(JMXConnectorServer cs, MBeanServer end) {
- // A newly-created connector server might have system forwarders,
- // so get rid of those.
- MBeanServerForwarder systemMBSF = cs.getSystemMBeanServerForwarder();
- systemMBSF.setMBeanServer(cs.getMBeanServer());
-
- expectChain(cs, "U", end);
-
- System.out.println("Add a user forwarder");
- cs.setMBeanServerForwarder(forwarders[0]);
- expectChain(cs, "U0", end);
-
- System.out.println("Add another user forwarder");
- cs.setMBeanServerForwarder(forwarders[1]);
- expectChain(cs, "U10", end);
-
- System.out.println("Add a system forwarder");
- forwarders[2].setMBeanServer(systemMBSF.getMBeanServer());
- systemMBSF.setMBeanServer(forwarders[2]);
- expectChain(cs, "2U10", end);
-
- System.out.println("Add another user forwarder");
- cs.setMBeanServerForwarder(forwarders[3]);
- expectChain(cs, "2U310", end);
-
- System.out.println("Add another system forwarder");
- forwarders[4].setMBeanServer(systemMBSF.getMBeanServer());
- systemMBSF.setMBeanServer(forwarders[4]);
- expectChain(cs, "42U310", end);
-
- System.out.println("Remove the first user forwarder");
- cs.removeMBeanServerForwarder(forwarders[3]);
- expectChain(cs, "42U10", end);
-
- System.out.println("Remove the last user forwarder");
- cs.removeMBeanServerForwarder(forwarders[0]);
- expectChain(cs, "42U1", end);
-
- System.out.println("Remove the first system forwarder");
- cs.removeMBeanServerForwarder(forwarders[4]);
- expectChain(cs, "2U1", end);
-
- System.out.println("Remove the last system forwarder");
- cs.removeMBeanServerForwarder(forwarders[2]);
- expectChain(cs, "U1", end);
-
- System.out.println("Remove the last forwarder");
- cs.removeMBeanServerForwarder(forwarders[1]);
- expectChain(cs, "U", end);
-
- System.out.println("---Doing random manipulations---");
- // In this loop we pick one of the forwarders at random each time.
- // If it is already in the chain, then we remove it. If it is not
- // in the chain, then we do one of three things: try to remove it
- // (expecting an exception); add it to the user chain; or add it
- // to the system chain.
- // A subtle point is that if there is no MBeanServer then
- // cs.setMBeanServerForwarder(mbsf) does not change mbsf.getMBeanServer().
- // Since we're recycling a random forwarder[i], we explicitly
- // call mbsf.setMBeanServer(null) in this case.
- String chain = "U";
- Random r = new Random();
- for (int i = 0; i < 50; i++) {
- int fwdi = r.nextInt(10);
- MBeanServerForwarder mbsf = forwarders[fwdi];
- char c = (char) ('0' + fwdi);
- int ci = chain.indexOf(c);
- if (ci >= 0) {
- System.out.println("Remove " + c);
- cs.removeMBeanServerForwarder(mbsf);
- chain = chain.substring(0, ci) + chain.substring(ci + 1);
- } else {
- switch (r.nextInt(3)) {
- case 0: { // try to remove it
- try {
- System.out.println("Try to remove absent " + c);
- cs.removeMBeanServerForwarder(mbsf);
- fail("Remove succeeded but should not have");
- return;
- } catch (NoSuchElementException e) {
- }
- break;
- }
- case 1: { // add it to the user chain
- System.out.println("Add " + c + " to user chain");
- if (cs.getMBeanServer() == null)
- mbsf.setMBeanServer(null);
- cs.setMBeanServerForwarder(mbsf);
- int postu = chain.indexOf('U') + 1;
- chain = chain.substring(0, postu) + c +
- chain.substring(postu);
- break;
- }
- case 2: { // add it to the system chain
- System.out.println("Add " + c + " to system chain");
- mbsf.setMBeanServer(systemMBSF.getMBeanServer());
- systemMBSF.setMBeanServer(mbsf);
- chain = c + chain;
- break;
- }
- }
- }
- expectChain(cs, chain, end);
- }
- }
-
- /*
- * Check that the forwarder chain has the expected contents. The forwarders
- * are encoded as a string. For example, "12U34" means that the system
- * chain contains forwarders[1] followed by forwarders[2], and the user
- * chain contains forwarders[3] followed by forwarders[4]. Since the
- * user chain is attached to the end of the system chain, another way to
- * look at this is that the U marks the transition from one to the other.
- *
- * After traversing the chains, we should be pointing at "end".
- */
- private static void expectChain(
- JMXConnectorServer cs, String chain, MBeanServer end) {
- System.out.println("...expected chain: " + chain);
- MBeanServer curr = cs.getSystemMBeanServerForwarder().getMBeanServer();
- int i = 0;
- while (i < chain.length()) {
- char c = chain.charAt(i);
- if (c == 'U') {
- if (cs.getMBeanServer() != curr) {
- fail("User chain should have started here: " + curr);
- return;
- }
- } else {
- int fwdi = c - '0';
- MBeanServerForwarder forwarder = forwarders[fwdi];
- if (curr != forwarder) {
- fail("Expected forwarder " + c + " here: " + curr);
- return;
- }
- curr = ((MBeanServerForwarder) curr).getMBeanServer();
- }
- i++;
- }
- if (curr != end) {
- fail("End of chain is " + curr + ", should be " + end);
- return;
- }
- System.out.println("...OK");
- }
-
- private static void fail(String msg) {
- System.out.println("FAILED: " + msg);
- failure = msg;
- }
-}
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/StandardForwardersTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +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.
- *
- * 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.
- */
-
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.management.ClientContext;
-import javax.management.MBeanServer;
-import javax.management.event.EventClientDelegate;
-import javax.management.remote.JMXConnectorServer;
-
-/*
- * @test
- * @bug 6663757
- * @summary Tests standard MBeanServerForwarders introduced by connector server
- * options.
- * @author Eamonn McManus
- */
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-
-public class StandardForwardersTest {
- private static String failure;
-
- private static class Forwarder {
- private final String attribute;
- private final boolean defaultEnabled;
- private final Class<?> expectedClass;
-
- public Forwarder(String attribute, boolean defaultEnabled,
- Class<?> expectedClass) {
- this.attribute = attribute;
- this.defaultEnabled = defaultEnabled;
- this.expectedClass = expectedClass;
- }
- }
-
- private static enum Status {DISABLED, ENABLED, DEFAULT}
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-
- MBeanServerForwarder ctxFwd = ClientContext.newContextForwarder(mbs, null);
- Forwarder ctx = new Forwarder(
- JMXConnectorServer.CONTEXT_FORWARDER, true, ctxFwd.getClass());
-
- MBeanServerForwarder locFwd =
- ClientContext.newLocalizeMBeanInfoForwarder(mbs);
- Forwarder loc = new Forwarder(
- JMXConnectorServer.LOCALIZE_MBEAN_INFO_FORWARDER, false,
- locFwd.getClass());
-
- MBeanServerForwarder ecdFwd =
- EventClientDelegate.newForwarder(mbs, null);
- Forwarder ecd = new Forwarder(
- JMXConnectorServer.EVENT_CLIENT_DELEGATE_FORWARDER, true,
- ecdFwd.getClass());
-
- Forwarder[] forwarders = {ctx, loc, ecd};
-
- // Now go through every combination of forwarders. Each forwarder
- // may be explicitly enabled, explicitly disabled, or left to its
- // default value.
- int nStatus = Status.values().length;
- int limit = (int) Math.pow(nStatus, forwarders.length);
- for (int i = 0; i < limit; i++) {
- Status[] status = new Status[forwarders.length];
- int ii = i;
- for (int j = 0; j < status.length; j++) {
- status[j] = Status.values()[ii % nStatus];
- ii /= nStatus;
- }
- Map<String, String> env = new HashMap<String, String>();
- String test = "";
- for (int j = 0; j < status.length; j++) {
- if (!test.equals(""))
- test += "; ";
- test += forwarders[j].attribute;
- switch (status[j]) {
- case DISABLED:
- test += "=false";
- env.put(forwarders[j].attribute, "false");
- break;
- case ENABLED:
- test += "=true";
- env.put(forwarders[j].attribute, "true");
- break;
- case DEFAULT:
- test += "=default(" + forwarders[j].defaultEnabled + ")";
- break;
- }
- }
- boolean consistent = isConsistent(env);
- test += "; (" + (consistent ? "" : "in") + "consistent)";
- System.out.println(test);
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
- try {
- JMXConnectorServer cs =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
- if (!consistent) {
- fail("Inconsistent attributes should have been rejected " +
- "but were not");
- }
- checkForwarders(cs, forwarders, status);
- } catch (IllegalArgumentException e) {
- if (consistent) {
- fail("Consistent attributes provoked IllegalArgumentException");
- e.printStackTrace(System.out);
- }
- }
- }
-
- if (failure == null)
- System.out.println("TEST PASSED");
- else
- throw new Exception(failure);
- }
-
- // Check that the classes of the forwarders in the system chain correspond
- // to what we expect given the options we have passed. This check is a bit
- // superficial in the sense that a forwarder might be for example a
- // SingleMBeanForwarderHandler but that doesn't prove that it is the
- // right Single MBean. Nevertheless the test should expose any severe
- // wrongness.
- //
- // The check here makes some assumptions that could become untrue in the
- // future. First, it assumes that the forwarders that are added have
- // exactly the classes that are in the Forwarder[] array. So for example
- // the forwarder for CONTEXT_FORWARDER must be of the same class as an
- // explicit call to ClientContext.newContextForwarder. The spec doesn't
- // require that - it only requires that the forwarder have the same
- // behaviour. The second assumption is that the connector server doesn't
- // add any forwarders of its own into the system chain, and again the spec
- // doesn't disallow that.
- private static void checkForwarders(
- JMXConnectorServer cs, Forwarder[] forwarders, Status[] status) {
- List<Class<?>> expectedClasses = new ArrayList<Class<?>>();
- for (int i = 0; i < forwarders.length; i++) {
- if (status[i] == Status.ENABLED ||
- (status[i] == Status.DEFAULT && forwarders[i].defaultEnabled))
- expectedClasses.add(forwarders[i].expectedClass);
- }
- MBeanServer stop = cs.getMBeanServer();
- List<Class<?>> foundClasses = new ArrayList<Class<?>>();
- for (MBeanServer mbs = cs.getSystemMBeanServerForwarder().getMBeanServer();
- mbs != stop;
- mbs = ((MBeanServerForwarder) mbs).getMBeanServer()) {
- foundClasses.add(mbs.getClass());
- }
- if (!expectedClasses.equals(foundClasses)) {
- fail("Incorrect forwarder chain: expected " + expectedClasses +
- "; found " + foundClasses);
- }
- }
-
- // env is consistent if either (a) localizer is not enabled or (b)
- // localizer is enabled and context is enabled.
- private static boolean isConsistent(Map<String, String> env) {
- String ctxS = env.get(JMXConnectorServer.CONTEXT_FORWARDER);
- boolean ctx = (ctxS == null) ? true : Boolean.parseBoolean(ctxS);
- String locS = env.get(JMXConnectorServer.LOCALIZE_MBEAN_INFO_FORWARDER);
- boolean loc = (locS == null) ? false : Boolean.parseBoolean(locS);
- return !loc || ctx;
- }
-
- private static void fail(String why) {
- System.out.println("FAILED: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -124,16 +124,7 @@
}
private static boolean test(String proto) throws Exception {
- boolean ok = true;
- for (boolean eventService : new boolean[] {false, true})
- ok &= test(proto, eventService);
- return ok;
- }
-
- private static boolean test(String proto, boolean eventService)
- throws Exception {
- System.out.println("Testing for proto " + proto + " with" +
- (eventService ? "" : "out") + " Event Service");
+ System.out.println("Testing for proto " + proto);
boolean ok = true;
@@ -145,8 +136,6 @@
Map serverMap = new HashMap();
serverMap.put(JMXConnectorServerFactory.DEFAULT_CLASS_LOADER,
serverLoader);
- serverMap.put(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
// make sure no auto-close at server side
serverMap.put("jmx.remote.x.server.connection.timeout", "888888888");
--- a/jdk/test/javax/management/remote/mandatory/notif/AddRemoveTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/AddRemoveTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003 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
@@ -33,12 +33,10 @@
*/
import java.net.MalformedURLException;
+import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rmi.RMIConnectorServer;
public class AddRemoveTest {
private static final String[] protocols = {"rmi", "iiop", "jmxmp"};
@@ -71,16 +69,9 @@
}
}
- private static boolean test(String proto) throws Exception {
- boolean ok = test(proto, false);
- ok &= test(proto, true);
- return ok;
- }
-
- private static boolean test(String proto, boolean eventService)
+ private static boolean test(String proto)
throws Exception {
- System.out.println(">>> Test for protocol " + proto + " with" +
- (eventService ? "" : "out") + " event service");
+ System.out.println(">>> Test for protocol " + proto);
JMXServiceURL u = new JMXServiceURL(proto, null, 0);
JMXConnectorServer server;
JMXServiceURL addr;
@@ -98,10 +89,7 @@
try {
// with a client listener, but close the server first
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
- server = JMXConnectorServerFactory.newJMXConnectorServer(u, env, mbs);
+ server = JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs);
server.start();
addr = server.getAddress();
--- a/jdk/test/javax/management/remote/mandatory/notif/DiffHBTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/DiffHBTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -32,11 +32,8 @@
*/
-import java.util.Collections;
-import java.util.Map;
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rmi.RMIConnectorServer;
/**
* This test registeres an unique listener with two different handbacks,
@@ -80,33 +77,14 @@
}
private static String test(String proto) throws Exception {
- String ret = null;
- for (boolean eventService : new boolean[] {false, true}) {
- String s = test(proto, eventService);
- if (s != null) {
- if (ret == null)
- ret = s;
- else
- ret = ret + "; " + s;
- }
- }
- return ret;
- }
-
- private static String test(String proto, boolean eventService)
- throws Exception {
- System.out.println(">>> Test for protocol " + proto + " with" +
- (eventService ? "" : "out") + " event service");
+ System.out.println(">>> Test for protocol " + proto);
JMXServiceURL u = new JMXServiceURL(proto, null, 0);
JMXConnectorServer server;
JMXConnector client;
try {
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
server =
- JMXConnectorServerFactory.newJMXConnectorServer(u, env, mbs);
+ JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs);
server.start();
JMXServiceURL addr = server.getAddress();
client = JMXConnectorFactory.connect(addr, null);
--- a/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005 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
@@ -29,12 +29,11 @@
* @author Shanliang JIANG
* @run clean EmptyDomainNotificationTest
* @run build EmptyDomainNotificationTest
- * @run main EmptyDomainNotificationTest classic
- * @run main EmptyDomainNotificationTest event
+ * @run main EmptyDomainNotificationTest
*/
-import java.util.Collections;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
@@ -47,7 +46,6 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
public class EmptyDomainNotificationTest {
@@ -82,25 +80,11 @@
public static void main(String[] args) throws Exception {
- String type = args[0];
- boolean eventService;
- if (type.equals("classic"))
- eventService = false;
- else if (type.equals("event"))
- eventService = true;
- else
- throw new IllegalArgumentException(type);
-
final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
final JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
-
- JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
server.start();
JMXConnector client = JMXConnectorFactory.connect(server.getAddress(), null);
--- a/jdk/test/javax/management/remote/mandatory/notif/ListenerScaleTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/ListenerScaleTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -51,8 +51,6 @@
* been compiled by the second.
*/
-import java.util.Collections;
-import java.util.Map;
import java.util.concurrent.Semaphore;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
@@ -67,7 +65,6 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
public class ListenerScaleTest {
private static final int WARMUP_WITH_ONE_MBEAN = 1000;
@@ -128,20 +125,12 @@
};
public static void main(String[] args) throws Exception {
- test(false);
- test(true);
- }
-
- private static void test(boolean eventService) throws Exception {
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
Sender sender = new Sender();
mbs.registerMBean(sender, testObjectName);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
JMXConnectorServer cs =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
JMXConnector cc = JMXConnectorFactory.connect(addr);
--- a/jdk/test/javax/management/remote/mandatory/notif/NotifBufferSizePropertyNameTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotifBufferSizePropertyNameTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2004-2005 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
@@ -31,11 +31,11 @@
* @run main NotifBufferSizePropertyNameTest
*/
+import java.io.IOException;
import java.util.*;
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rmi.RMIConnectorServer;
/**
* This class tests also the size of a server notification buffer.
@@ -88,9 +88,6 @@
private static void test(Map env) throws Exception {
final MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- env = new HashMap((env == null) ? Collections.emptyMap() : env);
- env.put(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
-
mbs.registerMBean(new NotificationEmitter(), oname);
JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer(
url,
--- a/jdk/test/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -45,7 +45,6 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
/**
* "This test checks for a bug whereby reconnection did not work if (a) it was
@@ -74,7 +73,6 @@
Map env = new HashMap(2);
env.put("jmx.remote.x.server.connection.timeout", new Long(serverTimeout));
env.put("jmx.remote.x.client.connection.check.period", new Long(Long.MAX_VALUE));
- env.put(RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
final MBeanServer mbs = MBeanServerFactory.newMBeanServer();
--- a/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferCreationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferCreationTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2007 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
@@ -32,8 +32,6 @@
*/
import java.net.MalformedURLException;
-import java.util.Collections;
-import java.util.Map;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
@@ -46,7 +44,6 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
public class NotificationBufferCreationTest {
private static final MBeanServer mbs =
@@ -89,8 +86,6 @@
JMXServiceURL u = null;
try {
u = new JMXServiceURL(protocol, null, 0);
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, "false");
server =
JMXConnectorServerFactory.newJMXConnectorServer(u,
null,
--- a/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2006 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
@@ -35,9 +35,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
-import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.Vector;
import javax.management.*;
@@ -90,7 +88,6 @@
* If the logic for adding the notification buffer's listener is incorrect
* we could remove zero or two notifications from an MBean.
*/
-import javax.management.remote.rmi.RMIConnectorServer;
public class NotificationBufferDeadlockTest {
public static void main(String[] args) throws Exception {
System.out.println("Check no deadlock if notif sent while initial " +
@@ -112,13 +109,7 @@
}
private static void test(String proto) throws Exception {
- test(proto, false);
- test(proto, true);
- }
-
- private static void test(String proto, boolean eventService) throws Exception {
- System.out.println("Testing protocol " + proto + " with" +
- (eventService ? "" : "out") + " event service");
+ System.out.println("Testing protocol " + proto);
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
ObjectName testName = newName();
DeadlockTest test = new DeadlockTest();
@@ -126,11 +117,8 @@
JMXServiceURL url = new JMXServiceURL("service:jmx:" + proto + ":///");
JMXConnectorServer cs;
try {
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
cs =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
} catch (MalformedURLException e) {
System.out.println("...protocol not supported, ignoring");
return;
--- a/jdk/test/javax/management/remote/mandatory/notif/NotificationEmissionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationEmissionTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -29,16 +29,11 @@
* @author Luis-Miguel Alventosa
* @run clean NotificationEmissionTest
* @run build NotificationEmissionTest
- * @run main NotificationEmissionTest 1 Classic
- * @run main NotificationEmissionTest 2 Classic
- * @run main NotificationEmissionTest 3 Classic
- * @run main NotificationEmissionTest 4 Classic
- * @run main NotificationEmissionTest 5 Classic
- * @run main NotificationEmissionTest 1 EventService
- * @run main NotificationEmissionTest 2 EventService
- * @run main NotificationEmissionTest 3 EventService
- * @run main NotificationEmissionTest 4 EventService
- * @run main NotificationEmissionTest 5 EventService
+ * @run main NotificationEmissionTest 1
+ * @run main NotificationEmissionTest 2
+ * @run main NotificationEmissionTest 3
+ * @run main NotificationEmissionTest 4
+ * @run main NotificationEmissionTest 5
*/
import java.io.File;
@@ -61,15 +56,9 @@
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXPrincipal;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
import javax.security.auth.Subject;
public class NotificationEmissionTest {
- private final boolean eventService;
-
- public NotificationEmissionTest(boolean eventService) {
- this.eventService = eventService;
- }
public class CustomJMXAuthenticator implements JMXAuthenticator {
public Subject authenticate(Object credentials) {
@@ -228,13 +217,8 @@
//
final Map<String,Object> env = new HashMap<String,Object>();
env.put("jmx.remote.authenticator", new CustomJMXAuthenticator());
- env.put(RMIConnectorServer.EVENT_CLIENT_DELEGATE_FORWARDER,
- Boolean.toString(eventService));
- if (prop) {
- echo("Setting jmx.remote.x.check.notification.emission to " +
- propValue);
+ if (prop)
env.put("jmx.remote.x.check.notification.emission", propValue);
- }
// Create the JMXServiceURL
//
@@ -302,14 +286,11 @@
// If the check is effective and we're using policy.negative,
// then we should see the two notifs sent by nb2 (of which one
// has a getSource() that is nb3), but not the notif sent by nb1.
- // Otherwise we should see all three notifs. If we're using the
- // Event Service with a Security Manager then the logic to
- // reapply the addNL permission test for every notification is
- // always enabled, regardless of the value of
- // jmx.remote.x.check.notification.emission. Otherwise, the
- // test is only applied if that property is explicitly true.
+ // Otherwise we should see all three notifs. The check is only
+ // effective if the property jmx.remote.x.check.notification.emission
+ // is explicitly true and there is a security manager.
int expectedNotifs =
- ((prop || eventService) && sm && !policyPositive) ? 2 : 3;
+ (prop && sm && !policyPositive) ? 2 : 3;
// Wait for notifications to be emitted
//
@@ -324,15 +305,14 @@
mbsc.removeNotificationListener(nb2, li);
int result = 0;
- List<ObjectName> sources = new ArrayList();
+ List<ObjectName> sources = new ArrayList<ObjectName>();
sources.add(nb1);
sources.add(nb2);
sources.add(nb3);
result = checkNotifs(expectedNotifs, li.notifs, sources);
if (result > 0) {
- echo("...SecurityManager=" + sm + "; policy=" + policyPositive +
- "; eventService=" + eventService);
+ echo("...SecurityManager=" + sm + "; policy=" + policyPositive);
return result;
}
} finally {
@@ -362,18 +342,9 @@
public static void main(String[] args) throws Exception {
echo("\n--- Check the emission of notifications " +
- "when a Security Manager is installed [" +
- args[1] + "] ---");
+ "when a Security Manager is installed");
- boolean eventService;
- if (args[1].equals("Classic"))
- eventService = false;
- else if (args[1].equals("EventService"))
- eventService = true;
- else
- throw new IllegalArgumentException(args[1]);
-
- NotificationEmissionTest net = new NotificationEmissionTest(eventService);
+ NotificationEmissionTest net = new NotificationEmissionTest();
int error = 0;
--- a/jdk/test/javax/management/remote/mandatory/notif/RMINotifTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/RMINotifTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -25,10 +25,11 @@
* @test
* @bug 7654321
* @summary Tests to receive notifications for opened and closed connections
+ions
* @author sjiang
* @run clean RMINotifTest
* @run build RMINotifTest
- * @run main RMINotifTest classic
+ * @run main RMINotifTest
* @run main RMINotifTest event
*/
@@ -38,8 +39,6 @@
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
-import java.util.Collections;
-import java.util.Map;
import java.util.Random;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanServer;
@@ -56,19 +55,10 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
public class RMINotifTest {
public static void main(String[] args) {
- String eventService;
- if (args[0].equals("classic"))
- eventService = "false";
- else if (args[0].equals("event"))
- eventService = "true";
- else
- throw new IllegalArgumentException(args[0]);
-
try {
// create a rmi registry
Registry reg = null;
@@ -105,10 +95,9 @@
"/jndi/rmi://:" + port + "/server" + port);
System.out.println("RMIConnectorServer address " + url);
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE, eventService);
JMXConnectorServer sServer =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, null);
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null,
+ null);
ObjectInstance ss = server.registerMBean(sServer, new ObjectName("Default:name=RmiConnectorServer"));
--- a/jdk/test/javax/management/remote/mandatory/notif/UnexpectedNotifTest.java Wed Oct 21 15:47:09 2009 +0100
+++ b/jdk/test/javax/management/remote/mandatory/notif/UnexpectedNotifTest.java Wed Oct 21 16:50:44 2009 +0100
@@ -63,17 +63,13 @@
} catch (ClassNotFoundException e) {
// OK: JMXMP not present so don't test it.
}
- for (String proto : protos) {
- test(proto, false);
- test(proto, true);
- }
+ for (String proto : protos)
+ test(proto);
}
- private static void test(String proto, boolean eventService)
- throws Exception {
+ private static void test(String proto) throws Exception {
System.out.println("Unexpected notifications test for protocol " +
- proto + " with" +
- (eventService ? "" : "out") + " event service");
+ proto);
MBeanServer mbs = null;
try {
// Create a MBeanServer
@@ -88,12 +84,9 @@
// Create a connector server
//
url = new JMXServiceURL("service:jmx:" + proto + "://");
- Map<String, String> env = Collections.singletonMap(
- RMIConnectorServer.DELEGATE_TO_EVENT_SERVICE,
- Boolean.toString(eventService));
server = JMXConnectorServerFactory.newJMXConnectorServer(url,
- env,
+ null,
mbs);
mbs.registerMBean(
--- a/jdk/test/javax/management/remote/mandatory/version/JMXSpecVersionTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6750008
- * @summary Test JMX.getSpecificationVersion
- * @author Eamonn McManus
- */
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.ListIterator;
-import java.util.Set;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InstanceNotFoundException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.JMX;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerDelegateMBean;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.StandardMBean;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.MBeanServerSupport;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-public class JMXSpecVersionTest {
- private static String failure;
- private static final Object POISON_PILL = new Object();
-
- private static class FakeDelegate implements DynamicMBean {
- private final Object specVersion;
- private final DynamicMBean delegate = new StandardMBean(
- new MBeanServerDelegate(), MBeanServerDelegateMBean.class, false);
-
- FakeDelegate(Object specVersion) {
- this.specVersion = specVersion;
- }
-
- public Object getAttribute(String attribute)
- throws AttributeNotFoundException, MBeanException,
- ReflectionException {
- if ("SpecificationVersion".equals(attribute)) {
- if (specVersion == POISON_PILL)
- throw new AttributeNotFoundException(attribute);
- else
- return specVersion;
- } else
- return delegate.getAttribute(attribute);
- }
-
- public void setAttribute(Attribute attribute)
- throws AttributeNotFoundException, InvalidAttributeValueException,
- MBeanException, ReflectionException {
- delegate.setAttribute(attribute);
- }
-
- public AttributeList getAttributes(String[] attributes) {
- AttributeList list = delegate.getAttributes(attributes);
- for (ListIterator<Attribute> it = list.asList().listIterator();
- it.hasNext(); ) {
- Attribute attr = it.next();
- if (attr.getName().equals("SpecificationVersion")) {
- it.remove();
- if (specVersion != POISON_PILL) {
- attr = new Attribute(attr.getName(), specVersion);
- it.add(attr);
- }
- }
- }
- return list;
- }
-
- public AttributeList setAttributes(AttributeList attributes) {
- return delegate.setAttributes(attributes);
- }
-
- public Object invoke(String actionName, Object[] params,
- String[] signature) throws MBeanException,
- ReflectionException {
- return delegate.invoke(actionName, params, signature);
- }
-
- public MBeanInfo getMBeanInfo() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
- }
-
- private static class MBeanServerWithVersion extends MBeanServerSupport {
- private final DynamicMBean delegate;
-
- public MBeanServerWithVersion(Object specVersion) {
- this.delegate = new FakeDelegate(specVersion);
- }
-
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name)
- throws InstanceNotFoundException {
- if (MBeanServerDelegate.DELEGATE_NAME.equals(name))
- return delegate;
- else
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return Collections.singleton(MBeanServerDelegate.DELEGATE_NAME);
- }
- }
-
- private static class EmptyMBeanServer extends MBeanServerSupport {
- @Override
- public DynamicMBean getDynamicMBeanFor(ObjectName name) throws InstanceNotFoundException {
- throw new InstanceNotFoundException(name);
- }
-
- @Override
- protected Set<ObjectName> getNames() {
- return Collections.emptySet();
- }
- }
-
- public static void main(String[] args) throws Exception {
- MBeanServer mbs = MBeanServerFactory.newMBeanServer();
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
- url, null, mbs);
- cs.start();
-
- String realVersion = (String) mbs.getAttribute(
- MBeanServerDelegate.DELEGATE_NAME, "SpecificationVersion");
- assertEquals("Reported local version",
- realVersion, JMX.getSpecificationVersion(mbs, null));
- assertEquals("Reported local version >= \"2.0\"",
- true, (realVersion.compareTo("2.0") >= 0));
-
- JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress());
- MBeanServerConnection mbsc = cc.getMBeanServerConnection();
- assertEquals("Reported remote version",
- realVersion, JMX.getSpecificationVersion(mbsc, null));
-
- cc.close();
- try {
- String brokenVersion = JMX.getSpecificationVersion(mbsc, null);
- fail("JMX.getSpecificationVersion succeded over closed connection" +
- " (returned " + brokenVersion + ")");
- } catch (Exception e) {
- assertEquals("Exception for closed connection",
- IOException.class, e.getClass());
- }
-
- try {
- String brokenVersion = JMX.getSpecificationVersion(
- new EmptyMBeanServer(), null);
- fail("JMX.getSpecificationVersion succeded with empty MBean Server" +
- " (returned " + brokenVersion + ")");
- } catch (Exception e) {
- assertEquals("Exception for empty MBean Server",
- IOException.class, e.getClass());
- }
-
- try {
- String brokenVersion = JMX.getSpecificationVersion(null, null);
- fail("JMX.getSpecificationVersion succeded with null MBean Server" +
- " (returned " + brokenVersion + ")");
- } catch (Exception e) {
- assertEquals("Exception for null MBean Server",
- IllegalArgumentException.class, e.getClass());
- }
-
- MBeanServer mbs1_2 = new MBeanServerWithVersion("1.2");
- String version1_2 = JMX.getSpecificationVersion(mbs1_2, null);
- assertEquals("Version for 1.2 MBean Server", "1.2", version1_2);
-
- // It's completely nutty for an MBean Server to return null as the
- // value of its spec version, and we don't actually say what happens
- // in that case, but in fact we return the null to the caller.
- MBeanServer mbs_null = new MBeanServerWithVersion(null);
- String version_null = JMX.getSpecificationVersion(mbs_null, null);
- assertEquals("Version for MBean Server that declares null spec version",
- null, version_null);
-
- try {
- MBeanServer mbs1_2_float = new MBeanServerWithVersion(1.2f);
- String version1_2_float =
- JMX.getSpecificationVersion(mbs1_2_float, null);
- fail("JMX.getSpecificationVersion succeeded with version 1.2f" +
- " (returned " + version1_2_float + ")");
- } catch (Exception e) {
- assertEquals("Exception for non-string version (1.2f)",
- IOException.class, e.getClass());
- }
-
- try {
- MBeanServer mbs_missing = new MBeanServerWithVersion(POISON_PILL);
- String version_missing =
- JMX.getSpecificationVersion(mbs_missing, null);
- fail("JMX.getSpecificationVersion succeeded with null version" +
- " (returned " + version_missing + ")");
- } catch (Exception e) {
- assertEquals("Exception for missing version",
- IOException.class, e.getClass());
- }
-
- ObjectName wildcardNamespaceName = new ObjectName("foo//*//bar//baz:k=v");
- try {
- String brokenVersion =
- JMX.getSpecificationVersion(mbsc, wildcardNamespaceName);
- fail("JMX.getSpecificationVersion succeeded with wildcard namespace" +
- " (returned " + brokenVersion + ")");
- } catch (Exception e) {
- assertEquals("Exception for wildcard namespace",
- IllegalArgumentException.class, e.getClass());
- }
-
- String sub1_2namespace = "blibby";
- JMXNamespace sub1_2 = new JMXNamespace(mbs1_2);
- ObjectName sub1_2name =
- JMXNamespaces.getNamespaceObjectName(sub1_2namespace);
- mbs.registerMBean(sub1_2, sub1_2name);
- String sub1_2namespaceHandlerVersion =
- JMX.getSpecificationVersion(mbs, sub1_2name);
- assertEquals("Spec version of namespace handler",
- realVersion, sub1_2namespaceHandlerVersion);
- // The namespace handler is in the top-level namespace so its
- // version should not be 1.2.
-
- for (String nameInSub : new String[] {"*:*", "d:k=v"}) {
- ObjectName subName = new ObjectName(sub1_2namespace + "//" + nameInSub);
- String subVersion = JMX.getSpecificationVersion(mbs, subName);
- assertEquals("Spec version in 1.2 namespace (" + nameInSub + ")",
- "1.2", subVersion);
- }
-
- mbs.unregisterMBean(sub1_2name);
- for (String noSuchNamespace : new String[] {
- sub1_2namespace + "//*:*", sub1_2namespace + "//d:k=v",
- }) {
- try {
- String brokenVersion = JMX.getSpecificationVersion(
- mbs, new ObjectName(noSuchNamespace));
- fail("JMX.getSpecificationVersion succeeded with missing " +
- "namespace (" + noSuchNamespace + " -> " +
- brokenVersion);
- } catch (Exception e) {
- assertEquals("Exception for missing namespace",
- IOException.class, e.getClass());
- }
- }
-
- if (failure != null)
- throw new Exception("TEST FAILED: " + failure);
- System.out.println("TEST PASSED");
- }
-
- private static void assertEquals(String what, Object expect, Object actual) {
- if (equal(expect, actual))
- System.out.println("OK: " + what + ": " + expect);
- else
- fail(what + ": expected " + expect + ", got " + actual);
- }
-
- private static boolean equal(Object x, Object y) {
- if (x == null)
- return (y == null);
- else
- return x.equals(y);
- }
-
- private static void fail(String why) {
- System.out.println("FAILED: " + why);
- failure = why;
- }
-}
--- a/jdk/test/javax/management/standardmbean/FindMethodTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6287328
- * @summary Add methods to StandardMBean to retrieve a method based on
- * MBean{Attribute|Operation}Info
- * @author Jean-Francois Denise
- * @run main FindMethodTest
- */
-
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.lang.management.ThreadMXBean;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.management.MBean;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.MBeanServer;
-import javax.management.ManagedAttribute;
-import javax.management.ManagedOperation;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-
-public class FindMethodTest {
-
- private static MBeanServer server =
- ManagementFactory.getPlatformMBeanServer();
-
- private static Map<String, Set<Method>> expectedMapping =
- new HashMap<String, Set<Method>>();
- private static Set<Method> STATE_SET = new HashSet<Method>();
- private static Set<Method> ENABLED_SET = new HashSet<Method>();
- private static Set<Method> DOIT_SET = new HashSet<Method>();
- private static Set<Method> STATUS_SET = new HashSet<Method>();
- private static Set<Method> HEAPMEMORYUSAGE_SET = new HashSet<Method>();
- private static Set<Method> THREADINFO_SET = new HashSet<Method>();
- private static Set<Method> DOIT_ANNOTATED_SET = new HashSet<Method>();
- private static Set<Method> IT_ANNOTATED_SET = new HashSet<Method>();
- private static HashSet<Set<Method>> TEST_MBEAN_SET =
- new HashSet<Set<Method>>();
- private static HashSet<Set<Method>> ANNOTATED_MBEAN_SET =
- new HashSet<Set<Method>>();
- private static HashSet<Set<Method>> MEMORY_MBEAN_SET =
- new HashSet<Set<Method>>();
- private static HashSet<Set<Method>> THREAD_MBEAN_SET =
- new HashSet<Set<Method>>();
-
- public interface TestMBean {
-
- public void doIt();
-
- public void setState(String str);
-
- public String getState();
-
- public boolean isEnabled();
-
- public void setStatus(int i);
- }
-
- public interface FaultyTestMBean {
-
- public void doIt(String doIt);
-
- public long getState();
-
- public void setEnabled(boolean b);
-
- public int getStatus();
-
- public String setWrong(int i);
- }
-
- @MBean
- public static class AnnotatedTest {
- @ManagedOperation
- public void doItAnnotated() {
-
- }
-
- public void dontDoIt() {
-
- }
-
- @ManagedAttribute
- public String getItAnnotated() {
- return null;
- }
- @ManagedAttribute
- public void setItAnnotated(String str) {
-
- }
-
- public String getItNot() {
- return null;
- }
-
- }
-
- static class Test implements TestMBean {
-
- public void doIt() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setState(String str) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public String getState() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public boolean isEnabled() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void setStatus(int i) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
- }
-
-
- static {
- try {
- ENABLED_SET.add(TestMBean.class.getDeclaredMethod("isEnabled"));
-
- STATE_SET.add(TestMBean.class.getDeclaredMethod("getState"));
- STATE_SET.add(TestMBean.class.getDeclaredMethod("setState",
- String.class));
- STATUS_SET.add(TestMBean.class.getDeclaredMethod("setStatus",
- int.class));
-
- DOIT_SET.add(TestMBean.class.getDeclaredMethod("doIt"));
-
- DOIT_ANNOTATED_SET.add(AnnotatedTest.class.getDeclaredMethod("doItAnnotated"));
-
- IT_ANNOTATED_SET.add(AnnotatedTest.class.getDeclaredMethod("getItAnnotated"));
- IT_ANNOTATED_SET.add(AnnotatedTest.class.getDeclaredMethod("setItAnnotated", String.class));
-
- THREADINFO_SET.add(ThreadMXBean.class.getDeclaredMethod("dumpAllThreads", boolean.class,
- boolean.class));
-
- HEAPMEMORYUSAGE_SET.add(MemoryMXBean.class.getDeclaredMethod("getHeapMemoryUsage"));
-
- TEST_MBEAN_SET.add(ENABLED_SET);
- TEST_MBEAN_SET.add(STATE_SET);
- TEST_MBEAN_SET.add(STATUS_SET);
- TEST_MBEAN_SET.add(DOIT_SET);
-
- ANNOTATED_MBEAN_SET.add(DOIT_ANNOTATED_SET);
- ANNOTATED_MBEAN_SET.add(IT_ANNOTATED_SET);
-
- MEMORY_MBEAN_SET.add(HEAPMEMORYUSAGE_SET);
-
- THREAD_MBEAN_SET.add(THREADINFO_SET);
-
- expectedMapping.put("State", STATE_SET);
- expectedMapping.put("Enabled", ENABLED_SET);
- expectedMapping.put("Status", STATUS_SET);
- expectedMapping.put("doIt", DOIT_SET);
- expectedMapping.put("HeapMemoryUsage", HEAPMEMORYUSAGE_SET);
- expectedMapping.put("dumpAllThreads", THREADINFO_SET);
- expectedMapping.put("doItAnnotated", DOIT_ANNOTATED_SET);
- expectedMapping.put("ItAnnotated", IT_ANNOTATED_SET);
-
- } catch (Exception ex) {
- ex.printStackTrace();
- throw new RuntimeException("Initialization failed");
- }
- }
-
- private static void testMBean(ObjectName name, Class<?> itf,
- HashSet<Set<Method>> expectMappings)
- throws Exception {
-
- Set<Set<Method>> expectedMappings =
- (Set<Set<Method>>) expectMappings.clone();
-
- MBeanInfo info = server.getMBeanInfo(name);
- for (MBeanAttributeInfo attr : info.getAttributes()) {
- Set<Method> expected = expectedMapping.get(attr.getName());
- if (expected == null) {
- continue;
- }
- if (!expectedMappings.remove(expected)) {
- throw new Exception("The mapping to use is not the expected " +
- "one for " + attr);
- }
- System.out.println("Expected : " + expected);
- Set<Method> found =
- StandardMBean.findAttributeAccessors(itf, attr);
- System.out.println("Found : " + found);
- if (!found.equals(expected)) {
- throw new Exception("Mapping error.");
- }
- }
- for (MBeanOperationInfo op : info.getOperations()) {
- Set<Method> expected = expectedMapping.get(op.getName());
- if (expected == null) {
- continue;
- }
- if (!expectedMappings.remove(expected)) {
- throw new Exception("The mapping to use is not the expected " +
- "one for " + op);
- }
- System.out.println("Expected : " + expected);
- Method method =
- StandardMBean.findOperationMethod(itf, op);
- Set<Method> found = new HashSet<Method>();
- found.add(method);
- System.out.println("Found : " + found);
- if (!found.equals(expected)) {
- throw new Exception("Mapping error.");
- }
- }
-
- if (expectedMappings.size() != 0) {
- throw new Exception("Some mapping have not been found " +
- expectedMappings);
- } else {
- System.out.println("All mappings have been found");
- }
- }
-
- public static void main(String[] args) throws Exception {
- // Positive tests
- Test t = new Test();
- ObjectName name = ObjectName.valueOf(":type=Test");
- server.registerMBean(t, name);
- AnnotatedTest at = new AnnotatedTest();
- ObjectName annotatedName = ObjectName.valueOf(":type=AnnotatedTest");
- server.registerMBean(at, annotatedName);
-
- testMBean(name, TestMBean.class, TEST_MBEAN_SET);
-
- testMBean(annotatedName, AnnotatedTest.class, ANNOTATED_MBEAN_SET);
-
- ObjectName memoryName =
- ObjectName.valueOf(ManagementFactory.MEMORY_MXBEAN_NAME);
- testMBean(memoryName, MemoryMXBean.class, MEMORY_MBEAN_SET);
-
- ObjectName threadName =
- ObjectName.valueOf(ManagementFactory.THREAD_MXBEAN_NAME);
- testMBean(threadName, ThreadMXBean.class, THREAD_MBEAN_SET);
-
- // Negative tests
- try {
- StandardMBean.findOperationMethod(null,
- new MBeanOperationInfo("Test",
- TestMBean.class.getDeclaredMethod("doIt")));
- throw new Exception("Expected exception not found");
- } catch (IllegalArgumentException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- try {
- StandardMBean.findOperationMethod(TestMBean.class, null);
- throw new Exception("Expected exception not found");
- } catch (IllegalArgumentException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- try {
- StandardMBean.findAttributeAccessors(null,
- new MBeanAttributeInfo("Test", "Test",
- TestMBean.class.getDeclaredMethod("getState"),
- TestMBean.class.getDeclaredMethod("setState",
- String.class)));
- throw new Exception("Expected exception not found");
- } catch (IllegalArgumentException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- try {
- StandardMBean.findAttributeAccessors(TestMBean.class, null);
- throw new Exception("Expected exception not found");
- } catch (IllegalArgumentException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- //Wrong operation signature
- try {
- StandardMBean.findOperationMethod(TestMBean.class,
- new MBeanOperationInfo("FaultyTest",
- FaultyTestMBean.class.getDeclaredMethod("doIt",
- String.class)));
- throw new Exception("Expected exception not found");
- } catch (NoSuchMethodException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- //Wrong attribute accessor
- try {
- StandardMBean.findAttributeAccessors(TestMBean.class,
- new MBeanAttributeInfo("FaultyTest", "FaultyTest", null,
- FaultyTestMBean.class.getDeclaredMethod("setEnabled",
- String.class)));
- throw new Exception("Expected exception not found");
- } catch (NoSuchMethodException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- //Wrong attribute type
- try {
- StandardMBean.findAttributeAccessors(TestMBean.class,
- new MBeanAttributeInfo("State", "toto.FaultType",
- "FaultyTest", true, true, false));
- throw new Exception("Expected exception not found");
- } catch (ClassNotFoundException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- //Wrong operation parameter type
- try {
- MBeanParameterInfo[] p = {new MBeanParameterInfo("p1",
- "toto.FaultType2", "FaultyParameter")
- };
- StandardMBean.findOperationMethod(TestMBean.class,
- new MBeanOperationInfo("doIt", "FaultyMethod", p, "void",
- 0));
- throw new Exception("Expected exception not found");
- } catch (ClassNotFoundException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- // Check that not annotated attributes are not found
- try {
- StandardMBean.findAttributeAccessors(AnnotatedTest.class,
- new MBeanAttributeInfo("ItNot", String.class.getName(),
- "FaultyTest", true, false, false));
- throw new Exception("Expected exception not found");
- } catch (NoSuchMethodException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- // Check that not annotated operations are not found
- try {
- StandardMBean.findOperationMethod(AnnotatedTest.class,
- new MBeanOperationInfo("dontDoIt","dontDoIt",null,
- Void.TYPE.getName(),0));
- throw new Exception("Expected exception not found");
- } catch (NoSuchMethodException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- // Check that wrong getter return type throws Exception
- try {
- StandardMBean.findAttributeAccessors(AnnotatedTest.class,
- new MBeanAttributeInfo("ItAnnotated", Long.class.getName(),
- "FaultyTest", true, false, false));
- throw new Exception("Expected exception not found");
- } catch (NoSuchMethodException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- // Check that wrong setter return type throws Exception
- try {
- StandardMBean.findAttributeAccessors(FaultyTestMBean.class,
- new MBeanAttributeInfo("Wrong", String.class.getName(),
- "FaultyTest", true, true, false));
- throw new Exception("Expected exception not found");
- } catch (NoSuchMethodException ex) {
- System.out.println("OK received expected exception " + ex);
- }
- }
-}
--- a/jdk/test/javax/management/standardmbean/RegistrationTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 6450834
- * @summary Forward MBeanRegistration calls
- * @author JF Denise
- * @run main RegistrationTest
- */
-
-import java.io.Serializable;
-import java.lang.management.ManagementFactory;
-import javax.management.*;
-
-public class RegistrationTest {
- static boolean preRegisterCalled;
- static boolean postRegisterCalled;
- static boolean preDeregisterCalled;
- static boolean postDeregisterCalled;
-
- static void checkResult(boolean expected) throws Exception {
- if((preRegisterCalled != expected ||
- postRegisterCalled != expected ||
- preDeregisterCalled != expected ||
- postDeregisterCalled != expected))
- throw new Exception("Mismatch preRegisterCalled = "
- + preRegisterCalled + ", postRegisterCalled = "
- + postRegisterCalled + ", preDeregisterCalled = "
- + preDeregisterCalled + ", postDeregisterCalled = "
- + postDeregisterCalled);
- }
- static class Wrapped implements MBeanRegistration,Serializable {
-
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- preRegisterCalled = true;
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- postRegisterCalled = true;
- }
-
- public void preDeregister() throws Exception {
- preDeregisterCalled = true;
- }
-
- public void postDeregister() {
- postDeregisterCalled = true;
- }
-
- }
-
- public static void main(String[] args) throws Exception {
- StandardMBean std = new StandardMBean(new Wrapped(),
- Serializable.class);
- ObjectName name = ObjectName.valueOf(":type=Test");
- ManagementFactory.getPlatformMBeanServer().registerMBean(std,name);
- ManagementFactory.getPlatformMBeanServer().unregisterMBean(name);
- checkResult(false);
- StandardMBean.Options opt = new StandardMBean.Options();
- opt.setMBeanRegistrationForwarded(true);
- std = new StandardMBean(new Wrapped(),
- Serializable.class, opt );
- ManagementFactory.getPlatformMBeanServer().registerMBean(std,name);
- ManagementFactory.getPlatformMBeanServer().unregisterMBean(name);
- checkResult(true);
- System.out.println("Test OK");
- }
-}