Description
Describe the bug
I'm trying to replace fasterxml-jackson
dependency with gson
from my simple app with just two dependencies: spring-boot-starter-web
and spring-cloud-function-web
dependencies.
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-json'
}
implementation 'com.google.code.gson:gson'
implementation("org.springframework.cloud:spring-cloud-function-web") {
exclude group: 'com.fasterxml.jackson.datatype'
exclude group: 'com.fasterxml.jackson.core'
exclude group: 'com.fasterxml.jackson.module'
}
I also have the following config to use gson mapper as preferred mapper for both http converter and cloud function.
spring.http.converters.preferred-json-mapper=gson
spring.cloud.function.preferred-json-mapper=gson
Scenario 1
When i run my empty project, i get following error (full stacktrace is on the repository)
java.lang.IllegalStateException: Error processing condition on org.springframework.cloud.function.observability.ObservationAutoConfiguration
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.5.0.jar:3.5.0]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:99) ~[spring-context-6.2.7.jar:6.2.7]
at gt.cloudfunctionjson.CloudFunctionJsonApplication.main(CloudFunctionJsonApplication.java:14) ~[main/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$JsonMapperConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@4e0e2f2a]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483) ~[spring-core-
... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/Module
... 33 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.Module
... 37 common frames omitted
Scenario 2
When I provide my own JsonMapper bean to bypass config initialization from org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration.JsonMapperConfiguration#jsonMapper
, i get a similar error from different place.
@Bean
JsonMapper gsonMapper(Gson gson) {
return new GsonMapper(gson);
}
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657) ~[spring-beans-6.2.7.jar:6.2.7]
at gt.cloudfunctionjson.CloudFunctionJsonApplication.main(CloudFunctionJsonApplication.java:14) ~[main/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.function.json.JsonMapper]: Factory method 'gsonMapper' threw exception with message: com/fasterxml/jackson/core/JsonProcessingException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:199) ~[spring-beans-6.2.7.jar:6.2.7]
... 21 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException
at gt.cloudfunctionjson.CloudFunctionJsonApplication.gsonMapper(CloudFunctionJsonApplication.java:20) ~[main/:na]
org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:393) ~[spring-context-6.2.7.jar:6.2.7]
at gt.cloudfunctionjson.CloudFunctionJsonApplication$$SpringCGLIB$$0.gsonMapper(<generated>) ~[main/:na]
... 24 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonProcessingException
... 33 common frames omitted
The problem is with JsonMapper class. It requires fasterxml jackson dependency to be present in classpath to create GsonMapper bean. Also the isJsonString, isJsonStringRepresentsCollection and isJsonStringRepresentsMap are not generic enough when either fasterxml or gson is present.
package org.springframework.cloud.function.json;
public abstract class JsonMapper {
private static final ObjectMapper mapper = new ObjectMapper().enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
versions
Spring Boot: 3.5.0
Spring Cloud: 2025.0.0
JDK: 21
Sample
https://github.com/gtiwari333/spring-cloud-function-without-jackson-xml