jackson-databind (Jackson) is performant, reliable, and universally known in
the Java ecosystem. Unfortunately, our dependency on it results in pain points when consuming the Azure SDK client libraries for
Java. Over the last few years, the Azure SDK for Java team worked to limit our reliance on jackson-databind.
Why was this change made?
Jackson is widely used in the Java ecosystem, but the versions being used varies library to library. This arrangement leads to dependency conflicts when multiple libraries bring in differing versions of Jackson, which can cause runtime issues. The Azure SDK for Java aims to minimize these conflicts and improve compatibility across different environments. Additionally, Jackson’s reliance on reflection can cause issues with the Java module system and security policies.
Introducing azure-json and azure-xml
To reduce and replace Jackson usage, the Azure SDK for Java now offers two new serialization libraries: azure-json
and azure-xml. These libraries support
JSON and XML serialization respectively, providing streaming readers and writers, and interfaces for models to implement serialization
behaviors. Neither library includes runtime dependencies, reducing the chances of dependency conflicts.
azure-json includes JsonReader, JsonWriter, and JsonSerializable, inspired by the JSON specification
and streaming APIs from jackson-core and gson (Gson). It uses the JsonProvider service provider interface (SPI) for creating instances,
with a default implementation using shaded jackson-core. azure-json also includes a model-based JSON structure in com.azure.json.models.
azure-xml includes XmlReader, XmlWriter, and XmlSerializable, inspired by the javax.xml.stream
APIs. These classes wrap Java’s XMLStreamReader and XMLStreamWriter interfaces. For performance reasons, azure-xml uses shaded
aalto-xml if the built-in implementations are resolved.
Using azure-json and azure-xml reduces dependency conflicts and the need for reflection, improving compatibility with the
Java module system.
Changes to models in Azure SDK for Java client libraries
Previously, client library models used jackson-annotations for serialization. Now, with azure-json and azure-xml, these
annotations are replaced with JsonSerializable and XmlSerializable implementations. This change reduces the need for
reflection and simplifies support for both JSON and XML serialization.
Integration points with Jackson and Gson
To integrate with existing applications, we provide support for serializing and deserializing JsonSerializable types using
Jackson and Gson. We also offer full implementations of JsonReader and JsonWriter in these libraries.
In azure-core-serializer-json-jackson, use JacksonJsonProvider.getJsonSerializableDatabindModule() to get a Jackson Module
that handles JsonSerializable types:
ObjectMapper objectMapper = JsonMapper.builder()
.addModule(JacksonJsonProvider.getJsonSerializableDatabindModule())
.build();
In azure-core-serializer-json-gson, use GsonJsonProvider.getJsonSerializableTypeAdapterFactory() to get a Gson TypeAdapter
that handles JsonSerializable types:
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(GsonJsonProvider.getJsonSerializableTypeAdapterFactory())
.create();
What happened to Jackson dependencies?
The Azure SDK for Java client libraries continue to depend on jackson-annotations, jackson-core, and jackson-databind in
azure-core for functionality that can’t be achieved by the azure-json and azure-xml streaming APIs. jackson-dataformat-xml
was removed as a dependency. Most non-azure-core* libraries eliminated direct dependencies on Jackson, relying instead on
azure-json and azure-xml.
The Azure SDK for Java team continues to explore the possibility of completely removing Jackson dependencies in azure-core.
If you have questions or concerns, contact us on GitHub.
0 comments