1 /*
   2  * Copyright (c) 1998, 2012, 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 4134233
  26  * @bug 4213186
  27  *
  28  * @summary synopsis: ActivationSystem.unregisterGroup should unregister objects in group
  29  * @author Ann Wollrath
  30  *
  31  * @library ../../../testlibrary
  32  * @build TestLibrary RMID JavaVM StreamPipe
  33  * @build ActivateMe CallbackInterface
  34  * @build UnregisterGroup
  35  * @build UnregisterGroup_Stub
  36  * @build Callback_Stub
  37  * @run main/othervm/policy=security.policy/timeout=480 UnregisterGroup
  38  */
  39 
  40 import java.io.*;
  41 import java.rmi.*;
  42 import java.rmi.activation.*;
  43 import java.rmi.server.*;
  44 import java.rmi.registry.*;
  45 import java.util.Properties;
  46 
  47 class Callback extends UnicastRemoteObject implements CallbackInterface {
  48 
  49   public static int num_deactivated = 0;
  50 
  51   public Callback() throws RemoteException { super(); }
  52 
  53   public void inc() throws RemoteException {
  54     incNumDeactivated();
  55   }
  56 
  57   public synchronized int getNumDeactivated() throws RemoteException {
  58     return(num_deactivated);
  59   }
  60 
  61   public synchronized void incNumDeactivated() {
  62     num_deactivated++;
  63   }
  64 
  65 }
  66 
  67 public class UnregisterGroup
  68         extends Activatable
  69         implements ActivateMe, Runnable
  70 {
  71 
  72     private static Exception exception = null;
  73     private static String error = null;
  74     private static boolean done = false;
  75     private static ActivateMe lastResortExitObj = null;
  76     private static final int NUM_OBJECTS = 10;
  77     private static int registryPort = -1;
  78 
  79     public UnregisterGroup(ActivationID id, MarshalledObject mobj)
  80         throws Exception
  81     {
  82         super(id, 0);
  83     }
  84 
  85     public void ping()
  86     {}
  87 
  88     public void unregister() throws Exception {
  89         super.unregister(super.getID());
  90     }
  91 
  92     /**
  93      * Spawns a thread to deactivate the object.
  94      */
  95     public void shutdown() throws Exception {
  96         (new Thread(this,"UnregisterGroup")).start();
  97     }
  98 
  99     /**
 100      * To support exiting of group VM as a last resort
 101      */
 102     public void justGoAway() {
 103         System.exit(0);
 104     }
 105 
 106     /**
 107      * Thread to deactivate object. First attempts to make object
 108      * inactive (via the inactive method).  If that fails (the
 109      * object may still have pending/executing calls), then
 110      * unexport the object forcibly.
 111      */
 112     public void run() {
 113 
 114         ActivationLibrary.deactivate(this, getID());
 115         System.err.println("\tActivationLibrary.deactivate returned");
 116 
 117         try {
 118             CallbackInterface cobj =
 119                 (CallbackInterface)Naming.lookup("//:" + registryPort + "/Callback");
 120             cobj.inc();
 121         } catch (Exception e) {
 122             System.err.println("cobj.inc exception");
 123             e.printStackTrace();
 124         }
 125 
 126     }
 127 
 128     public static void main(String[] args) {
 129 
 130         Registry registry;
 131 
 132         System.err.println("\nRegression test for bug 4134233\n");
 133 
 134         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
 135         RMID rmid = null;
 136 
 137         try {
 138             RMID.removeLog();
 139             rmid = RMID.createRMID();
 140             rmid.start();
 141 
 142             /* Cause activation groups to have a security policy that will
 143              * allow security managers to be downloaded and installed
 144              */
 145             final Properties p = new Properties();
 146             // this test must always set policies/managers in its
 147             // activation groups
 148             p.put("java.security.policy",
 149                   TestParams.defaultGroupPolicy);
 150             p.put("java.security.manager",
 151                   TestParams.defaultSecurityManager);
 152 
 153             //final int NUM_OBJECTS = 10;
 154 
 155             Thread t = new Thread() {
 156                 public void run () {
 157                     try {
 158                         System.err.println("Creating group descriptor");
 159                         ActivationGroupDesc groupDesc =
 160                             new ActivationGroupDesc(p, null);
 161                         ActivationSystem system = ActivationGroup.getSystem();
 162                         ActivationGroupID groupID =
 163                             system.registerGroup(groupDesc);
 164 
 165                         ActivateMe[] obj = new ActivateMe[NUM_OBJECTS];
 166 
 167                         for (int i = 0; i < NUM_OBJECTS; i++) {
 168                             System.err.println("Creating descriptor: " + i);
 169                             ActivationDesc desc =
 170                                 new ActivationDesc(groupID, "UnregisterGroup",
 171                                                    null, null);
 172                             System.err.println("Registering descriptor: " + i);
 173                             obj[i] = (ActivateMe) Activatable.register(desc);
 174                             System.err.println("Activating object: " + i);
 175                             obj[i].ping();
 176                         }
 177                         lastResortExitObj = obj[0];
 178 
 179                         System.err.println("Unregistering group");
 180                         system.unregisterGroup(groupID);
 181 
 182                         try {
 183                             System.err.println("Get the group descriptor");
 184                             system.getActivationGroupDesc(groupID);
 185                             error = "test failed: group still registered";
 186                         } catch (UnknownGroupException e) {
 187                             System.err.println("Test passed: " +
 188                                                "group unregistered");
 189                         }
 190 
 191 
 192                         /*
 193                          * Deactivate objects so group VM will exit.
 194                          */
 195                         for (int i = 0; i < NUM_OBJECTS; i++) {
 196                             System.err.println("Deactivating object: " + i);
 197                             obj[i].shutdown();
 198                             obj[i] = null;
 199                         }
 200                         lastResortExitObj = null;
 201 
 202                     } catch (Exception e) {
 203                         exception = e;
 204                     }
 205 
 206                     done = true;
 207                 }
 208             };
 209 
 210             t.start();
 211             t.join(120000);
 212 
 213             if (exception != null) {
 214                 TestLibrary.bomb("test failed", exception);
 215             } else if (error != null) {
 216                 TestLibrary.bomb(error, null);
 217             } else if (!done) {
 218                 TestLibrary.bomb("test failed: not completed before timeout", null);
 219             } else {
 220                 System.err.println("Test passed");
 221             }
 222 
 223 
 224         } catch (Exception e) {
 225             TestLibrary.bomb("test failed", e);
 226         } finally {
 227             if (lastResortExitObj != null) {
 228                 try {
 229                     lastResortExitObj.justGoAway();
 230                 } catch (Exception munch) {
 231                 }
 232             }
 233 
 234             // Wait for the object deactivation to take place first
 235             try {
 236 
 237                 // create reg and export callback object
 238                 registry = TestLibrary.createRegistryOnUnusedPort();
 239                 registryPort = TestLibrary.getRegistryPort(registry);
 240                 Callback robj = new Callback();
 241                 registry.bind("Callback", robj);
 242 
 243                 //get the callback object
 244                 int maxwait=30;
 245                 int nd = robj.getNumDeactivated();
 246                 while ((nd < NUM_OBJECTS) && (maxwait> 0)) {
 247                     System.err.println("num_deactivated="+nd);
 248                     try {
 249                         Thread.sleep(1000);
 250                     } catch (InterruptedException ie) {}
 251                     maxwait--;
 252                     nd = robj.getNumDeactivated();
 253                 }
 254             } catch (Exception ce) {
 255                 System.err.println("E:"+ce);
 256                 ce.printStackTrace();
 257             }
 258 
 259             ActivationLibrary.rmidCleanup(rmid);
 260         }
 261     }
 262 }