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