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