Skip to content

Fully document API changes made in 3.0 #5161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
odrotbohm opened this issue May 14, 2025 · 9 comments
Open
1 task done

Fully document API changes made in 3.0 #5161

odrotbohm opened this issue May 14, 2025 · 9 comments
Labels
to-evaluate Issue that has been received but not yet evaluated

Comments

@odrotbohm
Copy link

odrotbohm commented May 14, 2025

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

I am in the process of migrating a large code base containing an extensive set of custom Jackson (de)serializers and the experience is suboptimal. Types are gone, methods are moved or even removed without any hint, what implementors are supposed to do instead. Here's a (certainly non-exhaustive) shortlist of things I found:

  • StdScalarSerializer.getSchema(…) is gone
  • JsonToken.FIELD_NAME is now JsonToken.PROPERTY_NAME I assume
  • PropertyNamingStrategyBase is gone. It had been deprecated before, but without recommendation what to use instead.
  • NamingBase.translate(String) is protected now
  • JsonGenerator.getOutputContext() apparently is ….streamWriteContext() now
  • JsonGenerator.getCurrentValue() apparently is ….currentValue() now
  • MapSerializer.construct(…) signature has changed completely
  • ObjectMapper.findMixInClassFor(Class) is gone
  • How do I tweak an existing ObjectMapper instance? I understand I can use JsonMapper.builder() to create a new one, but I need to be able to configure existing instances.
  • What's a good replacement for ObjectMapper.copy()?
  • The MapperFeature.AUTO_DETECT_… constants are gone

Version Information

3.0 RC4

Reproduction

No response

Expected behavior

No response

Additional context

No response

@odrotbohm odrotbohm added the to-evaluate Issue that has been received but not yet evaluated label May 14, 2025
@pjfanning
Copy link
Member

ObjectMapper.rebuild() gives you a mapper builder that you can tweak and then call build on that to give you a new mapper.

@pjfanning
Copy link
Member

The jsonschema support is removed in Jackson 3.
https://github.com/FasterXML/jackson-module-jsonSchema?tab=readme-ov-file#future-plans-lack-thereof

There are some 3rd party libs that attempt to support JsonSchema with Jackson and their maintainers may be interested in also supporting Jackson 3.

@odrotbohm
Copy link
Author

We previously had hooks for users that took an ObjectMapper for customization but didn't return any value. The proper API to expose now seems to be JsonMapper.Builder. Unfortunately, ObjectMapper.rebuild() does not produce a compatible type. It looks like my only option is to stick with ObjectMapper but change APIs to now return (changed) instances and require users to manually ….rebuild(). … .build(), which feels quite unfortunate.

@cowtowncoder
Copy link
Member

cowtowncoder commented May 15, 2025

Here are some wiki pages that should contain majority of changes:

@cowtowncoder
Copy link
Member

cowtowncoder commented May 15, 2025

On ObjectMapper: yes, 3.0 makes mapper fully immutable, and Builders are the only way to configure things.

On rebuild()/build(), note that ObjectMapper is the base type, and type-safe one is JsonMapper subtype. Type is retained for it -- but ObjectMapper itself cannot do that.
It perhaps should have been changed to abstract to make this clear.

Various other notes on questions:

  • ObjectMapper.copy() is unnecessary as mappers are immutable. But if you want equivalent, mapper.rebuild().build(); does it
  • PropertyNamingStrategyBase will also be removed from 2.20 -- as per comments, see PropertyNamingStrategy class initialization depends on its subclass, this can lead to class loading deadlock #2715 for reasons for removal -- nasty crash possible.
    • Replacement for both 2.x and 3.0 is PropertyNamingStrategies.NamingBase
  • The MapperFeature.AUTO_DETECT_… constants are gone -- visibility configuration via ObjectMapper.builder().changeDefaultVisibility(...)
    • probably best to check out unit tests for usage.

@odrotbohm
Copy link
Author

That's incredibly helpful, Tatu. Thanks!

Regarding NamingBase: I called translate(String) to translate a few internal values applying the strategy generally defined on the Jackson level. Do you think that could be made public again?

@odrotbohm
Copy link
Author

After playing with this, the lack of a unified configuration API is really a bit cumbersome. I switched from customization APIs exposing UnaryOperator<JsonMapper.Builder> to UnaryOperator<MapperBuilder<ObjectMapper, ?>. The latter works with builders obtained via ObjectMapper.rebuild(). However, JsonMapper.builder() is not a MapperBuilder, which means I now have to do this dance again to be able to apply customizations to a JsonMapper.Builder

ObjectMapper mapper = JsonMapper.builder()
  . … customizations
  .build()

customizer.apply(mapper.rebuild());

The intermediate assignment is necessary to get to a MapperBuilder instead of a Builder. I might just hold things wrong. My goal is to expose customization abilities to users and ideally, I'd like to be able to invoke those both coming from an existing ObjectMapper or a fresh Builder.

@cowtowncoder
Copy link
Member

cowtowncoder commented May 15, 2025

Regarding NamingBase: I called translate(String) to translate a few internal values applying the strategy generally defined on the Jackson level. Do you think that could be made public again?

While it seems somewhat wrong (there's a reason it was made non-public), it's probably not the biggest sin in the world -- so would be open to a PR if you wanted to submit one?

@cowtowncoder
Copy link
Member

On Builders; I think the issue stems from ObjectMapper (and its builder) not having "this type" parameter.
At any rate I don't think there are easy changes.

One thing that might help is knowing that builders do NOT create new copies; they always return this for call chaining but do not create new instances. Not sure if you could make of this invariant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
to-evaluate Issue that has been received but not yet evaluated
Projects
None yet
Development

No branches or pull requests

3 participants