/* * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* @test * @bug 4183169 8032050 * @summary Minor problem with the way ReliableLog handles IOExceptions. * * @author Laird Dornin; code borrowed from Ann Wollrath * * @library ../../../testlibrary * @modules java.rmi/sun.rmi.registry * java.rmi/sun.rmi.server * java.rmi/sun.rmi.transport * java.rmi/sun.rmi.transport.tcp * @build TestLibrary RMID * TestSecurityManager RegisteringActivatable ShutdownGracefully_Stub * @run main/othervm/policy=security.policy/timeout=700 ShutdownGracefully */ import java.rmi.activation.*; import java.rmi.*; import java.util.Properties; import java.util.concurrent.TimeoutException; /** * The test creates an rmid with a special security manager. After * rmid makes two registrations (which is greater than rmid's * snapshotInterval) the security manager stops allowing rmid to write * to update and snapshot log files in rmid's log directory. The Test * registers an Activatable object twice with different group ids. * The second registration will cause rmid to have to write to a * LogFile (it causes a snapshot) and the security manager will not * allow the file write to happen. The test makes sure that rmid * shuts down in a graceful manner without any explicit request to do * so. The test will not exit for 400 seconds if rmid does not exit * (after that time, the test will fail). */ public class ShutdownGracefully extends Activatable implements RegisteringActivatable { private static RegisteringActivatable registering = null; private final static long SHUTDOWN_TIMEOUT = 400 * 1000; public static void main(String args[]) { RMID rmid = null; // Save exception if there is a exception or expected behavior Exception exception = null; System.err.println("\nRegression test for bug/rfe 4183169\n"); try { TestLibrary.suggestSecurityManager( "java.rmi.RMISecurityManager"); // start an rmid. RMID.removeLog(); rmid = RMID.createRMID(); // rmid needs to run with a security manager that // simulates a log problem; rmid should also snapshot // quickly. rmid.addOptions(new String[] { "-Djava.security.manager=TestSecurityManager", "-Dsun.rmi.activation.snapshotInterval=1"}); // rmid.addArguments(new String[] { // "-C-Djava.rmi.server.logCalls=true"}); rmid.start(); // Ensure that activation groups run with the correct // security manager. // Properties p = new Properties(); p.put("java.security.policy", TestParams.defaultGroupPolicy); p.put("java.security.manager", "java.lang.SecurityManager"); System.err.println("activation group will be created " + "in a new VM"); ActivationGroupDesc groupDesc = new ActivationGroupDesc(p, null); ActivationSystem system = ActivationGroup.getSystem(); ActivationGroupID groupID = system.registerGroup(groupDesc); System.err.println("registering activatable"); ActivationDesc desc = new ActivationDesc (groupID, "ShutdownGracefully", null, null); registering = (RegisteringActivatable) Activatable.register(desc); System.err.println("activate and deactivate object " + "via method call"); registering.shutdown(); /* * the security manager rmid is running with will stop * rmid from writing to its log files; in 1.2.x this would * have caused rmid to have thrown a runtime exception and * continue running in an unstable state. With the fix * for 4183169, rmid should shutdown gracefully instead. */ /* * register another activatable with a new group id; rmid * should not recover from this... I use two * registrations to more closely simulate the environment * in which the bug was found. In java versions with out * the appropriate bug fix, rmid would hide a * NullPointerException in this circumstance. */ p.put("dummyname", "dummyvalue"); groupDesc = new ActivationGroupDesc(p, null); ActivationGroupID secondGroupID = system.registerGroup(groupDesc); desc = new ActivationDesc(secondGroupID, "ShutdownGracefully", null, null); /* * registration request is expected to be failed. succeeded case * should be recorded. And raise error after clean up rmid. */ try { registering = (RegisteringActivatable) Activatable.register(desc); System.err.println("The registration request succeeded unexpectedly"); exception = new RuntimeException("The registration request succeeded unexpectedly"); } catch (ActivationException e) { System.err.println("received exception from registration " + "call that should have failed..."); // Need wait rmid process terminates. try { int exitCode = rmid.waitFor(SHUTDOWN_TIMEOUT); System.err.println("RMID has exited gracefully with exitcode:" + exitCode); rmid = null; } catch (TimeoutException te) { System.err.println("RMID process has not exited in given time"); exception = te; } } } catch (Exception e) { System.err.println("Exception thrown:" + e); exception = e; } finally { if (rmid != null) rmid.destroy(); } if (exception != null) TestLibrary.bomb("\nexception thrown in test: ", exception); } /** * implementation of RegisteringActivatable */ public ShutdownGracefully (ActivationID id, MarshalledObject mo) throws RemoteException { // register/export anonymously super(id, 0); } /** * Deactivates the object. We need to unexport forcibly because this call * in-progress on this object, which is the same object that we are trying * to deactivate. */ public void shutdown() throws Exception { Activatable.unexportObject(this, true); ActivationLibrary.deactivate(this, getID()); } }