blob: a8af98c654272ba16256a2f828087ea62b887910 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-1999 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 * @bug 4105080
26 * @summary Activation retry during a remote method call to an activatable
27 * object can cause infinite recursion in some situations. The
28 * RemoteRef contained in the ActivatableRef should never be
29 * an ActivatableRef, but another type.
30 * (Needs /othervm to evade JavaTest security manager --aecolley)
31 * @author Ann Wollrath
32 *
33 * @bug 4164971
34 * @summary allow non-public activatable class and/or constructor
35 * Main test class hasa non-public constructor to ensure
36 * functionality is in place
37 *
38 * @library ../../../testlibrary
39 * @build TestLibrary RMID
40 * @build ActivateMe CheckActivateRef_Stub CheckActivateRef
41 * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=true CheckActivateRef
42 * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=false CheckActivateRef
43 */
44
45import java.io.*;
46import java.rmi.*;
47import java.rmi.server.*;
48import java.rmi.activation.*;
49import sun.rmi.server.ActivatableRef;
50import java.lang.reflect.*;
51import java.util.Properties;
52
53public class CheckActivateRef
54 extends Activatable
55 implements ActivateMe, Runnable
56{
57
58 private CheckActivateRef(ActivationID id, MarshalledObject obj)
59 throws ActivationException, RemoteException
60 {
61 super(id, 0);
62 }
63
64 public void ping()
65 {}
66
67 /**
68 * Spawns a thread to deactivate the object.
69 */
70 public void shutdown() throws Exception
71 {
72 (new Thread(this,"CheckActivateRef")).start();
73 }
74
75 /**
76 * Thread to deactivate object. First attempts to make object
77 * inactive (via the inactive method). If that fails (the
78 * object may still have pending/executing calls), then
79 * unexport the object forcibly.
80 */
81 public void run() {
82 ActivationLibrary.deactivate(this, getID());
83 }
84
85 public static void main(String[] args) {
86 /*
87 * The following line is required with the JDK 1.2 VM so that the
88 * VM can exit gracefully when this test completes. Otherwise, the
89 * conservative garbage collector will find a handle to the server
90 * object on the native stack and not clear the weak reference to
91 * it in the RMI runtime's object table.
92 */
93 Object dummy = new Object();
94 RMID rmid = null;
95 ActivateMe obj;
96
97 // test should tolerate certain types of failures
98 int failures = 0;
99 int i = 0;
100
101 System.err.println("\nRegression test for bug 4105080\n");
102 System.err.println("java.security.policy = " +
103 System.getProperty("java.security.policy",
104 "no policy"));
105
106
107 String propValue =
108 System.getProperty("java.rmi.server.useDynamicProxies", "false");
109 boolean useDynamicProxies = Boolean.parseBoolean(propValue);
110
111 CheckActivateRef server;
112 try {
113 TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager);
114
115 // start an rmid.
116 RMID.removeLog();
117 rmid = RMID.createRMID();
118 rmid.start();
119
120 /* Cause activation groups to have a security policy that will
121 * allow security managers to be downloaded and installed
122 */
123 Properties p = new Properties();
124 // this test must always set policies/managers in its
125 // activation groups
126 p.put("java.security.policy",
127 TestParams.defaultGroupPolicy);
128 p.put("java.security.manager",
129 TestParams.defaultSecurityManager);
130 p.put("java.rmi.server.useDynamicProxies", propValue);
131
132 /*
133 * Activate an object by registering its object
134 * descriptor and invoking a method on the
135 * stub returned from the register call.
136 */
137 System.err.println("Create activation group in this VM");
138 ActivationGroupDesc groupDesc =
139 new ActivationGroupDesc(p, null);
140 ActivationSystem system = ActivationGroup.getSystem();
141 ActivationGroupID groupID = system.registerGroup(groupDesc);
142 ActivationGroup.createGroup(groupID, groupDesc, 0);
143 System.err.println("Creating descriptor");
144 ActivationDesc desc =
145 new ActivationDesc("CheckActivateRef", null, null);
146 System.err.println("Registering descriptor");
147 obj = (ActivateMe) Activatable.register(desc);
148
149 System.err.println("proxy = " + obj);
150
151 if (useDynamicProxies && !Proxy.isProxyClass(obj.getClass()))
152 {
153 throw new RuntimeException("proxy is not dynamic proxy");
154 }
155
156 /*
157 * Loop a bunch of times to force activator to
158 * spawn VMs (groups)
159 */
160 try {
161 for (; i < 7; i++) {
162
163 System.err.println("Activate object via method call");
164
165 /*
166 * Fix for 4277196: if we got an inactive group
167 * exception, it is likely that we accidentally
168 * invoked a method on an old activation
169 * group. Give some time for the group to go away
170 * and then retry the activation.
171 */
172 try {
173 obj.ping();
174 } catch (RemoteException e) {
175 Exception detail = (Exception) e.detail;
176 if ((detail != null) &&
177 (detail instanceof ActivationException) &&
178 (detail.getMessage().equals("group is inactive")))
179 {
180 try {
181 Thread.sleep(5000);
182 } catch (InterruptedException ex) {
183 }
184 obj.ping();
185
186 } else {
187 throw e;
188 }
189 }
190
191 System.err.println("proxy = " + obj);
192
193 /*
194 * Now that object is activated, check to make sure that
195 * the RemoteRef inside the stub's ActivatableRef
196 * is *not* an ActivatableRef.
197 */
198 ActivatableRef aref;
199 if (obj instanceof RemoteStub) {
200 aref = (ActivatableRef) ((RemoteObject) obj).getRef();
201 } else if (Proxy.isProxyClass(obj.getClass())) {
202 RemoteObjectInvocationHandler handler =
203 (RemoteObjectInvocationHandler)
204 Proxy.getInvocationHandler(obj);
205 aref = (ActivatableRef) handler.getRef();
206 } else {
207 throw new RuntimeException("unknown proxy type");
208 }
209
210 final ActivatableRef ref = aref;
211 Field f = (Field)
212 java.security.AccessController.doPrivileged
213 (new java.security.PrivilegedExceptionAction() {
214 public Object run() throws Exception {
215 Field ff = ref.getClass().getDeclaredField("ref");
216 ff.setAccessible(true);
217 return ff;
218 }
219 });
220 Object insideRef = f.get(ref);
221 System.err.println("insideRef = " + insideRef);
222 if (insideRef instanceof ActivatableRef) {
223 TestLibrary.bomb("Embedded ref is an ActivatableRef");
224 } else {
225 System.err.println("ActivatableRef's embedded ref type: " +
226 insideRef.getClass().getName());
227 }
228
229 /*
230 * Clean up object too.
231 */
232 System.err.println("Deactivate object via method call");
233 obj.shutdown();
234
235 try {
236 // give activation group time to go away
237 Thread.sleep(3000);
238 } catch (InterruptedException e) {
239 }
240 }
241 } catch (java.rmi.UnmarshalException ue) {
242 // account for test's activation race condition
243 if (ue.detail instanceof java.io.IOException) {
244 if ((failures ++) >= 3) {
245 throw ue;
246 }
247 } else {
248 throw ue;
249 }
250 }
251
252 System.err.println("\nsuccess: CheckActivateRef test passed ");
253
254 } catch (java.rmi.activation.ActivationException e) {
255 // test only needs to pass 3 times in 7
256 if (i < 4) {
257 TestLibrary.bomb(e);
258 }
259 } catch (Exception e) {
260 if (e instanceof java.security.PrivilegedActionException)
261 e = ((java.security.PrivilegedActionException)e).getException();
262 TestLibrary.bomb("\nfailure: unexpected exception " +
263 e.getClass().getName(), e);
264
265 } finally {
266 ActivationLibrary.rmidCleanup(rmid);
267 obj = null;
268 }
269 }
270}