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  * @run clean NotSerializableNotifTest
  30  * @run build NotSerializableNotifTest
  31  * @run main NotSerializableNotifTest
  32  */
  33 
  34 // java imports
  35 //
  36 import java.net.MalformedURLException;
  37 import javax.management.MBeanNotificationInfo;
  38 import javax.management.MBeanServer;
  39 import javax.management.MBeanServerConnection;
  40 import javax.management.MBeanServerFactory;
  41 import javax.management.Notification;
  42 import javax.management.NotificationBroadcasterSupport;
  43 import javax.management.NotificationListener;
  44 import javax.management.ObjectName;
  45 import javax.management.remote.JMXConnector;
  46 import javax.management.remote.JMXConnectorFactory;
  47 import javax.management.remote.JMXConnectorServer;
  48 import javax.management.remote.JMXConnectorServerFactory;
  49 import javax.management.remote.JMXServiceURL;
  50 
  51 public class NotSerializableNotifTest {
  52     private static final MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
  53     private static ObjectName emitter;
  54 
  55     private static String[] protocols;
  56 
  57     private static final int sentNotifs = 10;
  58 
  59     public static void main(String[] args) throws Exception {
  60         System.out.println(">>> Test to send a not serializable notification");
  61 
  62         // IIOP fails on JDK1.4, see 5034318
  63         final String v = System.getProperty("java.version");
  64         float f = Float.parseFloat(v.substring(0, 3));
  65         if (f<1.5) {
  66             protocols = new String[] {"rmi", "jmxmp"};
  67         } else {
  68             protocols = new String[] {"rmi", "iiop", "jmxmp"};
  69         }
  70 
  71         emitter = new ObjectName("Default:name=NotificationEmitter");
  72         mbeanServer.registerMBean(new NotificationEmitter(), emitter);
  73 
  74         for (int i = 0; i < protocols.length; i++) {
  75             test(protocols[i]);
  76         }
  77 
  78         System.out.println(">>> Test passed");
  79     }
  80 
  81 
  82     private static void test(String proto) throws Exception {
  83         System.out.println("\n>>> Test for protocol " + proto);
  84 
  85         JMXServiceURL url = new JMXServiceURL(proto, null, 0);
  86 
  87         System.out.println(">>> Create a server: "+url);
  88 
  89         JMXConnectorServer server = null;
  90         try {
  91             server = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
  92         } catch (MalformedURLException e) {
  93             System.out.println("System does not recognize URL: " + url +
  94                                "; ignoring");
  95             return;
  96         }
  97 
  98         server.start();
  99 
 100         url = server.getAddress();
 101 
 102         System.out.println(">>> Creating a client connectint to: "+url);
 103         JMXConnector conn = JMXConnectorFactory.connect(url, null);
 104         MBeanServerConnection client = conn.getMBeanServerConnection();
 105 
 106         // add listener from the client side
 107         Listener listener = new Listener();
 108         client.addNotificationListener(emitter, listener, null, null);
 109 
 110         // ask to send one not serializable notif
 111         Object[] params = new Object[] {new Integer(1)};
 112         String[] signatures = new String[] {"java.lang.Integer"};
 113         client.invoke(emitter, "sendNotserializableNotifs", params, signatures);
 114 
 115         // listener clean
 116         client.removeNotificationListener(emitter, listener);
 117         listener = new Listener();
 118         client.addNotificationListener(emitter, listener, null, null);
 119 
 120         //ask to send serializable notifs
 121         params = new Object[] {new Integer(sentNotifs)};
 122         client.invoke(emitter, "sendNotifications", params, signatures);
 123 
 124         // waiting ...
 125         synchronized (listener) {
 126             while (listener.received() < sentNotifs) {
 127                 listener.wait(); // either pass or test timeout (killed by test harness)
 128 
 129             }
 130         }
 131 
 132         // clean
 133         client.removeNotificationListener(emitter, listener);
 134 
 135         conn.close();
 136         server.stop();
 137     }
 138 
 139 //--------------------------
 140 // private classes
 141 //--------------------------
 142 
 143     private static class Listener implements NotificationListener {
 144         public void handleNotification(Notification notif, Object handback) {
 145             synchronized (this) {
 146                 if(++receivedNotifs == sentNotifs) {
 147                     this.notifyAll();
 148                 }
 149             }
 150         }
 151 
 152         public int received() {
 153             return receivedNotifs;
 154         }
 155 
 156         private int receivedNotifs = 0;
 157     }
 158 
 159     public static class NotificationEmitter extends NotificationBroadcasterSupport
 160         implements NotificationEmitterMBean {
 161 
 162         public MBeanNotificationInfo[] getNotificationInfo() {
 163             final String[] ntfTypes = {myType};
 164 
 165             final MBeanNotificationInfo[] ntfInfoArray  = {
 166                 new MBeanNotificationInfo(ntfTypes,
 167                                           "javax.management.Notification",
 168                                           "Notifications sent by the NotificationEmitter")};
 169 
 170             return ntfInfoArray;
 171         }
 172 
 173         /**
 174          * Send not serializable Notifications.
 175          *
 176          * @param nb The number of notifications to send
 177          */
 178         public void sendNotserializableNotifs(Integer nb) {
 179 
 180             Notification notif;
 181             for (int i=1; i<=nb.intValue(); i++) {
 182                 notif = new Notification(myType, this, i);
 183 
 184                 notif.setUserData(new Object());
 185                 sendNotification(notif);
 186             }
 187         }
 188 
 189         /**
 190          * Send Notification objects.
 191          *
 192          * @param nb The number of notifications to send
 193          */
 194         public void sendNotifications(Integer nb) {
 195             Notification notif;
 196             for (int i=1; i<=nb.intValue(); i++) {
 197                 notif = new Notification(myType, this, i);
 198 
 199                 sendNotification(notif);
 200             }
 201         }
 202 
 203         private final String myType = "notification.my_notification";
 204     }
 205 
 206     public interface NotificationEmitterMBean {
 207         public void sendNotifications(Integer nb);
 208 
 209         public void sendNotserializableNotifs(Integer nb);
 210     }
 211 }