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
40import java.io.*;
41import java.rmi.*;
42import java.rmi.activation.*;
43import java.rmi.server.*;
44import java.rmi.registry.*;
45import java.util.*;
46
47public 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
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
93    public ForceLogSnapshot() throws RemoteException {
94        UnicastRemoteObject.exportObject(this, 0);
95    }
96
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
111    public void crash() {
112        System.exit(0);
113    }
114
115    public ActivationID getID() {
116        return id;
117    }
118
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     */
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