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