[resteasy-dev] resteasy jax-rs fail fast on entity validation exception

Ron Sigal rsigal at redhat.com
Fri Oct 27 12:03:26 EDT 2017


It's me again.

John, what you're describing is the behavior I wrote about on Wednesday. 
Discussion inline:


On 10/27/2017 03:03 AM, John O'Hara wrote:
>
> Thank you for your responses. If I fill you in on a bit of background 
> about what I have experienced, then it might help clarify the issue I 
> see.
>
>
> Background
>
>
> I am running a JEE benchmark on EAP7.1 (using resteasy 3.0.24.Final). 
> One of rest endpoints has a @Valid annotation on a method parameter 
> for a complex object.
>
>
> @POST
>
> @Path("/foo")
>
> @Consumes(MediaType.APPLICATION_JSON)
>
> public void addFoo(@Valid Foo bar) throws Exception {
>
>
> The Foo class contains different validation annotations, such as 
> @NotNull, @Size, @Pattern and a custom validation annotation.
>
>
> One test determines how WF/EAP handles invalid requests. When I invoke 
> the endpoint above I see a non-deterministic response from the app 
> server.  If I invoke the endpoint with an invalid json object I 
> receive a HTTP 400 exception as expected, but if I invoke the endpoint 
> with a valid object, and *then* invoke the endpoint with an invalid 
> object I receive a HTTP 500 error.
>
>
> This exception only occurs on some property validation annotations and 
> not all (e.g. @NotNull works as expected)
>
>
> The test is being run in the context of CDI, and the HTTP 500 error is 
> coming from the ejb3 subsystem. The ejb3 subsystem is wrapping the 
> ConstraintValidationException raised by hibernate-validator.
>
>
>
> Observations
>
>
> In the call stack I capture [1], and WF thread dump [2] I can see;
>
>
> 1.
>
>     The test is run in the context of CDI. The HTTP 500 response code
>     message is caused by the ejb3 subsystem wrapping a
>     ConstraintValidationException raised by hibernate-validator
>
>
> 2.
>
>     The validator is not called in
>     ResourceMethodInvoker.invokeOnTarget() [3] as isValidatable is
>     false [4], a ResteasyViolationException is not thrown
>
>
> 3.
>
>     The request is validated again here [5], the validation exceptions
>     are not acted upon in this method call and the reflected method
>     (which happens to be the Foo class constructor) is called here [6]
>
>
>
> Questions
>
>
> 1.
>
>     Why is ResourceMethodInvoker.isValidatable false in WF/EAP?
>

In the context of CDI, field and property injections are not carried out 
until a method is called on an object. I don't know why, but that's how 
it is. So it's possible to do parameter validation inline in 
MethodInjectorImpl.invoke(), but it's premature to do field/parameter 
validation in ResourceMethodInvoker.invokeOnTargetAfterFilter().

> 1.
>
>     If isValidatable is false, and validation occurs again at
>     MethodInjectorImpl.invoke() can we not check for validation errors
>     and raise the correct exception there as well?
>

In effect, that's what is happening, but it's buried in 
org.jboss.resteasy.cdi.JaxrsInjectionTarget.inject(). In particular:

>        private void validate(HttpRequest request, T instance)
>        {
>           if (GetRestful.isRootResource(clazz))
>           {
>              ResteasyProviderFactory providerFactory =
>     ResteasyProviderFactory.getInstance();
>              ContextResolver<GeneralValidatorCDI> resolver =
>     providerFactory.getContextResolver(GeneralValidatorCDI.class,
>     MediaType.WILDCARD_TYPE);
>              if (resolver != null)
>              {
>                 validator =
>     providerFactory.getContextResolver(GeneralValidatorCDI.class,
>     MediaType.WILDCARD_TYPE).getContext(null);  /// Hmmm, this looks
>     redundant ...
>              }
>              if (validator != null &&
>     validator.isValidatableFromCDI(clazz))
>              {
>                 validator.validate(request, instance);
>                 validator.checkViolationsfromCDI(request);
>              }
>           }
>        }


Note that validator.checkViolationsfromCDI(request) will throw a 
ResteasyViolationException if any field/property/parameter violations 
have been detected.

-Ron

>
>
> I have a standalone test that I will clean up and push out. There are 
> some aspects of the test that can not be published publicly, so I need 
> to modify them first.
>
>
> Thanks,
>
>
> John
>
>
>
> [1] - see failing_4.stack
>
> [2] - see WF_stackTrace.out
>
> [3] - 
> https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/ResourceMethodInvoker.java#L305
>
> [4] - 
> https://github.com/resteasy/Resteasy/blob/master/providers/resteasy-validator-provider-11/src/main/java/org/jboss/resteasy/plugins/validation/GeneralValidatorImpl.java#L223
>
> [5] - 
> https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/MethodInjectorImpl.java#L119
>
> [6] - 
> https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/MethodInjectorImpl.java#L140
>
>
>
>
>
> _______________________________________________
> resteasy-dev mailing list
> resteasy-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/resteasy-dev

-- 
My company's smarter than your company (unless you work for Red Hat)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/resteasy-dev/attachments/20171027/3439c386/attachment-0001.html 


More information about the resteasy-dev mailing list