Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hibernate Validator does not support constraints on static methods #10579

Closed
pilhuhn opened this issue Jul 8, 2020 · 13 comments · Fixed by #10639
Closed

Hibernate Validator does not support constraints on static methods #10579

pilhuhn opened this issue Jul 8, 2020 · 13 comments · Fixed by #10639
Labels
area/hibernate-validator Hibernate Validator kind/bug Something isn't working
Milestone

Comments

@pilhuhn
Copy link
Contributor

pilhuhn commented Jul 8, 2020

Describe the bug

We have code

   public static Pager extractPager(@NotNull UriInfo uriInfo) {

Which fails with "HV000116: The object to be validated must not be null." The passed uriInfo is not null, as one can see in the debugger or via printout.

This used to work in Quarkus 1.5.1 and earlier (in fact that line of code was last touched in January).
When I remove the @NotNull annotation, the code works expected.

Expected behavior

Code execution continues with a non-null uriInfo parameter

Actual behavior

Hibernate Validator throws an exception that the passed object must not be null, even if it is not null

To Reproduce

Calling code: https://github.com/RedHatInsights/policies-ui-backend/blob/master/src/main/java/com/redhat/cloud/policies/app/rest/PolicyCrudService.java#L237

Problematic code:
https://github.com/RedHatInsights/policies-ui-backend/blob/master/src/main/java/com/redhat/cloud/policies/app/rest/utils/PagingUtils.java#L45

@pilhuhn pilhuhn added the kind/bug Something isn't working label Jul 8, 2020
@quarkusbot quarkusbot added the area/hibernate-validator Hibernate Validator label Jul 8, 2020
@quarkusbot
Copy link

/cc @gsmet

@gsmet
Copy link
Member

gsmet commented Jul 8, 2020

Any chance you could come up with a simple reproducer?

I wonder if it's a consequence of some work that has been done to support interceptors in more cases. @geoand does it ring a bell?

Until now, I don't think HV was supposed to work for static methods especially for a non bean instance.

@geoand
Copy link
Contributor

geoand commented Jul 8, 2020

@gsmet absolutely right. I think that interceptors for static methods were added recently, so that would explain it (cc @mkouba)

@gsmet
Copy link
Member

gsmet commented Jul 8, 2020

I'll try to understand what's going on tomorrow. Not fair to break my extension that didn't ask anything!

@pilhuhn
Copy link
Contributor Author

pilhuhn commented Jul 8, 2020

Interceptor sounds right, as this is the top frame I end up when I step into extractPager():

1cb101e6936e2eb232d0960a042364b57af8d809:116, PagingUtils_InterceptorInitializer (com.redhat.cloud.policies.app.rest.utils)
extractPager:-1, PagingUtils (com.redhat.cloud.policies.app.rest.utils)
getPoliciesForCustomer:237, PolicyCrudService (com.redhat.cloud.policies.app.rest)
getPoliciesForCustomer$$superaccessor6:1497, PolicyCrudService_Subclass (com.redhat.cloud.policies.app.rest)

@mkouba
Copy link
Contributor

mkouba commented Jul 9, 2020

So if I understand it correctly the @NotNull annotation was previously ignored and nobody compained ;-). Now it's intercepted but fails incorrectly. We should probably (1) find out why it fails incorrectly, (2) ignore static methods in MethodValidatedAnnotationsTransformer if not supported and log a big warning for any javax.validation annotation declared on a static method.

@pilhuhn
Copy link
Contributor Author

pilhuhn commented Jul 9, 2020

Indeed, @NotNull is ignored in 1.5.1.

@pilhuhn
Copy link
Contributor Author

pilhuhn commented Jul 9, 2020

I don't think ignoring static methods is a good idea, as a lot of helpers are static and will/may/could use those validation annotations as a way to enforce pre-conditions without writing a lot of code.

@mkouba
Copy link
Contributor

mkouba commented Jul 9, 2020

I don't think ignoring static methods is a good idea...

Ok, but it never worked before because static method interception is not supported by Weld (and CDI in general).

I will create a simple test to see what's happening...

@mkouba
Copy link
Contributor

mkouba commented Jul 9, 2020

So the problem is that AbstractMethodValidationInterceptor.validateMethodInvocation() does not expect the result of ctx.getTarget() to be null. Unfortunately, the contract of javax.validation.executable.ExecutableValidator.validateParameters(T, Method, Object[], Class<?>...) is very clear - throw IllegalArgumentException if null is passed for any of the parameters... @gsmet Any idea how to workaround this limitation?

@gsmet gsmet changed the title Hibernate Validator is wrong in 1.6, works in 1.5.1 and earlier Hibernate Validator does not support constraint on static methods Jul 9, 2020
@gsmet
Copy link
Member

gsmet commented Jul 9, 2020

So, I had a look this morning. The spec thing is not a big issue as we could have an HV-specific interface extending it and taking a class.

What concerns me is that the executable validation feature has clearly been designed with the limitations of CDI/Weld in mind which were in line with the validation of beans. So a lot of things in HV expect an object, some SPI included (for instance DefaultGroupSequenceProvider).

I have absolutely no idea if we could shoe in support for that either by not supporting some features in this case or by redesigning things.

For now, I think I would go back to ignoring these annotations as they might be in area of the code developers can't touch.

Question: how should I do it? Should I simply ignore the static methods in the annotation transformer? What happened previously if the user called a static method on an instance object, it could be intercepted or not?

I suppose the other option would be to ignore things in the interceptor when ctx.getTarget() is null.

WDYT?

@mkouba
Copy link
Contributor

mkouba commented Jul 9, 2020

Question: how should I do it? Should I simply ignore the static methods in the annotation transformer?

I'd rather log a warning.

What happened previously if the user called a static method on an instance object, it could be intercepted or not?

I believe that it's called as a regular static method. So it was not intercepted.

@pilhuhn
Copy link
Contributor Author

pilhuhn commented Jul 9, 2020 via email

@gsmet gsmet changed the title Hibernate Validator does not support constraint on static methods Hibernate Validator does not support constraints on static methods Jul 10, 2020
gsmet added a commit to gsmet/quarkus that referenced this issue Jul 10, 2020
We go back to the previous behavior (but with a warning) as Hibernate
Validator does not support constraints on static methods.

Fixes quarkusio#10579
gsmet added a commit to gsmet/quarkus that referenced this issue Jul 16, 2020
We go back to the previous behavior (but with a warning) as Hibernate
Validator does not support constraints on static methods.

Fixes quarkusio#10579
@gsmet gsmet modified the milestones: 1.7.0 - master, 1.6.1.Final Jul 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/hibernate-validator Hibernate Validator kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants