`io.micronaut.validation.Validated` does not work on `final` classes
See original GitHub issueUsing Micronaut @Validated
appears to generate proxies which extend the class
Compiling the following:
@io.micronaut.validation.Validated
@org.immutables.value.Value.Immutable
@com.fasterxml.jackson.databind.annotation.JsonSerialize(as = ImmutableFoobar.class)
public interface Foobar {
String getFoo();
}
Results in following:
[ERROR] /blah/blah/target/generated-sources/annotations/ImmutableFoobar.java:[28,13]
error: Cannot apply AOP advice to final class. Class must be made non-final to support proxying: ImmutableFoobar
Note the compile error is likely from Micronaut’s pre-processor. it goes away if not using @JsonSerialize
but the usecase here is to use this as a payload so not really an option
Micronaut is a compile time oriented dependency injector and does not rely on reflection, so I get why Micronaut probably needs to extend the class to make a proxy
I also get why Immutables makes the class final
(at least I think). But the constructor is private
so extending it is already hampered by that, plus everything is basically final
within the class anyway, so I do not think making it final
really buys much in terms of safety
I guess I could generate the Immutable class, add it to my source file, make it non-final, comment out the @Immutable
annotation, and repeat this exercise if/when the class changes
Is there any middle ground?
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)
Okay, seems like this was a waste of your time, for which I apologize
The swagger codegen tool I was using was annotating the model classes so I assumed that was the correct thing to do. Seems like that is not the case. Adding annotations on the model class does not seem to enforce validation. Will have to follow up with codegen project to see why they are doing this
The minimum that seems to be required is to annotate the rest controller method argument with
@Valid
and annotate the class of the type in the aforementioned method with@Introspected
so Micronaut will process it and generate the hintsExample that does the correct thing by enforcing payload size:
I did learn that if you do not include
io.micronaut.beanvalidation:micronaut-hibernate-validator
then it will default to some other implementation, but I do not know what it isAgain, sorry to waste your time by not doing proper due diligence
First, I misspoke about Micronaut generating source code during pre-compilation phase; it was just my IDE de-compiling stuff and me not paying attention. Micronaut seems to generate hints from the annotations that would otherwise be read at run time and generates a bunch of helper classes for each kind of validation. That much I kind of knew before but I never stared at the classes before because they are just generated junk for the most part. However, after doing said staring, I cannot see anywhere where the class is actually extended. Maybe I should look at the source of the pre-processor to see what it is doing when it checks for
final
Regarding #1, you raise a good point. My issue arose while using a swagger code generator which spits out source code. It chooses to annotate the datatype; not the controller. Let me try reversing that to align with the examples in the documentation and see if that does not resolve things before I waste your time on this. If it works, I will move my beef there
Regarding #2, I do not think Micronaut has their own validator. The docs suggest adding
io.micronaut.beanvalidation:micronaut-hibernate-validator
to your project (see https://docs.micronaut.io/latest/guide/#datavalidation). So I assume this uses Hibernate under the covers as the name suggests, but I have not dug into it much. As part of my tests, I will force a validation error and check the stacktrace.