March 11th, 2025

Replacing jackson-databind with azure-json and azure-xml

Alan Zimmer
Software Engineer

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.

Author

Alan Zimmer
Software Engineer

Alan works on the Azure SDK team building Java libraries. He primarily focuses on the Core, Search, and Storage libraries.

0 comments