// Mark the start time
long start = System.currentTimeMillis();
// Create a pointer to a new Invocation
EJBContainerInvocation newSi = null;
// Create a pointer to the response we'll return
InvocationResponse response = null;
// Create a pointer to the Session ID
Serializable sessionId = null;
/*
* Setup Environment (Stack/Thread)
*/
// Hold a reference to the existing TCL
ClassLoader originalLoader = Thread.currentThread().getContextClassLoader();
// Set the Container's CL as TCL, required to unmarshall methods from the bean impl class
Thread.currentThread().setContextClassLoader(this.getClassloader());
// Push the ENC onto the stack
pushEnc();
try
{
/*
* Obtain the target method (unmarshall from invocation)
*/
// Cast
assert invocation instanceof StatefulRemoteInvocation : SessionContainer.class.getName()
+ ".dynamicInoke supports only " + StatefulRemoteInvocation.class.getSimpleName()
+ ", but has been passed: " + invocation;
StatefulRemoteInvocation si = (StatefulRemoteInvocation) invocation;
// Get the method hash
long methodHash = si.getMethodHash();
log.debug("Received dynamic invocation for method with hash: " + methodHash);
// Get the Method via MethodInfo from the Advisor
Advisor advisor = this.getAdvisor();
MethodInfo info = advisor.getMethodInfo(methodHash);
Method unadvisedMethod = info.getMethod();
// Get the invoked method from invocation metadata
Object objInvokedMethod = si.getMetaData(SessionSpecRemotingMetadata.TAG_SESSION_INVOCATION,SessionSpecRemotingMetadata.KEY_INVOKED_METHOD);
assert objInvokedMethod !=null : "Invoked Method must be set on invocation metadata";
assert objInvokedMethod instanceof SerializableMethod : "Invoked Method set on invocation metadata is not of type " + SerializableMethod.class.getName() + ", instead: " + objInvokedMethod;
SerializableMethod invokedMethod = (SerializableMethod)objInvokedMethod;
try
{
// Increment invocation statistics
invokeStats.callIn();
/*
* Obtain Session ID
*/
// Obtain the Session ID
Object objSessionId = si.getMetaData(StatefulSessionRemotingMetadata.TAG_SFSB_INVOCATION,
StatefulSessionRemotingMetadata.KEY_SESSION_ID);
if (objSessionId != null)
{
assert objSessionId instanceof Serializable : "Session IDs must be "
+ Serializable.class.getSimpleName();
sessionId = (Serializable) objSessionId;
}
if (info != null && unadvisedMethod != null && isHomeMethod(unadvisedMethod))
{
response = invokeHomeMethod(info, si);
}
else if (info != null && unadvisedMethod != null && isEJBObjectMethod(unadvisedMethod))
{
response = invokeEJBObjectMethod(info, si);
}
else
{
if (unadvisedMethod.isBridge())
{
unadvisedMethod = this.getNonBridgeMethod(unadvisedMethod);
info = super.getMethodInfo(unadvisedMethod);
}
if (sessionId == null)
{
StatefulBeanContext ctx = getCache().create(null, null);
Object objNewId = ctx.getId();
assert objNewId instanceof Serializable : "Obtained new Session ID from cache, " + objNewId
+ ", which is not " + Serializable.class.getSimpleName();
sessionId = (Serializable) objNewId;
}
/*
* Set the invoked method
*/
//TODO Remove when CurrentInvocation is ironed out
// Set onto stack
SessionSpecContainer.invokedMethod.push(invokedMethod);
/*
* Build a new Invocation
*/
// Construct the invocation
newSi = new StatefulContainerInvocation(info, sessionId);
//newSi = new StatefulContainerInvocation(info.getInterceptors(), long methodHash, Method advisedMethod, Method unadvisedMethod, Advisor advisor, Object id);
newSi.setArguments(si.getArguments());
newSi.setMetaData(si.getMetaData());
newSi.setAdvisor(getAdvisor());
// Create an object to hold the return value
Object returnValue = null;
/*
* Perform Invocation
*/
// Invoke
returnValue = newSi.invokeNext();
// Marshall the response
response = marshallResponse(invocation, returnValue, newSi.getResponseContextInfo());
if (sessionId != null)
{
response.addAttachment(StatefulConstants.NEW_ID, sessionId);
}
// response = marshallResponse(invocation, rtn, newSi.getResponseContextInfo());
// if (newId != null) response.addAttachment(StatefulConstants.NEW_ID, newId);
// Create a Response
// response = new InvocationResponse(returnValue);
// Map<Object, Object> responseContext = newSi.getResponseContextInfo();
// response.setContextInfo(responseContext);
}
}
catch (Throwable t)
{
Throwable exception = t;
// if (sessionId != null)
// {
// exception = new ForwardId(t, sessionId);
// }
Map<Object, Object> responseContext = null;
if (newSi != null)
{
responseContext = newSi.getResponseContextInfo();
}
response = marshallException(invocation, exception, responseContext);
return response;
}
finally