Filip
Filip

Reputation: 1058

RestEasy 3.0.13 on WebSphere 8.5.5 : Bean Validation Framework version issue

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

And optionnally

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

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 :

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

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 :

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!"
}

Upvotes: 2

Views: 2200

Answers (1)

Filip
Filip

Reputation: 1058

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

Upvotes: 3

Related Questions