i18n gotcha suggested by Seam manual
dbatcn Jul 4, 2006 6:51 PMI had gotten a very simple Seam project created in Eclipse successfully cloned from seam-registration. I started changing it a bit to be a bit more like the seam-booking example (just the registration page part), which included adding the @NotNull and @Length annotations that come from Hibernate. I'm trying to build an application with Seam and Facelets and Hibernate, which seems to be the recommended approach from the documentation.
Since I am the unusual kind of American who expects that his software will need a non-English UI in order to sell it abroad :-), I had also followed the recommendation of putting a message.properties file in WEB-INF/classes, as suggested in section 5.2 (Internationalization.Labels) of the reference manual. Well, it turns out that if you do that, then you override the Hibernate validator message properties from its DefaultValidatorMessages properties. This caused me to get:
2006-07-04 15:16:30,921 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/seam-registration].[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalArgumentException: could not instantiate ClassValidator
at org.hibernate.validator.ClassValidator.createValidator(ClassValidator.java:265)
at org.hibernate.validator.ClassValidator.createMemberValidator(ClassValidator.java:233)
at org.hibernate.validator.ClassValidator.initValidator(ClassValidator.java:176)
at org.hibernate.validator.ClassValidator.<init>(ClassValidator.java:110)
at org.hibernate.validator.ClassValidator.<init>(ClassValidator.java:98)
at org.hibernate.validator.ClassValidator.<init>(ClassValidator.java:92)
at org.jboss.seam.Component.getValidator(Component.java:652)
at org.jboss.seam.util.Validation.getValidator(Validation.java:23)
at org.jboss.seam.ui.ModelValidator.validate(ModelValidator.java:38)
at javax.faces.component._ComponentUtils.callValidators(_ComponentUtils.java:133)
at javax.faces.component.UIInput.validateValue(UIInput.java:254)
at javax.faces.component.UIInput.validate(UIInput.java:269)
at javax.faces.component.UIInput.processValidators(UIInput.java:144)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:417)
at javax.faces.component.UIForm.processValidators(UIForm.java:68)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:417)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:142)
at org.apache.myfaces.lifecycle.LifecycleImpl.processValidations(LifecycleImpl.java:240)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:106)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:30)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key validator.notNull
at java.util.ResourceBundle.getObject(ResourceBundle.java:325)
at java.util.ResourceBundle.getString(ResourceBundle.java:285)
at org.hibernate.validator.ClassValidator.replace(ClassValidator.java:518)
at org.hibernate.validator.ClassValidator.createValidator(ClassValidator.java:260)
... 40 more
I was quite perplexed for a few hours. I'm sure that as I become more familiar with Seam this sort of time will shorten, but I do think that it's one of those issues that can discourage people from using Seam. Having the source for Seam and Hibernate around certainly helped in figuring out a diagnosis.
Rooting around in the examples, I noticed that the messages.properties files for the dvdstore and issues examples define various "validator.*" properties:
validator.assertFalse=assertion failed validator.assertTrue=assertion failed validator.future=must be a future date validator.length=length must be between {min} and {max} validator.max=must be less than or equal to {value} validator.min=must be greater than or equal to {value} validator.notNull=may not be null validator.past=must be a past date validator.pattern=must match "{regex}" validator.range=must be between {min} and {max} validator.size=size must be between {min} and {max} validator.email=not a well-formed email address
Removing or renaming my messages.properties file makes the problem go away.
So, first, a caveat emptor warning to others so that you can avoid my misfortune.
And, second, a couple of suggestions for Seam:
* at the least, I think there ought to be some warning about this in the reference manual (easy)
* I think that there ought to be a way to get the usefulness of a messages.properties file default (i.e. not having to put <f:loadBundle ... /> in every page) without incurring the burden of having to redefine the various Hibernate validator text properties: there's a maintenance and correctness burden (less easy)
Best regards,
Dave