2
votes

The question follows further down this post, but it can be summed up to this : how to get Hibernate Validator 5 to work with RestEasy? Isn't bean validation 1.1 required for JAX-RS 2.0? Or will it work with Bean Validation 1.0)

I give info in this post that go beyond my question, in order to reproduce all steps I did and errors I got on to this point, in the hope it helps anyone, who like me, would like to have a JAX-RS 2.0 (RestEasy impl) on WAS 8.5.5. I found absolutely no doc at all so here it is what I got.

I am currently trying to move from, Jersey 2.xx, JPA 2.1, on Tomcat 7, to RestEasy on WAS 8.5.5. I could also try Apache CXF, but I ran onto other problems.

I can't use Jersey with CDI in WAS because of this : https://java.net/jira/browse/JERSEY-1933

-----THE SETUP----

a) create a ear with a web module in RAD

b) in the deployment descriptor, for the EAR, I set the class loader mode to: parent last, WAR classloader policy : module

c) in the deployment descriptor, for the Web module, I set the class loader mode to: parent last

d) disabled WAS jax-rs engine (jax-rs 1.1) (Added JVM arg -Dcom.ibm.websphere.webservices.DisableIBMJAXWSEngine=true)

note on c) : if I use parent first, JAX-RS 1.1 that comes with WAS gets loaded before my JAX-RS 2.0 jar. All kinds of errors will follow.

note on b) : if i don't use "module", but "application" classloader policy, I get this error

> Provider org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer
> not a subtype

I setup the RestEasy servlet in web.xml

<servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>

    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.mydomain.RestEasyConfig</param-value>
    </init-param>

    <init-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </init-param>

    <init-param>
        <param-name>resteasy.servlet.context.deployment</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

The following jar were included in my WAR in the WEB-INF lib

  • activation-1.1.1.jar
  • apache-mime4j-0.6.jar
  • commons-codec-1.6.jar
  • commons-io-2.1.jar
  • commons-logging-1.1.3.jar
  • jackson-annotations-2.4.1.jar
  • jackson-core-2.4.1.jar
  • jackson-databind-2.4.1.jar
  • jackson-jaxrs-base-2.4.1.jar
  • jackson-jaxrs-json-provider-2.4.1.jar
  • jackson-module-jaxb-annotations-2.4.1.jar
  • javax.annotation-api-1.2.jar
  • javax.el-3.0.0.jar
  • jaxb-api-2.2.7.jar
  • jaxb-core-2.2.7.jar
  • jaxb-impl-2.2.7.jar
  • jboss-el-api_3.0_spec-1.0.0.Final.jar
  • jboss-jaxrs-api_2.0_spec-1.0.0.Final.jar
  • jboss-logging-3.1.4.GA.jar
  • resteasy-cache-core-3.0.13.Final.jar
  • resteasy-cdi-3.0.13.Final.jar
  • resteasy-client-3.0.13.Final.jar
  • resteasy-jackson2-provider-3.0.13.Final.jar
  • resteasy-jaxb-provider-3.0.13.Final.jar
  • resteasy-jaxrs-3.0.13.Final.jar
  • resteasy-links-3.0.13.Final.jar
  • resteasy-multipart-provider-3.0.13.Final.jar
  • resteasy-servlet-initializer-3.0.13.Final.jar
  • resteasy-validator-provider-11-3.0.13.Final.jar
  • stax2-api-3.1.1.jar
  • validation-api-1.1.0.Final.jar

And optionnally

  • hibernate-validator-5.0.1.Final.jar
  • resteasy-hibernatevalidator-provider-3.0.13.Final.jar
  • classmate-0.8.0.jar

I am not using maven for now, before I get a POC (proof of concept) working... so all these jars (exception javax.annotation 1.2) come from the RestEasy 3.0.13 download.

-----THE PROBLEM ------

The problem I run into, is that when ReatEasy tries to load its configuration, it complains it cannot find a validation implementation. For all I know, the container is supposed to come with a bean validation implementation but RestEasy can`t find it.

> Caused by: javax.validation.ValidationException: Unable to create a
> Configuration, because no Bean Validation provider could be found. Add
> a provider like Hibernate Validator (RI) to your classpath.   at
> javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:271)
>   at
> org.jboss.resteasy.plugins.validation.AbstractValidatorContextResolver.getConfig(AbstractValidatorContextResolver.java:78)

So then I add the 3 optionnal JARs listed above to provide a Hibernate Validator, and removed

  • resteasy-validator-provider-11-3.0.13.Final.jar

Then I get this error :

class not found : org.hibernate.validator.method.MethodValidator

So I figured that this was a Hibernate Validator 4.3 class which seems not to exists in hibernate validator 5. I went on, removed the Hibernate Validator jars (classmate + hibernate validators 5), and added the following 2 jars :

  • hibernate-validator-4.3.2.Final.jar
  • hibernate-validator-annotation-processor-4.3.2.Final.jar

I also removed this jar, as hibernate validator 4.3 implements bean validation 1.0.

  • validation-api-1.1.0.Final.jar

And then my hello JAX-RS 2.0 service worked!

I was shocked! Doesn't the JAX-RS needs a bean validation 1.1 to work?

How is it that RestEasy ships with Hib. Validator 5.X and the Hib.Validator seems to relies on Hib Validator 4.X?

Does anyone have similar issues with RestEasy? Any comments?

Let`s see what else break in the next few days! (god I miss Jersey on Tomcat)

extra info as I also post this as a reference for those who would have the same problems...


Final JAR list :

  • activation-1.1.1.jar
  • apache-mime4j-0.6.jar
  • commons-codec-1.6.jar
  • commons-io-2.1.jar
  • commons-logging-1.1.3.jar
  • hibernate-validator-4.3.2.Final.jar
  • hibernate-validator-annotation-processor-4.3.2.Final.jar
  • jackson-annotations-2.4.1.jar
  • jackson-core-2.4.1.jar
  • jackson-databind-2.4.1.jar
  • jackson-jaxrs-base-2.4.1.jar
  • jackson-jaxrs-json-provider-2.4.1.jar
  • jackson-module-jaxb-annotations-2.4.1.jar
  • javax.annotation-api-1.2.jar
  • javax.el-3.0.0.jar
  • jaxb-api-2.2.7.jar
  • jaxb-core-2.2.7.jar
  • jaxb-impl-2.2.7.jar
  • jboss-el-api_3.0_spec-1.0.0.Final.jar
  • jboss-jaxrs-api_2.0_spec-1.0.0.Final.jar
  • jboss-logging-3.1.4.GA.jar
  • resteasy-cache-core-3.0.13.Final.jar
  • resteasy-cdi-3.0.13.Final.jar
  • resteasy-client-3.0.13.Final.jar
  • resteasy-hibernatevalidator-provider-3.0.13.Final.jar
  • resteasy-jackson2-provider-3.0.13.Final.jar
  • resteasy-jaxb-provider-3.0.13.Final.jar
  • resteasy-jaxrs-3.0.13.Final.jar
  • resteasy-links-3.0.13.Final.jar
  • resteasy-multipart-provider-3.0.13.Final.jar
  • resteasy-servlet-initializer-3.0.13.Final.jar
  • stax2-api-3.1.1.jar

RestEasyConfig.java

@ApplicationPath("/services")
public class RestEasyConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {

        Set<Class<?>> classes = new HashSet<Class<?>>();

        classes.add(TestService.class);
        return classes;

    }

}

TestService.java

@Path("/test")
public class TestService extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getAccount() {

        String ok = "OK!";

        Map<String, String> map = new HashMap<String, String>();
        map.put("response", ok);

        Response response = Response.ok().entity(map).build();

        return response;
    }

}

The end point : https://localhost:9445/jaxrs2web/rest/test

The result :

{
    "response": "OK!"
}
1
Maybe you should consider using latest WebSphere Liberty Profile? For more details see wasdev.net. It fully supports Java EE7, JAX-RS-2.0 with CDI and JAX-WS is implemented using CXF stack, and get rid of all these libraries in your app.Gas
Yeah... I know full Java EE7: sweet! But no, I can't. Full WAS is a "non-functionnal" requirement. I swim in a blue pool. P AIX server, full WAS, remotly supportted by IBM wasAdmins, etc. The slightest change to this is not an option for reasons I can't state here. I also know that WAS 9 is beta in Bluemix, but I fear how long it will take to get to me!Filip
As per this article is Java EE 7 compatible, so it must provide a Bean Validation 1.1 provider. Therefore you should not add Hibernate Validator to your deployment and focus on investigating why JAX-RS doesn't pick it up. As JAX-RS also is part of EE 7, you probably should first look for references on how to replace the container-provided JAX-RS provider with another solution if the built-in one does not work for your purposes.Gunnar
unnar as stated par Gas, Websphere liberty profile 8.5.5 is JEE7.., WAS 8.5.5 (full) is JEE6 only. There is a major diff between Liberty Profile and full WAS.Filip
filipd, if full WAS is requirement, then I'd stick to Jax-RS, JAX-WS and JPA provided by WAS not by third party libraries. It will save you a ton of classloading issues. Also Hibernate is slower, than JPA provider used in WAS. And you cannot use JPA 2.1 in the container managed manner. So, unless you really, really have to use those 3rd party libs, stick with what is already in WAS.Gas

1 Answers

3
votes

So its turns out that there is 2 providers for bean validation provided with RestEasy.

A) One for Bean Validation 1.0 using absolutely Hibernate Validator 4.X. This has nothing to do with the JAX-RS spec... I guess it just a provider like any other.

B) The other for Bean Validation 1.1, which tries to uses bean validation implementation provider by the conatainer, using either CDI or JNDI.

Context context = new InitialContext();
validatorFactory = tmpValidatorFactory = ValidatorFactory.class.cast(context.lookup("java:comp/ValidatorFactory"));

I need to create my own provider to user my specific (hibernate validator 5.x) Bean Validation 1.1 implementation, as the containers implementation is a 1.0 impl.

This can be done easily using org.jboss.resteasy.plugins.validation.AbstractValidatorContextResolver.java as base code