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