On 10/27/2017 08:33 AM, John O'Hara wrote:
After some more digging, I have found that this issue occurs if the
the rest endpoint is also defined as an ejb managed bean. e.g.
@Stateless @Path("/policyholder")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PolicyHolderEndpoint {
In this case the JaxrsInjectionTarget.inject() is only called on the
first endpoint invocation, and not on subsequent calls.
Hmmm. @Stateless, so it doesn't have @Request scope; i.e., it's created
just once. I conjecture you wouldn't see this problem for a @Stateful
session bean.
In the application the pusdo PolicyHolderEndpoint class is also a
managed bean that is injected into other services as a single entry
point for managing policyHolders.
Is it reasonable to expect a rest endpoint can also be defined as an
ejb managed bean?
According to the JAX-RS spec:
10.2.4 Enterprise Java Beans (EJBs)
In a product that supports EJBs, an implementation MUST support
the use of stateless and singleton ses-
sion beans as root resource classes, providers and Application
subclasses. JAX-RS annotations can be
applied to methods in an EJB’s local interface or directly to
methods in a no-interface EJB. Resource class
annotations (like @Path ) MUST be applied to an EJB’s class
directly following the annotation inheritance
rules defined in Section 3.6.
I need to look into why weld isn't injecting the JaxrsInjectionTarget,
butI think that my original question still stands in this use case.
If we are running in a CDI context, we already ascertain in
MethodInjectorImpl.invoke() whether there are validation exceptions by
calling [1]. Can we fail at this point, rather than delegating the
validation to the CDI manager and waiting for a callback?
The CDI spec says we have to accumulate as many violations as possible
before throwing an exception,so, in general, we still have to proceed to
check field / property violations.
BUT ... I think the scope is the source of the problem. If an EJB
session bean is created just once, then field / parameter injections
should be checked only once. On subsequent calls, it does, as you say,
make sense to stop and throw an exception after checking parameters.
SO ... if my reasoning makes sense, this is something that should be
handled in Resteasy. If you agree, do you want to create a JIRA and I'll
work on it? What do you think?
-Ron
Thanks
[1] -
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/...
On Fri, Oct 27, 2017 at 8:21 AM, John O'Hara <johara(a)redhat.com
<mailto:johara@redhat.com>> wrote:
Ron,
I re-read your email and double checked the call
to GeneralValidatorImpl.checkViolationsfromCDI().
I only see this being called once, on the first request.
I will dig some more to see why it is not being called on all requests
Thanks
John
On Fri, Oct 27, 2017 at 8:03 AM, John O'Hara <johara(a)redhat.com
<mailto:johara@redhat.com>> 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?
2.
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?
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/...
<
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/...
[4] -
https://github.com/resteasy/Resteasy/blob/master/providers/resteasy-valid...
<
https://github.com/resteasy/Resteasy/blob/master/providers/resteasy-valid...
[5] -
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/...
<
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/...
[6] -
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/...
<
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/...
--
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>
--
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>
_______________________________________________
resteasy-dev mailing list
resteasy-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/resteasy-dev --
My company's smarter than your company (unless you work for Red Hat)