jackson-modules-base icon indicating copy to clipboard operation
jackson-modules-base copied to clipboard

Generate reflection-free Jackson serializers at compile time

Open mariofusco opened this issue 1 year ago • 1 comments

I'm opening this issue only to start a discussion about the possibility of automatically generating reflection-free Jackson (de)serializers. My current understanding is that Afterburner first and Blackbird now are 2 modules designed with exactly this purpose. Their drawback however is that they generate at runtime reflection-free accessors for a specific field/method while, thanks to Quarkus architecture and tools like Jandex and Gizmo, I could be able to generate at build time the serializer for a whole pojo like I started doing in this PoC.

I would like to continue that experiment, but before moving too much forward and wasting my time, I wanted to share my doubts about it:

  1. Is there anything similar that we could do directly in Jackson, instead of implementing it in a Quarkus extension? For instance have you considered using an annotation scanner at build time and triggering the generation of the serializers for the annotated user's pojos from a maven plugin?
  2. Even if this is not feasible (or simply out of scope for Jackson) is there any rework/refactor that we could implement in Jackson in order to avoid duplicating in the Quarkus extension all the complex Jackson serialization logic?
  3. My main concern regarding the former point is that Jackson serialization comes with a tons of features and edge cases and it will be extremely hard and error-prone to reimplement all of them in Quarkus. The strategy that I have in mind (admittedly suboptimal) to workaround this problem is having a list of the Jackson's features that we support and generate seralizers only against them and when we bump into an unknown annotation we avoid to generate the serializer at all for that specific pojo, thus falling back to the reflection based Jackson mechanism. Do you see any issue with this approach or have any better suggestion?

Any feedback is welcome. /cc @cowtowncoder

mariofusco avatar Jul 11 '24 14:07 mariofusco

Quick note: yes, I have occasionally thought about such a thing, but no, nothing implemented.

Afterburner and Blackbird are sort of half of the puzzle: to remove runtime use of Reflection for constructing and setting/getting values. But to do generation itself on runtime. Nothing in Jackson stack works on build time, so this would need to be a whole new set of machinery. And even with that, the concern of complicated handling possible deviating from vanilla/default handling is quite real.

If someone was to consider build-time generation of matching (de)serializers -- or, maybe better yet, sort of adapters called generically (sort of minimalistic handler classes Afterburner/Blackbird generate), I'd be happy to help.

It could be something like generating bytecode for "setter"/"getter" classes associated with value types, for which general "BuildTime[De]Serializer"s could be built; containing something like "setString(String property/int index, String value)" (and similarly for "getXxx()"

Or more generally: yes, I'd be perfectly happy adding small extension points that might be needed for build-time generated handlers.

And directly on points:

(1) As per above, no, I don't think there's anything more than small pieces by AB/BB (2) Not sure, but I would be willing to help do refactor if some was identified to help (3) Yes, this makes sense to me. And sounds similar to how AB/BB downgrade to standard handling when necessary.

cowtowncoder avatar Jul 13 '24 00:07 cowtowncoder

Looks like there has been some work committed to Quarkus: would be nice to have links from here to outcomes, docs, if possible? (sounds like serialization-side opt-in optimization feature flag now exists)

cowtowncoder avatar Oct 14 '24 15:10 cowtowncoder

This is still a work in progress, anyway I explained what I have done so far in this post https://quarkus.io/blog/quarkus-metaprogramming/

mariofusco avatar Oct 14 '24 16:10 mariofusco

Ok thank you for sharing @mariofusco !

cowtowncoder avatar Oct 14 '24 16:10 cowtowncoder