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