657b9db1ba
Updated files with 2011, 2012 and 2013 years according to the file's last updated date Reviewed-by: tbell, lancea, chegar
196 lines
7.0 KiB
Java
196 lines
7.0 KiB
Java
/*
|
|
* Copyright (c) 1998, 2012, 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 4118600
|
|
* @summary RMI UnmarshallException, interaction on stopping a thread.
|
|
*
|
|
* @bug 4177704
|
|
* @summary RuntimeExceptions can corrupt call connections that may be reused.
|
|
*
|
|
* @author Laird Dornin
|
|
*
|
|
* @library ../../../testlibrary
|
|
* @build TestLibrary CheckUnmarshal CheckUnmarshalOnStopThread_Stub
|
|
* PoisonPill RuntimeExceptionParameter
|
|
* @run main/othervm/timeout=480 CheckUnmarshalOnStopThread
|
|
*/
|
|
|
|
import java.rmi.*;
|
|
import java.rmi.server.*;
|
|
import java.io.*;
|
|
import java.rmi.registry.*;
|
|
|
|
/**
|
|
* Description for 4118600:
|
|
*
|
|
* If an rmi call thread is stopped while unmarshalling a return
|
|
* value), java.lang.ThreadDeath will be thrown during
|
|
* UnicastRef.invoke(...). If rmi handles the Error properly, the
|
|
* remote method connection will not be reused. Otherwise the
|
|
* connection can be freed and reused in a corrupted state, which will
|
|
* lead to the throwing of an UnmarshalException the next time the
|
|
* connection is used.
|
|
*
|
|
* To test RMI Error handling, the test invokes the remote call,
|
|
* getPoisonPill, a number of times. This method returns an object
|
|
* which throws an Error on return value deserialization (from its
|
|
* readObject method). If RMI handles the error correctly, another
|
|
* remote call, ping, should execute correctly (i.e. with no
|
|
* exceptions). The test fails if the ping method throws an
|
|
* UnmarshalException.
|
|
*
|
|
* The old way that the test used to operate:
|
|
*
|
|
* Iterate a large number of times: each iteration spawns a thread
|
|
* that makes multiple rmi calls, sleep for 10 milliseconds, then stop
|
|
* the thread that is making the rmi calls (hopefully during return
|
|
* value Unmarshalling).
|
|
*
|
|
* Count the number of UnmarshalExceptions that occur during test
|
|
* iterations. If this number is > 10, then the test fails.
|
|
*
|
|
* Note: Even if rmi is catching java.lang.ThreadDeath properly, other
|
|
* types of exceptions (often related to monitor state, etc.) can
|
|
* occur. This test is only written to track UnmarshalExceptions;
|
|
* success/failure does not depend on other types of problems.
|
|
*
|
|
* Description for 4177704:
|
|
*
|
|
* Similar situation as for 4177704 except that instead of just
|
|
* ensuring that RMI properly handles Errors, the second part of the
|
|
* test ensures that RMI deals with RuntimeExceptions correctly.
|
|
*
|
|
* Test also ensures that call connections are freed without reuse
|
|
* when RuntimeExceptions are thrown during the marshalling of call
|
|
* parameters. An object that throws a RuntimeException in its
|
|
* writeObject method helps to carry out this part of the test.
|
|
*/
|
|
public class CheckUnmarshalOnStopThread
|
|
extends UnicastRemoteObject
|
|
implements CheckUnmarshal
|
|
{
|
|
final static int RUNTIME_PILL = 1;
|
|
public static int typeToThrow = 0;
|
|
|
|
/*
|
|
* remote object implementation
|
|
*/
|
|
|
|
CheckUnmarshalOnStopThread() throws RemoteException { }
|
|
|
|
public PoisonPill getPoisonPill() throws RemoteException {
|
|
return new PoisonPill(new Integer(0));
|
|
}
|
|
|
|
public Object ping() throws RemoteException {
|
|
return (Object) new Integer(0);
|
|
}
|
|
|
|
public void passRuntimeExceptionParameter(
|
|
RuntimeExceptionParameter rep) throws RemoteException
|
|
{
|
|
// will never be called
|
|
}
|
|
|
|
public static void main(String [] args) {
|
|
|
|
Object dummy = new Object();
|
|
CheckUnmarshal cu = null;
|
|
CheckUnmarshalOnStopThread cuonst = null;
|
|
|
|
System.err.println("\nregression test for bugs: " +
|
|
"4118600 and 4177704\n");
|
|
|
|
try {
|
|
cuonst = new CheckUnmarshalOnStopThread();
|
|
cu = (CheckUnmarshal) UnicastRemoteObject.toStub(cuonst);
|
|
|
|
// make sure that RMI will free connections appropriately
|
|
// under several situations:
|
|
|
|
// when Errors are thrown during parameter unmarshalling
|
|
System.err.println("testing to see if RMI will handle errors");
|
|
ensureConnectionsAreFreed(cu, true);
|
|
|
|
// when RuntimeExceptions are thrown during parameter unmarshalling
|
|
System.err.println("testing to see if RMI will handle " +
|
|
"runtime exceptions");
|
|
typeToThrow = RUNTIME_PILL;
|
|
ensureConnectionsAreFreed(cu, true);
|
|
|
|
// when RuntimeExceptions are thrown during parameter marshalling
|
|
System.err.println("testing to see if RMI will handle " +
|
|
"runtime exceptions thrown during " +
|
|
"parameter marshalling");
|
|
ensureConnectionsAreFreed(cu, false);
|
|
|
|
System.err.println
|
|
("\nsuccess: CheckUnmarshalOnStopThread test passed ");
|
|
|
|
} catch (Exception e) {
|
|
TestLibrary.bomb(e);
|
|
} finally {
|
|
cu = null;
|
|
deactivate(cuonst);
|
|
}
|
|
}
|
|
|
|
static void ensureConnectionsAreFreed(CheckUnmarshal cu, boolean getPill)
|
|
throws Exception
|
|
{
|
|
// invoke a remote call that will corrupt a call connection
|
|
// that will not be freed (if the bug is not fixed)
|
|
|
|
for (int i = 0 ; i < 250 ; i++) {
|
|
try {
|
|
Object test = cu.ping();
|
|
if (getPill) {
|
|
cu.getPoisonPill();
|
|
} else {
|
|
cu.passRuntimeExceptionParameter(
|
|
new RuntimeExceptionParameter());
|
|
}
|
|
} catch (Error e) {
|
|
// expect an Error from call unmarshalling, ignore it
|
|
} catch (RuntimeException e) {
|
|
// " RuntimeException "
|
|
}
|
|
}
|
|
|
|
System.err.println("remote calls passed, received no " +
|
|
"unmarshal exceptions\n\n");
|
|
}
|
|
|
|
static void deactivate(RemoteServer r) {
|
|
// make sure that the object goes away
|
|
try {
|
|
System.err.println("deactivating object.");
|
|
UnicastRemoteObject.unexportObject(r, true);
|
|
} catch (Exception e) {
|
|
e.getMessage();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|