Hello,

We've had some discussion here about the question :
In which layer do we resolve error message internationalisation ?

There are two trends in our company :
1. we resolve error message internationalisation only when we're in the presentation layer (front end).
2. we resolve error message when throwing the exception (i.e. service layer / front layer or even technical classes - such as security classes).

Our design must be applied to all kinds of application :
1. standalone web application.
2. composite web application (which call mainframe / Eis programs or resources).
3. web services.
4. jms based application.
5. batch.
and so on...

We've had a look at our past design and at several open source framework to know how this was resolved, and I think the two trends exist, i.e.
. [trend 2] HibernateValidator (which can be called in all layers) resolve message i18n when the validation is executed.
. [trend 2] Acegi resolve internally message internationalisation.
. [trend 1] Spring Validator let resolve message i18n in front layer.

The pro for trend 2 are :
a - message i18n is resolved at the source. So, when the application calls an external service (distributed such as web service, Jms, ... or framework such as acegi), the application
doesn't need to create everytime all the i18n messages since they are already taken care for.

The cons is :
a - User ou caller's locale must be propagated in all my app layer (perhaps this is already a best pratice ? I don't know).
b - the message resolved in the service doesn't always corresponds to the application constraints
(i.e. the service propagates a business error with message 'The birth date (05/03/2004) is invalid' and the application uses date format dd-mm-yyyy).
So, in this case, the application needs to overload those i18n messages.

Do you have an opinion about the subject or best practice to advice me ?


Sample code from acegi (trend 2)
Code:
- throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
    Dans acegi, message résolu dans acegi avec msg erreur ET code erreur.
    i.e.
    Dans AbstractUserDetailsAuthenticationProvider :    
    public Authentication authenticate(Authentication authentication)
        throws AuthenticationException {

        ...
            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        ...
    }
Sample code from Hibernate Validator (trend 2) :
Resolve i18n message when executing validation (we give the locale in the resourceBundle).
Code:
    
    i.e. 
    ResourceBundle lBundle = ResourceBundle.getBundle ("messages", Locale.GERMAN);
        MyPojo a = new MyPojo();
        a.setCountry( "Australia" );
        a.setZip( "1221341234123" );
        a.setState( "Vic" );
        a.setLine1( "Karbarook Ave" );
        a.setId( 3 );
        ClassValidator<MyPojo> lValidator = new ClassValidator<MyPojo> (MyPojo.class, lBundle);
        validationMessages = lValidator.getInvalidValues( a );
3. Spring Validator (trend 2)
The logic is here to resolve i18n message in the front end (validating just returns an ObjectError which implements MessageSourceResolvable).