1 /*
   2  * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @summary Tests to send a not serializable notification.
  27  * @bug 5022196
  28  * @author Shanliang JIANG
  29  * @modules java.management
  30  * @run clean NotSerializableNotifTest
  31  * @run build NotSerializableNotifTest
  32  * @run main NotSerializableNotifTest
  33  */
  34 
  35 // java imports
  36 //
  37 import java.net.MalformedURLException;
  38 import javax.management.MBeanNotificationInfo;
  39 import javax.management.MBeanServer;
  40 import javax.management.MBeanServerConnection;
  41 import javax.management.MBeanServerFactory;
  42 import javax.management.Notification;
  43 import javax.management.NotificationBroadcasterSupport;
  44 import javax.management.NotificationListener;
  45 import javax.management.ObjectName;
  46 import javax.management.remote.JMXConnector;
  47 import javax.management.remote.JMXConnectorFactory;
  48 import javax.management.remote.JMXConnectorServer;
  49 import javax.management.remote.JMXConnectorServerFactory;
  50 import javax.management.remote.JMXServiceURL;
  51 
  52 public class NotSerializableNotifTest {
  53     private static final MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
  54     private static ObjectName emitter;
  55 
  56     private static String[] protocols;
  57 
  58     private static final int sentNotifs = 10;
  59 
  60     public static void main(String[] args) throws Exception {
  61         System.out.println(">>> Test to send a not serializable notification");
  62 
  63         // IIOP fails on JDK1.4, see 5034318
  64         final String v = System.getProperty("java.version");
  65         float f = Float.parseFloat(v.substring(0, 3));
  66         if (f<1.5) {
  67             protocols = new String[] {"rmi", "jmxmp"};
  68         } else {
  69             protocols = new String[] {"rmi", "iiop", "jmxmp"};
  70         }
  71 
  72         emitter = new ObjectName("Default:name=NotificationEmitter");
  73         mbeanServer.registerMBean(new NotificationEmitter(), emitter);
  74 
  75         for (int i = 0; i < protocols.length; i++) {
  76             test(protocols[i]);
  77         }
  78 
  79         System.out.println(">>> Test passed");
  80     }
  81 
  82 
  83     private static void test(String proto) throws Exception {
  84         System.out.println("\n>>> Test for protocol " + proto);
  85 
  86         JMXServiceURL url = new JMXServiceURL(proto, null, 0);
  87 
  88         System.out.println(">>> Create a server: "+url);
  89 
  90         JMXConnectorServer server = null;
  91         try {
  92             server = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
  93         } catch (MalformedURLException e) {
  94             System.out.println("System does not recognize URL: " + url +
  95                                "; ignoring");
  96             return;
  97         }
  98 
  99         server.start();
 100 
 101         url = server.getAddress();
 102 
 103         System.out.println(">>> Creating a client connectint to: "+url);
 104         JMXConnector conn = JMXConnectorFactory.connect(url, null);
 105         MBeanServerConnection client = conn.getMBeanServerConnection();
 106 
 107         // add listener from the client side
 108         Listener listener = new Listener();
 109         client.addNotificationListener(emitter, listener, null, null);
 110 
 111         // ask to send one not serializable notif
 112         Object[] params = new Object[] {new Integer(1)};
 113         String[] signatures = new String[] {"java.lang.Integer"};
 114         client.invoke(emitter, "sendNotserializableNotifs", params, signatures);
 115 
 116         // listener clean
 117         client.removeNotificationListener(emitter, listener);
 118         listener = new Listener();
 119         client.addNotificationListener(emitter, listener, null, null);
 120 
 121         //ask to send serializable notifs
 122         params = new Object[] {new Integer(sentNotifs)};
 123         client.invoke(emitter, "sendNotifications", params, signatures);
 124 
 125         // waiting ...
 126         synchronized (listener) {
 127             while (listener.received() < sentNotifs) {
 128                 listener.wait(); // either pass or test timeout (killed by test harness)
 129 
 130             }
 131         }
 132 
 133         // clean
 134         client.removeNotificationListener(emitter, listener);
 135 
 136         conn.close();
 137         server.stop();
 138     }
 139 
 140 //--------------------------
 141 // private classes
 142 //--------------------------
 143 
 144     private static class Listener implements NotificationListener {
 145         public void handleNotification(Notification notif, Object handback) {
 146             synchronized (this) {
 147                 if(++receivedNotifs == sentNotifs) {
 148                     this.notifyAll();
 149                 }
 150             }
 151         }
 152 
 153         public int received() {
 154             return receivedNotifs;
 155         }
 156 
 157         private int receivedNotifs = 0;
 158     }
 159 
 160     public static class NotificationEmitter extends NotificationBroadcasterSupport
 161         implements NotificationEmitterMBean {
 162 
 163         public MBeanNotificationInfo[] getNotificationInfo() {
 164             final String[] ntfTypes = {myType};
 165 
 166             final MBeanNotificationInfo[] ntfInfoArray  = {
 167                 new MBeanNotificationInfo(ntfTypes,
 168                                           "javax.management.Notification",
 169                                           "Notifications sent by the NotificationEmitter")};
 170 
 171             return ntfInfoArray;
 172         }
 173 
 174         /**
 175          * Send not serializable Notifications.
 176          *
 177          * @param nb The number of notifications to send
 178          */
 179         public void sendNotserializableNotifs(Integer nb) {
 180 
 181             Notification notif;
 182             for (int i=1; i<=nb.intValue(); i++) {
 183                 notif = new Notification(myType, this, i);
 184 
 185                 notif.setUserData(new Object());
 186                 sendNotification(notif);
 187             }
 188         }
 189 
 190         /**
 191          * Send Notification objects.
 192          *
 193          * @param nb The number of notifications to send
 194          */
 195         public void sendNotifications(Integer nb) {
 196             Notification notif;
 197             for (int i=1; i<=nb.intValue(); i++) {
 198                 notif = new Notification(myType, this, i);
 199 
 200                 sendNotification(notif);
 201             }
 202         }
 203 
 204         private final String myType = "notification.my_notification";
 205     }
 206 
 207     public interface NotificationEmitterMBean {
 208         public void sendNotifications(Integer nb);
 209 
 210         public void sendNotserializableNotifs(Integer nb);
 211     }
 212 }