Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.25k stars 1.93k forks source link

Change BinaryData fromObject(Object) and toObject(Class<T>) / toObject(TypeReference<T>) behavior #40816

Open alzimmermsft opened 3 days ago

alzimmermsft commented 3 days ago

BinaryData's fromObject(Object), toObject(Class<T>), and toObject(TypeReference<T>) APIs (and any *Async variants) will use a default JsonSerializer to handle consuming or converting data. Right now, this will attempt to load a classpath service provider implementation of JsonSerializer, if available, and if one isn't found it will fall back to a default implementation contained in azure-core. This comes with some unexpected side effects when an application adds a new dependency which could bring in a JsonSerializer implementation from the classpath, and unfortunately due to how JSON serialization works in the ecosystem different implementations generally don't play well using a simple plug-and-play concept like service providers.

For example, if an application had no implementations of JsonSerializer on the classpath and then updates to add a new dependency which transitively includes azure-core-serializer-json-gson, models may break during serialization if they were using Jackson annotations as now GSON's serializer is used which doesn't work with Jackson annotations.

Proposal: If the APIs that don't have a parameter for ObjectSerializer are used always use the default implementation in azure-core so there is consistent behavior no matter what happens to the classpath. This makes the Azure SDKs for Java more consistent by having a deterministic behavior here. Additionally, since there are no parameters used when loading the classpath implementation, it will now be clearer on how to configure custom serialization integration using one of our own implementations (azure-core-serializer-json-gson, azure-core-serializer-json-jackson, azure-core-serializer-avro-apache) or by providing a custom implementation.

Additionally, we should put this behavior behind a compatibility switch which re-enables allowing classpath look ups to determine the default JsonSerializer used. This will allow for cases where classpath mutation should be respected to continue working without requiring immediate code changes.