Hi, anyone knows how the following issue can be solved?
In the stateless business sessionbean, we will have "home-made" application exceptions (relating to business logics, for example "CustomerNotFoundException"), thrown up to the client (swing) layer, wrapped in EJBException to achieve automatic rollback.
This is all OK, but a problem arises as the message needs to be translated (by calling a translator bean, or simple class, I guess) to proper locale language. We intend to do this by having the specific Exception class keep a final static member - for example EXCEPTION_KEY="cust_not_found". When the Exception is first created, it should in its constructor go and fetch the proper message - in some language -(from language file/Resource bundle) using its hardcoded key.
Now, this call may itself throw some exception, which then must be handled within the constructor of the Application exception. For instance, if the translator session bean throws a remote exception, or IOError exception...
How can we avoid this need for exception handling mechanisms in the constructor of the CustomerNotFoundException??
Doing the translator bean getMessage(key) call before the creation of Exception (setting the proper language message once the exception is created ) is of course possible, as the EXCEPTION_KEY is static and can be used before class is created, but then we'll have some extra code to implement every time we want to throw an exception (translatorBean.getMessage;new AppException;AppException.setMessage), and the translator-bean call may still raise an exception that will have to be handled...
And the same issues must also be addressed as for the logging of the exception - what if the logger bean itself throws an exception???
Please, any help in resolving this issue will be highly appreciated!!!
This is a very interesting problem, and I think you have very good ideas. What I want to do is to add some experience from a project with a Swing client calling EJB:s.
What we did was to put the exception key in the exception, and the translation (based on Locale) on the client side. We had one exception class (OurProjectException) with a method getExceptionKey(), and the key was a parameter to the constructor of OurProjectException. However, from what I know today (I designed this in January last year), I strongly recommend you to define subclasses like the CustomerNotFoundException. In that case you can let getExceptionKey() return a hardcoded value!
Moreover, I recommend you to throw OutProjectException (or subclasses) in the EJB remote interface, instead of using the way over EJBException and RemoteException. The rollback can be fixed with setRollbackOnly() on the EJBContext interface! But this is my personal recommendation, and I know that many designers will go for the EJBException solution!
On the client side, we wrote a Singleton class with a method getDisplayText(String key, Locale locale) to get the actual text to display. The implementation used the ResourceBundle functionality. If a translation is missing in your properties file, that must be handled by the application. (Different "text is missing" messages can be applicable in different situations.)
The properties files where distributed with the client JAR file. We did not have to built any cache since performance was OK anyway. Maybe a cache in the ClassLoader???
Why putting the translation on the client???
1. The think translation is a part of the application, and therefore it should not be mixed with server side components.
2. Error handling is moved to client, and can be changed without impact on the server side code.
3. IMPORTANT! I suppose you client will have some login? Then you will need the display texts (in different languages) _before_ you connect to the EJB server, and some of the text (in the login window) must be distributet with the client JAR. If you distribute some text, put them all in the same file!!!
If you give me a mail address, I can send you some code on the exception and singleton implementations.
thanks a lot for the answer!! - your tips are really helpful, and it's nice to know that we seem to be on the right track.
I'd very much appreciate if you could send some source -
my mail adress is: alco at libro dot se
Again, thanks for your informative answer!
(However - the problem of exceptions thrown when creating other exceptions and getting message+logging, still pertains)
Best regards -
I with Thomas that having the presentation-tier (be that a thick-client, JSP, etc) bear the responsility of translating a system-defined value is the most correct approach. It is after all a display issue.
WRT your exceptions themselves possibly throwing exceptions, at some point you have to determine which exceptions should be propagated all the way to the user, and which ones should not. Generally speaking, if it is an "expected" exception, go ahead and tell the user what happened. But if the exception could only be due to a technical failure (bad code, files missing from server, etc) a generic ApplicationException should suffice (along with a good dose of logging).