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 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 * @key intermittent 43 */ 44 45 import java.io.*; 46 import java.rmi.*; 47 import java.rmi.server.*; 48 import java.rmi.activation.*; 49 import sun.rmi.server.ActivatableRef; 50 import java.lang.reflect.*; 51 import java.util.Properties; 52 53 public 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 rmid.cleanup(); 267 obj = null; 268 } 269 } 270 }