1 /*
   2  * Copyright (c) 1998, 2014, 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 /* @test
  25  * @bug 4173960
  26  * @summary synopsis: Activatable objects cannot be restarted.
  27  * @author Laird Dornin
  28  *
  29  * @library ../../../testlibrary
  30  * @build TestLibrary RMID ActivationLibrary
  31  *     ActivateMe ForceLogSnapshot_Stub
  32  * @run main/othervm/policy=security.policy/timeout=640 ForceLogSnapshot
  33  */
  34 
  35 import java.io.*;
  36 import java.rmi.*;
  37 import java.rmi.activation.*;
  38 import java.rmi.server.*;
  39 import java.rmi.registry.*;
  40 import java.util.*;
  41 
  42 public class ForceLogSnapshot
  43         implements ActivateMe
  44 {
  45     /** how many activatable remote objects to create to test rmid */
  46     final public static int HOW_MANY = 50;
  47     final public static int NUM_GROUPS = 4;
  48     /** cause RMID to generate a snapshot every 10th activated object */
  49     final public static int SNAPSHOT_INTERVAL = 10;
  50 
  51     private ActivationID id;
  52     private Vector responders = new Vector();
  53 
  54     private static final String RESTARTABLE = "restartable";
  55     private static final String ACTIVATABLE = "activatable";
  56 
  57     private static Object lock = new Object();
  58     private static boolean[] restartedObjects = new boolean[HOW_MANY];
  59     private static boolean[] activatedObjects = new boolean[HOW_MANY];
  60 
  61     public ForceLogSnapshot(ActivationID id, MarshalledObject mobj)
  62         throws ActivationException, RemoteException
  63     {
  64         this.id = id;
  65         int intId = 0;
  66 
  67         Activatable.exportObject(this, id, 0);
  68         ActivateMe obj;
  69         String responder;
  70         try {
  71             Object[] stuff = (Object[]) mobj.get();
  72 
  73             intId = ((Integer) stuff[0]).intValue();
  74             responder = (String) stuff[1];
  75             obj = (ActivateMe) stuff[2];
  76 
  77             System.err.println(responder + " service started");
  78         } catch (Exception e) {
  79             System.err.println("unable to obtain stub from marshalled object");
  80             System.err.println(e.getMessage());
  81             e.printStackTrace();
  82             return;
  83         }
  84 
  85         obj.ping(intId, responder);
  86     }
  87 
  88     public ForceLogSnapshot() throws RemoteException {
  89         UnicastRemoteObject.exportObject(this, 0);
  90     }
  91 
  92     public void ping(int intId, String responder) {
  93         System.err.println("ForceLogSnapshot: received ping from " +
  94                            responder);
  95         if (responder.equals(RESTARTABLE)) {
  96             synchronized (lock) {
  97                 restartedObjects[intId] = true;
  98             }
  99         } else if (responder.equals(ACTIVATABLE)) {
 100             synchronized (lock) {
 101                 activatedObjects[intId] = true;
 102             }
 103         }
 104     }
 105 
 106     public void crash() {
 107         System.exit(0);
 108     }
 109 
 110     public ActivationID getID() {
 111         return id;
 112     }
 113 
 114     public static void main(String[] args) {
 115 
 116         System.out.println("\nRegression test for bug 4173960\n");
 117 
 118         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
 119 
 120         RMID rmid = null;
 121         ForceLogSnapshot[] unicastObjs = new ForceLogSnapshot[HOW_MANY];
 122 
 123         try {
 124             String option = " -Dsun.rmi.activation.snapshotInterval=" +
 125                 SNAPSHOT_INTERVAL;
 126 
 127             RMID.removeLog();
 128             rmid = RMID.createRMID();
 129             rmid.addOptions(new String[] {option, "-Djava.compiler="});
 130             rmid.start();
 131 
 132             /* Cause activation groups to have a security policy that will
 133              * allow security managers to be downloaded and installed
 134              */
 135             Properties p = new Properties();
 136             // this test must always set policies/managers in its
 137             // activation groups
 138             p.put("java.security.policy",
 139                   TestParams.defaultGroupPolicy);
 140             p.put("java.security.manager",
 141                   TestParams.defaultSecurityManager);
 142 
 143             Object[][] stuff = new Object[HOW_MANY][];
 144             MarshalledObject restartMobj = null;
 145             ActivationGroupDesc groupDesc = null;
 146             MarshalledObject activateMobj = null;
 147             ActivationGroupID[] groupIDs = new ActivationGroupID[NUM_GROUPS];
 148             ActivationDesc restartableDesc = null;
 149             ActivationDesc activatableDesc = null;
 150             ActivateMe[] restartableObj = new ActivateMe[HOW_MANY];
 151             ActivateMe[] activatableObj = new ActivateMe[HOW_MANY];
 152 
 153             /*
 154              * Create unicast object to be contacted when service is activated.
 155              */
 156             int group = 0;
 157             int groupNo = 0;
 158             for (int i = 0 ; i < HOW_MANY ; i ++ ) {
 159 
 160                 System.err.println("Creating descriptors and remote objects");
 161 
 162                 unicastObjs[i] = new ForceLogSnapshot();
 163 
 164                 /*
 165                  * Create and register descriptors for a restartable and
 166                  * non-restartable service (respectively) in a group other than
 167                  * this VM's group.
 168                  */
 169                 stuff[i] = new Object[] { new Integer(i),
 170                                               RESTARTABLE, unicastObjs[i] };
 171                 restartMobj = new MarshalledObject(stuff[i]);
 172 
 173                 stuff[i][1] = ACTIVATABLE;
 174                 activateMobj = new MarshalledObject(stuff[i]);
 175 
 176                 groupDesc =
 177                     new ActivationGroupDesc(p, null);
 178 
 179                 if (i < NUM_GROUPS) {
 180                     groupNo = i;
 181                     groupIDs[groupNo] =
 182                         ActivationGroup.getSystem().
 183                         registerGroup(groupDesc);
 184                 } else {
 185                     groupNo = (group++)%NUM_GROUPS;
 186                 }
 187 
 188                 System.err.println("Objects group number: " + groupNo);
 189 
 190                 restartableDesc =
 191                     new ActivationDesc(groupIDs[groupNo], "ForceLogSnapshot", null,
 192                                        restartMobj, true);
 193 
 194                 activatableDesc =
 195                     new ActivationDesc(groupIDs[groupNo], "ForceLogSnapshot", null,
 196                                        activateMobj, false);
 197 
 198                 System.err.println("Registering descriptors");
 199                 restartableObj[i] =
 200                     (ActivateMe) Activatable.register(restartableDesc);
 201 
 202                 activatableObj[i] =
 203                     (ActivateMe) Activatable.register(activatableDesc);
 204                 System.err.println("registered activatable #: " + i);
 205 
 206                 // start reusing groups if we need to do so.
 207             }
 208 
 209             int repeatOnce = 1;
 210             do {
 211 
 212                 /*
 213                  * Restart rmid; it should start up the restartable service
 214                  */
 215                 rmid.restart();
 216 
 217                 if (howManyRestarted(restartedObjects, 10) < HOW_MANY) {
 218                         TestLibrary.bomb("Test1 failed: a service would not " +
 219                                          "restart");
 220                 }
 221                 System.err.println("Test1 passed: rmid " +
 222                                    "all service(s) restarted. Performing next test.");
 223 
 224                 /*
 225                  * Make sure no activatable services were automatically
 226                  * restarted.
 227                  */
 228                 if (howManyRestarted(activatedObjects, 2) != 0) {
 229                     TestLibrary.bomb("Test2 failed: activatable service restarted!",
 230                                      null);
 231                 }
 232                 System.err.println("Test2 passed: rmid did not " +
 233                                    "restart activatable service(s)");
 234 
 235                 if (repeatOnce > 0) {
 236                     try {
 237                         System.err.println("\nCrash restartable object");
 238                         for (int i = 0 ; i < HOW_MANY ; i ++) {
 239                             restartableObj[i].crash();
 240                         }
 241                     } catch (Exception e) {
 242                     }
 243                 }
 244 
 245             } while (repeatOnce-- > 0);
 246 
 247 
 248         } catch (Exception e) {
 249             TestLibrary.bomb("test failed", e);
 250         } finally {
 251             rmid.cleanup();
 252             for (int i = 0 ; i < HOW_MANY ; i ++) {
 253                 TestLibrary.unexport(unicastObjs[i]);
 254             }
 255         }
 256     }
 257 
 258     /**
 259      * Check to see how many services have been automatically
 260      * restarted.
 261      */
 262     private static int howManyRestarted(boolean[] startedObjects, int retries) {
 263         int succeeded = 0;
 264         int restarted = 0;
 265         int atry = 0;
 266 
 267         while ((restarted < HOW_MANY) && (atry < retries)) {
 268             restarted = 0;
 269             for (int j = 0 ; j < HOW_MANY ; j ++ ) {
 270                 synchronized(lock) {
 271                     if (startedObjects[j]) {
 272                         restarted ++;
 273                     }
 274                 }
 275             }
 276             System.err.println("not all objects restarted, retrying...");
 277             try {
 278                 Thread.sleep(10000);
 279             } catch (InterruptedException ie) {
 280             }
 281             atry ++;
 282         }
 283         return restarted;
 284     }
 285 }