users@glassfish.java.net

Re: javax.ejb.NoSuchObjectLocalException: Invalid Session Key

From: Wolfram Rittmeyer <w.rittmeyer_at_jsptutorial.org>
Date: Sun, 15 Mar 2009 13:54:34 +0100

Markus Karg wrote:
> Wolfram,
>
>> This happens when a RuntimeException (or RemoteException) gets thrown
>> and is not caught within your SFSB. As soon as the container catches
>> it,
>> your bean is toast. Thus you should look carefully at any calls you
>> make
>> to other components and catch possible RuntimeExceptions and throw an
>> application-dependent exception instead. Any declared Exceptions
> (other
>> than Remote- and RuntimeExceptions) are expected exceptions and do not
>> cause your bean to be destroyed.
>
> Is this EJB 3.0 compliant? I mean, if that is true then actually EACH
> method of EACH SB must be surrounded by try...catch(RuntimeException) --
> what would be a lot of work! Can't believe that EJB 3 says that a SB
> shall shut down if it catches a RuntimeException. Does it?

It is compliant. See section 4.4.2.:
A RuntimeException thrown from any method of the session bean class
(including the business methods and the lifecycle callback interceptor
methods invoked by the container) results in the transition to the “does
not exist” state. Exception handling is described in detail in Chapter
13. See section 11.4.2 for the rules pertaining to lifecycle callback
interceptor methods when more than one such method applies to the bean
class.
 From the client perspective, the corresponding session object does not
exist any more. If a client subsequently attempts to invoke a method on
the bean’s business interface, the container will throw the
javax.ejb.NoSuchEJBException[16]. If the EJB 2.1 client view is used,
the container will throw the java.rmi.NoSuchObjectException if the
client is a remote client, or the javax.ejb.NoSuchObjectLocalException
if the client is a local client.

See also section 13.3.1.

But there is no need to act upon it in SLSBs. In this case it doesn't
matter that the instance is discarded. The next call simply uses another
bean from the pool. So this problem is only relevant for stateful
session beans.

BTW: I guess the reasoning is that a system exception causes the bean to
be in an unreliable state since you have not been able to clean up after
the exception. Thus this instance rightfully must be abandoned.

There is also a third way to deal with this - you could use your own
RuntimeExceptions that themself are annotated as @ApplicationException.
But this of course only helps with code where you have control over
which RuntimeException to throw. So it is probably of no use to you.

> And, wouldn't there be a log entry in server.log naming that
> RuntimeException? In my log there is none.
>

Hmm, strange. I have just simulated this and the causing
RuntimeException is logged.

>> The other option is, that your client code realizes that an exception
>> has occured and thus creates a new SFSB to use from then on.
>
> Well, that would imply a lot of cluttering in the client code: Actually
> you must catch the RemoteException at each of possibly thousands of
> locations to recreate the session and retry the command...

Your client has to deal with the exception anyway. The transaction has
been rolled back, the bean has been discarded and an exception has been
thrown. The user probably should know about this, you might want to log
the exception and so on. How do you deal with this?

>
> BTW, is there any chance to see the cause of the session closure in some
> log file?

Well it should be logged. But the loglevel is INFO. For productive
systems not the best choice IMHO. I suggest to issue a bug report to
change this log level for future versions.


--
Wolfram Rittmeyer
> 
> Thanks for you kind answer, now I know what to look for...
> Regards
> Markus