# HG changeset patch # User smarks # Date 1356745001 28800 # Node ID 26279f5fc4da6451f5abdac803cf9ba571c1a8e8 # Parent cf325f3b80b15c2855f1f2de9b40bf582d744863# Parent 60d0e9160ae4019f374d4cf3cd7013576a0a9122 Merge diff -r cf325f3b80b1 -r 26279f5fc4da jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Fri Dec 28 18:32:26 2012 -0500 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Fri Dec 28 17:36:41 2012 -0800 @@ -25,16 +25,15 @@ package com.sun.jmx.remote.internal; -import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.remote.security.NotificationAccessController; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; import java.io.IOException; import java.security.AccessControlContext; import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -291,13 +290,18 @@ // so that we can know too, and remove the corresponding entry from the listenerMap. // See 6957378. private void snoopOnUnregister(NotificationResult nr) { - Set delegateSet = listenerMap.get(MBeanServerDelegate.DELEGATE_NAME); - if (delegateSet == null || delegateSet.isEmpty()) { - return; + List copy = null; + synchronized (listenerMap) { + Set delegateSet = listenerMap.get(MBeanServerDelegate.DELEGATE_NAME); + if (delegateSet == null || delegateSet.isEmpty()) { + return; + } + copy = new ArrayList<>(delegateSet); } + for (TargetedNotification tn : nr.getTargetedNotifications()) { Integer id = tn.getListenerID(); - for (IdAndFilter idaf : delegateSet) { + for (IdAndFilter idaf : copy) { if (idaf.id == id) { // This is a notification from the MBeanServerDelegate. Notification n = tn.getNotification(); diff -r cf325f3b80b1 -r 26279f5fc4da jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Fri Dec 28 18:32:26 2012 -0500 +++ b/jdk/test/ProblemList.txt Fri Dec 28 17:36:41 2012 -0800 @@ -148,9 +148,6 @@ # 6959636 javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all -# 7120365 -javax/management/remote/mandatory/notif/DiffHBTest.java generic-all - ############################################################################ # jdk_math diff -r cf325f3b80b1 -r 26279f5fc4da jdk/test/javax/management/remote/mandatory/notif/ConcurrentModificationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/remote/mandatory/notif/ConcurrentModificationTest.java Fri Dec 28 17:36:41 2012 -0800 @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7120365 + * @summary test on Concurrent Modification + * @author Shanliang JIANG + * @run main ConcurrentModificationTest + */ + +import java.net.MalformedURLException; +import java.util.ConcurrentModificationException; +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.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +/** + * + */ +public class ConcurrentModificationTest { + private static final String[] protocols = {"rmi", "iiop", "jmxmp"}; + private static int number = 100; + + private static final MBeanServer mbs = MBeanServerFactory.createMBeanServer(); + private static ObjectName delegateName; + private static ObjectName[] timerNames = new ObjectName[number]; + private static NotificationListener[] listeners = new NotificationListener[number]; + + private static Throwable uncaughtException = null; + + public static void main(String[] args) throws Exception { + System.out.println(">>> test on Concurrent Modification."); + + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + e.printStackTrace(); + if (e instanceof ConcurrentModificationException) { + uncaughtException = e; + } + } + }); + + delegateName = new ObjectName("JMImplementation:type=MBeanServerDelegate"); + for (int i=0; i>> Test for protocol " + protocols[i]); + test(protocols[i]); + if (uncaughtException != null) { + if ("".equals(errors)) { + errors = "Failed to " + protocols[i] + ": "+uncaughtException; + } else { + errors = errors+", failed to " + protocols[i] + ": "+uncaughtException; + } + System.out.println(">>> FAILED for protocol " + protocols[i]); + } else { + System.out.println(">>> PASSED for protocol " + protocols[i]); + } + } + + if ("".equals(errors)) { + System.out.println("All Passed!"); + } else { + System.out.println("!!!!!! Failed."); + + throw new RuntimeException(errors); + } + } + + private static void test(String proto) throws Exception { + JMXServiceURL u = new JMXServiceURL(proto, null, 0); + JMXConnectorServer server; + JMXConnector client; + + try { + server = + JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs); + server.start(); + JMXServiceURL addr = server.getAddress(); + client = JMXConnectorFactory.connect(addr, null); + } catch (MalformedURLException e) { + System.out.println(">>> not support: " + proto); + return; + } + + final MBeanServerConnection mserver = client.getMBeanServerConnection(); + + int count = 0; + boolean adding = true; + while (uncaughtException == null && count++ < 10) { + for (int i = 0; i < number; i++) { + listenerOp(mserver, listeners[i], adding); + mbeanOp(mserver, timerNames[i], adding); + } + adding = !adding; + } + + if (uncaughtException != null) { // clean + for (int i = 0; i < number; i++) { + try { + mbeanOp(mserver, timerNames[i], false); + } catch (Exception e) { + } + } + } + client.close(); + server.stop(); + } + + private static void mbeanOp(MBeanServerConnection mserver, ObjectName name, boolean adding) + throws Exception { + if (adding) { + mserver.createMBean("javax.management.timer.Timer", name); + } else { + mserver.unregisterMBean(name); + } + } + + private static void listenerOp(MBeanServerConnection mserver, NotificationListener listener, boolean adding) + throws Exception { + if (adding) { + mserver.addNotificationListener(delegateName, listener, null, null); + } else { + mserver.removeNotificationListener(delegateName, listener); + } + } +} \ No newline at end of file