grails-core
grails-core copied to clipboard
Codec order is not respected by default
Codecs are intended to support an "order" property, but this is not correctly respected by the DefaultCodecLookup. This implies that it is impossible to override one codec with another with the same name, unless they just happen to load in the order desired.
In DefaultCodecLookup .registerCodecs() when called from the default startup events, the codecs are retrieved and sorted using OrderComparator.INSTANCE. However, at this point the codec order in DefaultGrailsCodecClass has not yet been initialized, and is the default of 100+instantiationCounter.
Consequently, adding an order property/getter on a *Codec class is not respected unless the codec is preinitialized in some way, or initialization is triggered twice. This does mean that there is an easy (and computationally cheap) workaround: simply call applicationContext.getBean('codecLookup', DefaultCodecLookup).reInitialize() again during application startup. However, it seems that it would be better to respect the order property during the first initialization.
With what version of Grails are you working?
Is there a reason that a codec makes more sense than extension methods for your use case?
Thanks for the feedback.
Totally forgot that part!
This is in 3.2.10. If it's fixed in 3.3.x I personally don't think it's critical enough for the 3.2 branch, but it also seemed subtle enough to go unnoticed for a long time.
I really don't know if there is a better implementation for our use case; it's some code that's been upgraded since 1.1 and honestly could probably use some big picture refactoring. That said, if codecs are supposed to support order, it seems like they probably should respect that during initialization!
Just stumbled upon this. I am trying to overwrite the default JSONCodec
because it serializes bare strings without quotes (which I think is also not correct behavior), but apparently it is not possible because the order of codecs is initialized after they have been sorted. 😒
btw: This is now on Grails 5.1.2.