Conflict between ValidationMessages.properties files

Tags: , ,



I use to collect all my validation constraints in a common library. In the root of the jar I put a ValidationMessages_it.properties file. All works fine, if I put this library into a jsf 2 war project all validation messages are shown correctly. However a problem arise if I put another ValidationMessages_it.properties in the war artifact too. In this case a {library.message_key} string is shown.

I think Bean Validation find the right property file in the war and does not take into account that in the library. How can I solve?

Example

I have a library, commons.jar, that contains custom constraints. In order to set messages for these constraints I’ve added a ValidationMessages_it.properties in the root of this library

commons.jar
    |
    + library
    |   |
    |   + CustomConstraint.class
    |
    + ValidationMessages_it.properties

ValidationMessages_it.properties

library.custom=Questo è l'errore di cui parlavo

CustomConstraint.java

@Pattern( regexp = "[a-z]", message = "{library.custom}" )
@Constraint( validatedBy = {} )
@Documented
@Target( { ElementType.METHOD, ElementType.FIELD } )
@Retention( RetentionPolicy.RUNTIME )
public @interface CustomConstraint {
    String message() default "C'è un errore";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

PS: note that the message key is on the @Pattern annotation instead of message(), this could seem a mistake but otherwise it never works!

After that I want to use this commons.jar in my web app project (jsf/mojarra 2.1). All works fine. The displayed error message is “Questo è l’errore di cui parlavo”.

But now suppose I define new validation constraints in my webapp, so I want to supply translations for these constraints by adding a ValidationMessages_it.properties in WEB-INF/classes folder. In this case the displayed error message is “{library.custom}”

So I think that BV (or jsf?) find the bundle in the war and does not take into account that in the commons.jar. It does not find the key library.custom in the ValidationMessages_it.properties that resides in the WEB-INF/classes folder thus return {library.custom} literally.

Example 2

Based on Bean Validation constraints in a shared library, my package structure seems correct. I uploaded a simple web app to show the problem:

I tested the webapp in Glassfish 3.1.2, JBoss AS 7.1.1, Geronimo 3.0.0

Glassfish and JBoss have the same behavior. In Geronimo it works a little bit better.

Answer

I think the solution in your case is the mentioned AggregateResourceBundleLocator. However, you cannot have the same name for the property files. Internally ResourceBundle#getBundle is called which does return a single ResourceBundle. There is no concept of combining/merging properties files with the same name.

EDIT 1

Regarding a standard way of doing it – unfortunately there is none. There is an open issue for Bean Validation 1.1 (BVAL-252) to address the ability to provide constraint libraries, but there is nothing decided yet and the message interpolation would needs addressing as well. Maybe you have an idea on how it should work. If so provide your suggestion to the expert group. Check beanvalidation.org



Source: stackoverflow