In Spring 5.3, to address this issue, Spring added a new API here. It is supposed to be used like this:

@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
    return builder -> builder.modules(list -> list.add(...));
}

Sadly, if you add exactly that configuration along side JacksonAutoConfiguration, Spring Boot would break with an unhinged java.lang.UnsupportedOperationException: null. This is due to the following lines in JacksonAutoConfiguration:

private void configureModules(Jackson2ObjectMapperBuilder builder) {
    builder.modulesToInstall(this.modules.toArray(new Module[0]));
}

The cause is the implementation of Jackson2ObjectMapperBuilder.modulesToInstall(Module...modules), particularly this line:

this.modules = Arrays.asList(modules);

Spring will reuse this.modules and use it when you call builder.modules(Consumer<List<Module>>) causing the exception.

A solution should be easy, we can either patch JacksonAutoConfiguration or on Spring side.

Currently, for a workaround, it is reasonable to make do with:

@Bean
Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    return builder -> builder.modules(list -> {
            List<Module> modules = new ArrayList<>(list);
            // extra modules here
            builder.modules(modules);
    });
}

Comment From: wilkinsona

Thanks for the report. The javadoc of Jackson2ObjectMapperBuilder advises against mixing modules and modulesToInstall, however your customizer would still cause a failure if it used modulesToInstall(Consumer<List<Module>>). I've asked the Framework team for their opinion.