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