question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`io.micronaut.validation.Validated` does not work on `final` classes

See original GitHub issue

Using 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:closed
  • Created 2 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
David-16commented, Jun 4, 2021

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 hints

Example that does the correct thing by enforcing payload size:

@Controller("/v1")
public class BasicRestService {
    @Post("/hello")
    public String sayHello(@Valid final Payload payload) {
        return String.format("Hola, %s!\n", payload.getName());
    }
}

@Introspected
@Immutable
@JsonDeserialize(as = ImmutablePayload.class)
public interface Payload {
    @Size(min = 1, max = 11)
    String getName();
}

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 is

Again, sorry to waste your time by not doing proper due diligence

0reactions
David-16commented, Jun 4, 2021

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Validating the POJO record with Micronaut not working
Using Micronaut bean validation for the record class is not working compile 'io.micronaut:micronaut-validation:2.2.1'. Record class
Read more >
1 Introduction - Micronaut Documentation
Implicit @Validated and @Valid. It is no longer necessary to apply the @Validated annotation to beans that accept @Valid arguments or use any...
Read more >
Table of Contents - Micronaut Documentation
Micronaut is a modern, JVM-based, full stack Java framework designed for building modular, easily testable JVM applications with support for Java, Kotlin and ......
Read more >
Error Handling - Micronaut Guides
Micronaut has built-in support for validation of beans that are annotated with javax.validation annotations. The necessary dependencies are included by default ...
Read more >
Management & Monitoring - Micronaut Documentation
Support validation groups with @Validated. You can ... import io.micronaut.context. ... should be used in place of the annotation classes when working with ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found