Hi Steve, hi all,

We discussed this topic briefly in the last sync, in the context of
iceberg-core specifically. Here is a quick summary:

- The exposure of the Jackson 2 API in iceberg-core often appears accidental.

- If exposure is unavoidable, introducing dual exposure via method
overloads has been proposed.

- Another option under consideration is providing two separate
artifacts, one for Jackson 2 and one for Jackson 3.

- Ultimately, we need more time to evaluate the optimal path forward.

To help guide this decision, I did a deeper investigation into where
these Jackson types actually leak out. The exposure broadly falls into
four categories:

1) Parser classes (SchemaParser, MetadataUpdateParser, etc.)
2) The JsonUtil utility class.
3) The HTTPRequest.mapper() method.
4) RESTSerializers.registerAll(ObjectMapper) and
HTTPClient.Builder.withObjectMapper(ObjectMapper).

Based on these findings, I suggest the following approach for each area:

- For the parser classes (1), we should ideally restrict visibility to
package-private if feasible (implies revapi exceptions).

- For JsonUtil (2), I recommend either transitioning it to
package-private or deprecating it for removal.

- For HTTPRequest.mapper() (3), the exposure was an unfortunate design
choice: we should deprecate it for removal and re-implement the logic
within a package-private helper class.

Item (4) represents the biggest challenge since consumers legitimately
rely on them to configure their object mappers. Removing them entirely
might be too disruptive; a better approach would be to accept the
tight coupling and introduce parallel Jackson 3 overloads instead. Or,
as Steve mentions, add a layer of indirection to decouple the API
completely.

In conclusion, if we put the extension points (4) aside for a moment,
it looks like we have a clear opportunity to perform some API cleanup
before we fully commit to the Jackson 3 migration, by reducing the
Jackson 2 exposure to its minimum.

What do you all think?

Thanks,
Alex

On Mon, Jul 20, 2026 at 2:57 PM Steve Loughran <[email protected]> wrote:
>
>
> the public APIs are the pain point, and adding jackson 3 overloads is 
> possibly going to replicate the same problem.
>
> I'd propose
> - identify those things where json parsing/generation takes place and are 
> published
> - see how they could extended such that jackson 3 supported could be done 
> without adding jackson 3 to their signatures
>
> I'm thinking of how the various parsers have toJson() methods which take 
> jackson generators
>
>   public static void toJson(TableIdentifier identifier, JsonGenerator 
> generator)
>
> if another layer of indirection is added (JsonBinding?) that supplied the 
> generator then an overridden entry point could be supplied
>
>   public static void toJson(TableIdentifier identifier, JsonBinding binding)  
> {
>    if (binding instance of Jackson2Binding jackson2binding) {
>     return toJson(identifier, jackson2binding.generator());
>    } else {
>      return ((jackson3binding)bindiong)....)
>
> These could be added for the apis today, with the jackson2 stuff tagged as 
> deprecated, and new apis only coming though the new overload
>
> I'm glossing over the many implementation details here, but the key thing is: 
> exposing someone else's library as part your public API inevitably becomes 
> something you end up regretting.
>
>
> On Thu, 16 Jul 2026 at 15:53, Alexandre Dutra <[email protected]> wrote:
>>
>> Hi all,
>>
>> As more frameworks (like Spring Boot and Quarkus) migrate to Jackson
>> 3, I wanted to open a conversation about what a Jackson 3 migration
>> would look like for Iceberg and what trade-offs we should think
>> through together.
>>
>> Iceberg currently depends on Jackson 2 in several modules, most
>> significantly iceberg-core. Other modules with direct Jackson
>> dependencies include iceberg-aws, iceberg-nessie, iceberg-snowflake,
>> and iceberg-kafka-connect. Most modules could be migrated separately.
>>
>> The migration is largely mechanical but pervasive: artifact
>> coordinates and Java package names change across the board, several
>> core classes and methods are renamed, ObjectMapper construction moves
>> to a builder pattern, and exceptions become unchecked. JDK 17 is
>> required, which Iceberg already enforces.
>>
>> The blast radius for iceberg-core would be roughly:
>>
>> - Spark and Flink runtime JARs: low impact. Both already shade Jackson
>> 2; adding a relocation rule for Jackson 3 is a one-line fix per
>> runtime variant.
>>
>> - Kafka Connect: also low impact, although the Kafka Connect
>> distribution uses unshaded JARs.
>>
>> - Downstream users of iceberg-core: this is the most significant
>> concern. Jackson types leak into the public API of many XYZParser
>> classes, JsonUtil, and the REST HTTP layer.
>>
>> The honest answer is that icebegr-core's public API is permanently
>> Jackson-coupled by design. We should imho acknowledge this fact; the
>> best migration approach is to add Jackson 3 overloads wherever
>> applicable, and make Jackson 2 and 3 coexist for some time.
>>
>> Looking forward to hearing your thoughts on this topic.
>>
>> Thanks,
>> Alex

Reply via email to