Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java
38867 views
/*1* Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 619989926* @summary Tests reconnection done by a fetching notif thread.27* @author Shanliang JIANG28* @run clean NotifReconnectDeadlockTest29* @run build NotifReconnectDeadlockTest30* @run main NotifReconnectDeadlockTest31*/3233import java.util.HashMap;34import java.util.Map;35import javax.management.MBeanServer;36import javax.management.MBeanServerFactory;37import javax.management.Notification;38import javax.management.NotificationBroadcasterSupport;39import javax.management.NotificationListener;40import javax.management.ObjectName;41import javax.management.remote.JMXConnectionNotification;42import javax.management.remote.JMXConnector;43import javax.management.remote.JMXConnectorFactory;44import javax.management.remote.JMXConnectorServer;45import javax.management.remote.JMXConnectorServerFactory;46import javax.management.remote.JMXServiceURL;4748/**49* "This test checks for a bug whereby reconnection did not work if (a) it was50* initiated by the fetchNotifications thread and (b) it succeeded. These conditions51* are not usual, since connection failure is usually caused by either idle timeout52* (which doesn't usually happen if fetchNotifications is running) or communication53* problems (which are usually permanent so reconnection fails). But they can happen,54* so we test for them here.55* The test sets a very short idle timeout, and effectively suspends the56* fetchNotifications thread by having it invoke a listener with a delay in it.57* This means that the idle timeout happens. When the delayed listener returns,58* the fetchNotifications thread will attempt to reconnect, and this attempt should59* succeed, so we meet the two conditions above.60* The test succeeds if there is indeed a reconnection, detected by the connection61* listener seeing an OPENED notification. The connection listener should not see62* a CLOSED or FAILED notification."63*/64public class NotifReconnectDeadlockTest {6566public static void main(String[] args) throws Exception {67System.out.println(68">>> Tests reconnection done by a fetching notif thread.");6970ObjectName oname = new ObjectName ("Default:name=NotificationEmitter");71JMXServiceURL url = new JMXServiceURL("rmi", null, 0);72Map env = new HashMap(2);73env.put("jmx.remote.x.server.connection.timeout", new Long(serverTimeout));74env.put("jmx.remote.x.client.connection.check.period", new Long(Long.MAX_VALUE));7576final MBeanServer mbs = MBeanServerFactory.newMBeanServer();7778mbs.registerMBean(new NotificationEmitter(), oname);79JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer(80url,81env,82mbs);83server.start();8485JMXServiceURL addr = server.getAddress();86JMXConnector client = JMXConnectorFactory.connect(addr, env);8788Thread.sleep(100); // let pass the first client open notif if there is89client.getMBeanServerConnection().addNotificationListener(oname,90listener,91null,92null);9394client.addConnectionNotificationListener(listener, null, null);9596// max test time: 2 minutes97final long end = System.currentTimeMillis()+120000;9899synchronized(lock) {100while(clientState == null && System.currentTimeMillis() < end) {101mbs.invoke(oname, "sendNotifications",102new Object[] {new Notification("MyType", "", 0)},103new String[] {"javax.management.Notification"});104105try {106lock.wait(10);107} catch (Exception e) {}108}109}110111if (clientState == null) {112throw new RuntimeException(113"No reconnection happened, need to reconfigure the test.");114} else if (JMXConnectionNotification.FAILED.equals(clientState) ||115JMXConnectionNotification.CLOSED.equals(clientState)) {116throw new RuntimeException("Failed to reconnect.");117}118119System.out.println(">>> Passed!");120121client.removeConnectionNotificationListener(listener);122client.close();123server.stop();124}125126//--------------------------127// private classes128//--------------------------129public static class NotificationEmitter extends NotificationBroadcasterSupport130implements NotificationEmitterMBean {131132public void sendNotifications(Notification n) {133sendNotification(n);134}135}136137public interface NotificationEmitterMBean {138public void sendNotifications(Notification n);139}140141private final static NotificationListener listener = new NotificationListener() {142public void handleNotification(Notification n, Object hb) {143144// treat the client notif to know the end145if (n instanceof JMXConnectionNotification) {146if (!JMXConnectionNotification.NOTIFS_LOST.equals(n.getType())) {147148clientState = n.getType();149System.out.println(150">>> The client state has been changed to: "+clientState);151152synchronized(lock) {153lock.notifyAll();154}155}156157return;158}159160System.out.println(">>> Do sleep to make reconnection.");161synchronized(lock) {162try {163lock.wait(listenerSleep);164} catch (Exception e) {165// OK166}167}168}169};170171private static final long serverTimeout = 1000;172private static final long listenerSleep = serverTimeout*6;173174private static String clientState = null;175private static final int[] lock = new int[0];176}177178179