blob: c45d95674e6dc6aca5660dd7bd984361f7518fd0 [file] [log] [blame]
/*
* Copyright (c) 1999, 2017, 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
* java.base/sun.nio.ch
* @build TestLibrary RMID RMIDSelectorProvider
* 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.createRMIDOnEphemeralPort();
// 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.cleanup();
}
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());
}
}