1 /* 2 * Copyright (c) 1999, 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 4183169 8032050 26 * @summary Minor problem with the way ReliableLog handles IOExceptions. 27 * 28 * @author Laird Dornin; code borrowed from Ann Wollrath 29 * 30 * @library ../../../testlibrary 31 * @modules java.rmi/sun.rmi.registry 32 * java.rmi/sun.rmi.server 33 * java.rmi/sun.rmi.transport 34 * java.rmi/sun.rmi.transport.tcp 35 * @build TestLibrary RMID 36 * TestSecurityManager RegisteringActivatable ShutdownGracefully_Stub 37 * @run main/othervm/policy=security.policy/timeout=700 ShutdownGracefully 38 */ 39 40 import java.rmi.activation.*; 41 import java.rmi.*; 42 import java.util.Properties; 43 import java.util.concurrent.TimeoutException; 44 45 /** 46 * The test creates an rmid with a special security manager. After 47 * rmid makes two registrations (which is greater than rmid's 48 * snapshotInterval) the security manager stops allowing rmid to write 49 * to update and snapshot log files in rmid's log directory. The Test 50 * registers an Activatable object twice with different group ids. 51 * The second registration will cause rmid to have to write to a 52 * LogFile (it causes a snapshot) and the security manager will not 53 * allow the file write to happen. The test makes sure that rmid 54 * shuts down in a graceful manner without any explicit request to do 55 * so. The test will not exit for 400 seconds if rmid does not exit 56 * (after that time, the test will fail). 57 */ 58 public class ShutdownGracefully 59 extends Activatable implements RegisteringActivatable 60 { 61 private static RegisteringActivatable registering = null; 62 63 private final static long SHUTDOWN_TIMEOUT = 400 * 1000; 64 65 public static void main(String args[]) { 66 67 RMID rmid = null; 68 69 // Save exception if there is a exception or expected behavior 70 Exception exception = null; 71 System.err.println("\nRegression test for bug/rfe 4183169\n"); 72 73 try { 74 TestLibrary.suggestSecurityManager( 75 "java.rmi.RMISecurityManager"); 76 77 // start an rmid. 78 RMID.removeLog(); 79 rmid = RMID.createRMID(); 80 81 // rmid needs to run with a security manager that 82 // simulates a log problem; rmid should also snapshot 83 // quickly. 84 rmid.addOptions(new String[] { 85 "-Djava.security.manager=TestSecurityManager", 86 "-Dsun.rmi.activation.snapshotInterval=1"}); 87 88 // rmid.addArguments(new String[] { 89 // "-C-Djava.rmi.server.logCalls=true"}); 90 91 rmid.start(); 92 93 // Ensure that activation groups run with the correct 94 // security manager. 95 // 96 Properties p = new Properties(); 97 p.put("java.security.policy", 98 TestParams.defaultGroupPolicy); 99 p.put("java.security.manager", 100 "java.lang.SecurityManager"); 101 102 System.err.println("activation group will be created " + 103 "in a new VM"); 104 ActivationGroupDesc groupDesc = 105 new ActivationGroupDesc(p, null); 106 ActivationSystem system = ActivationGroup.getSystem(); 107 ActivationGroupID groupID = system.registerGroup(groupDesc); 108 109 System.err.println("registering activatable"); 110 ActivationDesc desc = new ActivationDesc 111 (groupID, "ShutdownGracefully", null, null); 112 registering = (RegisteringActivatable) 113 Activatable.register(desc); 114 115 System.err.println("activate and deactivate object " + 116 "via method call"); 117 registering.shutdown(); 118 119 /* 120 * the security manager rmid is running with will stop 121 * rmid from writing to its log files; in 1.2.x this would 122 * have caused rmid to have thrown a runtime exception and 123 * continue running in an unstable state. With the fix 124 * for 4183169, rmid should shutdown gracefully instead. 125 */ 126 127 /* 128 * register another activatable with a new group id; rmid 129 * should not recover from this... I use two 130 * registrations to more closely simulate the environment 131 * in which the bug was found. In java versions with out 132 * the appropriate bug fix, rmid would hide a 133 * NullPointerException in this circumstance. 134 */ 135 p.put("dummyname", "dummyvalue"); 136 groupDesc = new ActivationGroupDesc(p, null); 137 ActivationGroupID secondGroupID = 138 system.registerGroup(groupDesc); 139 desc = new ActivationDesc(secondGroupID, 140 "ShutdownGracefully", null, null); 141 142 /* 143 * registration request is expected to be failed. succeeded case 144 * should be recorded. And raise error after clean up rmid. 145 */ 146 try { 147 registering = (RegisteringActivatable) 148 Activatable.register(desc); 149 System.err.println("The registration request succeeded unexpectedly"); 150 exception = new RuntimeException("The registration request succeeded unexpectedly"); 151 } catch (ActivationException e) { 152 System.err.println("received exception from registration " + 153 "call that should have failed..."); 154 // Need wait rmid process terminates. 155 try { 156 int exitCode = rmid.waitFor(SHUTDOWN_TIMEOUT); 157 System.err.println("RMID has exited gracefully with exitcode:" + exitCode); 158 rmid = null; 159 } catch (TimeoutException te) { 160 System.err.println("RMID process has not exited in given time"); 161 exception = te; 162 } 163 } 164 } catch (Exception e) { 165 System.err.println("Exception thrown:" + e); 166 exception = e; 167 } finally { 168 if (rmid != null) 169 rmid.destroy(); 170 } 171 if (exception != null) 172 TestLibrary.bomb("\nexception thrown in test: ", exception); 173 } 174 175 /** 176 * implementation of RegisteringActivatable 177 */ 178 public ShutdownGracefully 179 (ActivationID id, MarshalledObject mo) throws RemoteException 180 { 181 // register/export anonymously 182 super(id, 0); 183 } 184 185 /** 186 * Deactivates the object. We need to unexport forcibly because this call 187 * in-progress on this object, which is the same object that we are trying 188 * to deactivate. 189 */ 190 public void shutdown() throws Exception { 191 Activatable.unexportObject(this, true); 192 ActivationLibrary.deactivate(this, getID()); 193 } 194 }