Skip to content

Jackson2HttpMessageConvertersConfiguration uses ConditionOn Jackson3 XMLMapper class #49015

@tvahrst

Description

@tvahrst

Short description:
With SpringBoot 4, Jackson2HttpMessageConvertersConfiguration contains a nested Configuration class (MappingJackson2XmlHttpMessageConverterConfiguration) to provide Jackson2XmlMessageConvertersCustomizer as soon as xml-dataformat is present. The condition

@ConditionalOnClass(tools.jackson.dataformat.xml.XmlMapper.class)	

uses (accidentely) the Jackson3 XmlMapper class, which can lead to NoClassDefFoundErrors

Details
Many of our applications still require Jackson2ObjectMapperBuilder for the programmatic deserialization/serialization of objects. While we switched to Jackson3 by default when we upgraded to Spring Boot 4, we still provide a Jackson2ObjectMapperBuilder bean in the spring context for compatibility reasons. (We do not set spring.http.converters.preferred-json-mapper: jackson2).

This triggers the Jackson2HttpMessageConvertersConfiguration and leads to NoClassDefFoundErrors as soon as Jackson3 xml-dataformat is present.

Sample Code to reproduce the exception

pom.xml

		<!-- Jackson 3 Deps -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jackson</artifactId>
		</dependency>
		<dependency>
			<groupId>tools.jackson.dataformat</groupId>
			<artifactId>jackson-dataformat-xml</artifactId>
		</dependency>

		<!-- for Jackson2ObjectMapperBuilder -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
		</dependency>

DemoApplication.class

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}


       //  SB35 compatibility bean
	@Bean
	@Scope("prototype")
	public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(){
		return new Jackson2ObjectMapperBuilder();
	}
}

Exception:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.http.converter.autoconfigure.Jackson2HttpMessageConvertersConfiguration$Jackson2XmlMessageConvertersCustomizer]: Factory method 'mappingJackson2XmlHttpMessageConverter' threw exception with message: com/fasterxml/jackson/dataformat/xml/XmlMapper
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:183) ~[spring-beans-7.0.3.jar:7.0.3]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiateWithFactoryMethod(SimpleInstantiationStrategy.java:72) ~[spring-beans-7.0.3.jar:7.0.3]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:152) ~[spring-beans-7.0.3.jar:7.0.3]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-7.0.3.jar:7.0.3]
	... 65 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/dataformat/xml/XmlMapper
	at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.build(Jackson2ObjectMapperBuilder.java:684) ~[spring-web-7.0.3.jar:7.0.3]
	at org.springframework.boot.http.converter.autoconfigure.Jackson2HttpMessageConvertersConfiguration$MappingJackson2XmlHttpMessageConverterConfiguration.mappingJackson2XmlHttpMessageConverter(Jackson2HttpMessageConvertersConfiguration.java:73) ~[spring-boot-http-converter-4.0.2.jar:4.0.2]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:565) ~[na:na]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:155) ~[spring-beans-7.0.3.jar:7.0.3]
	... 68 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.dataformat.xml.XmlMapper
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:490) ~[na:na]
	... 73 common frames omitted

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions