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

John O'Hara johara at redhat.com
Fri Oct 27 13:24:37 EDT 2017


Ron,

I realised that after I sent my email.

The issue happens when the rest endpoint is an ejb managed bean,
org.jboss.resteasy.cdi.JaxrsInjectionTarget.inject() only gets called in
the first invocation of the endpoint.  On subsequent invocations,
JaxrsInjectionTarget.inject() is not called, so the validation exceptions
are not handled and I see a http 500 cause by a wrapped validation
exception being thrown in the ejb subsystem.

John

On Fri, Oct 27, 2017 at 5:03 PM, Ron Sigal <rsigal at redhat.com> wrote:

> 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
>
>
>
>    1.
>
>    The validator is not called in ResourceMethodInvoker.invokeOnTarget()
>    [3] as isValidatable is false [4], a ResteasyViolationException is not
>    thrown
>
>
>
>    1.
>
>    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 listresteasy-dev at lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/resteasy-dev
>
>
> --
> My company's smarter than your company (unless you work for Red Hat)
>
>
> _______________________________________________
> resteasy-dev mailing list
> resteasy-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/resteasy-dev
>
>


-- 

JOHN O'HARA

PRINCIPAL SOFTWARE ENGINEER

Red Hat <https://www.redhat.com/>
<https://red.ht/sig>
TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
@redhatway <https://twitter.com/redhatway>   @redhatinc
<https://instagram.com/redhatinc>   @redhatsnaps
<https://snapchat.com/add/redhatsnaps>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/resteasy-dev/attachments/20171027/35fe144e/attachment-0001.html 


More information about the resteasy-dev mailing list