1

I am new to Spring 3 MVC and was trying out form validation using the Java validation API and the Hibernate Validator implementation JARs. I am using Tomcat 6 for my application. Below is the pom.xml:

<properties>  
<spring.version>3.1.1.RELEASE</spring.version>  
<jdk.version>1.6</jdk.version>  
</properties>

<dependencies>  

    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-core</artifactId>  
        <version>${spring.version}</version>  
    </dependency>  

    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-web</artifactId>  
        <version>${spring.version}</version>  
    </dependency>  

    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-webmvc</artifactId>  
        <version>${spring.version}</version>  
    </dependency>  

    <!-- CGLIB is required to process @Configuration classes -->  
    <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
</dependency>            

    <dependency>  
        <groupId>junit</groupId>  
        <artifactId>junit</artifactId>  
        <version>3.8.1</version>  
        <scope>test</scope>  
    </dependency>  
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
       </dependencies>  

Below is the model class Employee.java:

@Size(min=2,max=30)
private String name;
@NotEmpty @Email
private String email;
@NotNull @Min(18) @Max(35)
private Integer age;
@Size(min=10)
private String phone;
// Getters and Setters

Below is the JSP containing the form:

<form:form method="post" commandName="empl" action="validate">
<table>
    <tr>
        <td>
            <label for="nameInput">Name:</label>
        </td>
        <td>
            <form:input path="name" id="nameInput"/>
            <form:errors path="name"></form:errors>
        </td>
    </tr>
    <tr>
        <td>
            <label for="ageInput">Age:</label>
        </td>
        <td>
            <form:input path="age" id="ageInput"/>
            <form:errors path="age"></form:errors>
        </td>
    </tr>
    <tr>
        <td>
            <label for="phoneInput">Phone:</label>
        </td>
        <td>
            <form:input path="phone" id="phoneInput"/>
            <form:errors path="phone"></form:errors>
        </td>
    </tr>
    <tr>
        <td>
            <label for="emailInput">Email:</label>
        </td>
        <td>
            <form:input path="email" id="emailInput"/>
            <form:errors path="email"></form:errors>
        </td>
    </tr>
    <%--<tr>
        <td>
            <label for="birthdayInput">Birthday:</label>
        </td>
        <td>
            <form:input path="birthday" id="birthdayInput" placeholder="MM/DD/YYYY"/>
            <form:errors path="birthday"></form:errors>
        </td>
    </tr>
     <tr>
        <td>
            <label for="genderInput">Birthday:</label>
        </td>
        <td>
            <form:select id="genderInput" path="" items="${gender }">      </form:select>
            <form:errors path="birthday"></form:errors>
        </td>
    </tr> --%>
    <tr>
        <td colspan="2">
            <input type="submit" value="Submit">
        </td>
    </tr>
</table>
</form:form>

When I click the submit button I am getting the error. Even the Controller handler method is not invoked and the below error is thrown:

java.lang.NoSuchMethodError: javax.el.ExpressionFactory.newInstance()Ljavax/el/ExpressionFactory;
org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTerm.<clinit>(InterpolationTerm.java:60)
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.interpolateExpression(ResourceBundleMessageInterpolator.java:227)
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.interpolateMessage(ResourceBundleMessageInterpolator.java:187)
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.interpolate(ResourceBundleMessageInterpolator.java:120)
org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator.interpolate(LocaleContextMessageInterpolator.java:49)
org.hibernate.validator.internal.engine.ValidationContext.interpolate(ValidationContext.java:370)
org.hibernate.validator.internal.engine.ValidationContext.createConstraintViolation(ValidationContext.java:284)
org.hibernate.validator.internal.engine.ValidationContext.createConstraintViolations(ValidationContext.java:246)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:289)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:133)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateComposingConstraints(ConstraintTree.java:233)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:102)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:85)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:478)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:424)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:388)
org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:340)
org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:158)
org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:101)
org.springframework.validation.DataBinder.validate(DataBinder.java:722)
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.validateIfApplicable(ModelAttributeMethodProcessor.java:155)
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:108)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

I tried adding the following dependency but of no use (hence removed it afterwards):

<dependency>
        <groupId>javax.el</groupId>
        <artifactId>el-api</artifactId>
        <version>2.2</version>
    </dependency>

Please advise how to resolve this.

EDIT

If I add this dependency (but of no use, hence removed it as well):

<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>el-impl</artifactId>
    <version>2.2</version>
</dependency>

Then I am getting the below error:

java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.servlet.jsp.JspApplicationContext.getExpressionFactory()Ljavax/el/ExpressionFactory;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/index_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspApplicationContext, have different Class objects for the type javax/el/ExpressionFactory used in the signature
at org.apache.jsp.index_jsp._jspInit(index_jsp.java:22)
at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:164)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:340)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)

EDIT 2

Below is the snapshot for the jars:

enter image description here

user182944
  • 7,897
  • 33
  • 108
  • 174

2 Answers2

7

The problem is that Tomcat 6 ships an older version of EL (2.1) while Hibernate Validator 5.x requires the newer EL 2.2. Have a look at: http://hibernate.org/validator/faq/#does-hibernate-validator-5-x-work-with-tomcat-6.

Jukka
  • 4,583
  • 18
  • 14
1

You can use 4.3.1.Final version of hibernate-validator and that will solve the primary issue .The changes mentioned in the edit's are not required.This is assuming you dont need the features of EL 2.2 as the example that you are trying is a basic one.

You can still use the latest hibernate-validator jar,but as pointed out you need to upgrade to tomcat 7 or have the latest EL 2.2 jars in tomcat lib.

There's a simple comparision here http://tomcat.apache.org/whichversion.html

crackerplace
  • 5,305
  • 8
  • 34
  • 42