blob: 69c8d5979fdcfa2765f1b2006b1d8b82f1844827 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.test.dunit;
import org.apache.geode.GemFireException;
/**
* This exception is thrown when an exception occurs during a remote method invocation. This
* {@link RuntimeException} wraps the actual exception. It allows distributed unit tests to verify
* that an exception was thrown in a different VM.
*
* <PRE>
* VM vm0 = host0.getVM(0);
* try {
* vm.invoke(() -> this.getUnknownObject());
*
* } catch (RMIException ex) {
* assertIndexDetailsEquals(ex.getCause() instanceof ObjectException);
* }
* </PRE>
*
* Note that special steps are taken so that the stack trace of the cause exception reflects the
* call stack on the remote machine. The stack trace of the exception returned by
* {@link #getCause()} may not be available.
*
* see hydra.RemoteTestModuleIF
*
*/
@SuppressWarnings("serial")
public class RMIException extends GemFireException {
/**
* SHADOWED FIELD that holds the cause exception (as opposed to the HokeyException
*/
private Throwable cause;
/** The name of the method being invoked */
private String methodName;
/**
* The name of the class (or class of the object type) whose method was being invoked
*/
private String className;
/** The type of exception that was thrown in the remote VM */
private String exceptionClassName;
/** Stack trace for the exception that was thrown in the remote VM */
private String stackTrace;
/** The VM in which the method was executing */
private VM vm;
//////////////////////// Constructors ////////////////////////
/**
* Creates a new <code>RMIException</code> that was caused by a given <code>Throwable</code> while
* invoking a given method.
*/
public RMIException(VM vm, String className, String methodName, Throwable cause) {
super("While invoking " + className + "." + methodName + " in " + vm, cause);
this.cause = cause;
this.className = className;
this.methodName = methodName;
this.vm = vm;
}
/**
* Creates a new <code>RMIException</code> to indicate that an exception of a given type was
* thrown while invoking a given method.
*
* @param vm The VM in which the method was executing
* @param className The name of the class whose method was being invoked remotely
* @param methodName The name of the method that was being invoked remotely
* @param cause The type of exception that was thrown in the remote VM
* @param stackTrace The stack trace of the exception from the remote VM
*/
public RMIException(VM vm, String className, String methodName, Throwable cause,
String stackTrace) {
super("While invoking " + className + "." + methodName + " in " + vm,
new HokeyException(cause, stackTrace));
this.vm = vm;
this.cause = cause;
this.className = className;
this.methodName = methodName;
// this.exceptionClassName = exceptionClassName; assignment has no effect
this.stackTrace = stackTrace;
}
/**
* Returns the class name of the exception that was thrown in a remote method invocation.
*/
public String getExceptionClassName() {
return this.exceptionClassName;
}
// /**
// * Returns the stack trace for the exception that was thrown in a
// * remote method invocation.
// */
// public String getStackTrace() {
// return this.stackTrace;
// }
/**
* Returns the cause of this exception. Note that this is not necessarily the exception that gets
* printed out with the stack trace.
*/
@Override
public Throwable getCause() {
return this.cause;
}
/**
* Returns the VM in which the remote method was invoked
*/
public VM getVM() {
return this.vm;
}
////////////////////// Inner Classes //////////////////////
/**
* A hokey exception class that makes it looks like we have a real cause exception.
*/
private static class HokeyException extends Throwable {
private String stackTrace;
private String toString;
HokeyException(Throwable cause, String stackTrace) {
this.toString = cause.toString();
this.stackTrace = stackTrace;
}
@Override
public void printStackTrace(java.io.PrintWriter pw) {
pw.print(this.stackTrace);
pw.flush();
}
public String toString() {
return this.toString;
}
}
}