I'm as upgrading from Spring Boot 1.5.21 to 2.2.5.
I need to use MonetaryModule
to deserialize rest calls, and depending on Spring's ObjectMapper
.
I have defined such a bean for this module in a some @Configuration
class (MonetaryModule
is extending Module
):
@Bean
public MonetaryModule monetaryModule() {
return new MonetaryModule();
}
I can see in /beans
endpoint it was created. However, it is not actually loaded to ObjectMapper
. After a lot of debugging and digging around Spring's code, I came to the conclusion that there is something wrong in JacksonAutoConfiguration
. it has an inner static class called JacksonObjectMapperBuilderConfiguration
and in it there's a bean
that creates the Jackson2ObjectMapperBuilder
. in the creation process, there's a call to customize()
that eventually gets to this code:
private void configureModules(Jackson2ObjectMapperBuilder builder) {
Collection<Module> moduleBeans = getBeans(this.applicationContext, Module.class);
builder.modulesToInstall(moduleBeans.toArray(new Module[0]));
}
This code seems responsible for loading the modules into ObjectMapper
, Problem is that this Jackson2ObjectMapperBuilder
is not actually created. It appears in /beans
endpoint but de facto when I breakpoint there I'm not hitting the breakpoint. This explains why the module is not loaded into ObjectMapper
.
Question is, why is this code not being called? and why /bean
indicates the bean does exist?
Edit - Adding conditions evaluation report:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
AopAutoConfiguration matched:
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration matched:
- @ConditionalOnClass found required class 'org.aspectj.weaver.Advice' (OnClassCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration.CglibAutoProxyConfiguration matched:
- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)
ConfigServiceBootstrapConfiguration#configServicePropertySource matched:
- @ConditionalOnProperty (spring.cloud.config.enabled) matched (OnPropertyCondition)
- @ConditionalOnMissingBean (types: org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; SearchStrategy: all) did not find any beans (OnBeanCondition)
ConfigServiceBootstrapConfiguration.RetryConfiguration matched:
- @ConditionalOnClass found required classes 'org.springframework.retry.annotation.Retryable', 'org.aspectj.lang.annotation.Aspect', 'org.springframework.boot.autoconfigure.aop.AopAutoConfiguration' (OnClassCondition)
- @ConditionalOnProperty (spring.cloud.config.fail-fast) matched (OnPropertyCondition)
ConfigServiceBootstrapConfiguration.RetryConfiguration#configServerRetryInterceptor matched:
- @ConditionalOnMissingBean (names: configServerRetryInterceptor; SearchStrategy: all) did not find any beans (OnBeanCondition)
ConfigurationPropertiesRebinderAutoConfiguration matched:
- @ConditionalOnBean (types: org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; SearchStrategy: all) found bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor' (OnBeanCondition)
ConfigurationPropertiesRebinderAutoConfiguration#configurationPropertiesBeans matched:
- @ConditionalOnMissingBean (types: org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; SearchStrategy: current) did not find any beans (OnBeanCondition)
ConfigurationPropertiesRebinderAutoConfiguration#configurationPropertiesRebinder matched:
- @ConditionalOnMissingBean (types: org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; SearchStrategy: current) did not find any beans (OnBeanCondition)
EncryptionBootstrapConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.security.crypto.encrypt.TextEncryptor' (OnClassCondition)
PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer matched:
- @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) did not find any beans (OnBeanCondition)
Negative matches:
-----------------
AopAutoConfiguration.AspectJAutoProxyingConfiguration.JdkDynamicAutoProxyConfiguration:
Did not match:
- @ConditionalOnProperty (spring.aop.proxy-target-class=false) did not find property 'proxy-target-class' (OnPropertyCondition)
AopAutoConfiguration.ClassProxyingConfiguration:
Did not match:
- @ConditionalOnMissingClass found unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
DiscoveryClientConfigServiceBootstrapConfiguration:
Did not match:
- @ConditionalOnProperty (spring.cloud.config.discovery.enabled) did not find property 'spring.cloud.config.discovery.enabled' (OnPropertyCondition)
EncryptionBootstrapConfiguration.RsaEncryptionConfiguration:
Did not match:
- Keystore nor key found in Environment (EncryptionBootstrapConfiguration.KeyCondition)
Matched:
- @ConditionalOnClass found required class 'org.springframework.security.rsa.crypto.RsaSecretEncryptor' (OnClassCondition)
EncryptionBootstrapConfiguration.VanillaEncryptionConfiguration:
Did not match:
- @ConditionalOnMissingClass found unwanted class 'org.springframework.security.rsa.crypto.RsaSecretEncryptor' (OnClassCondition)
Exclusions:
-----------
None
Unconditional classes:
----------------------
None
Also, attached is the output of /conditions
& /beans
endpoints output (Too large to paste into the post itself)
endpoints output
If you use Spring Boot, the jackson-databind dependency comes in the spring-boot-starter-json module (which also is included in other spring boot started moduled, like spring-boot-starter-web ).
Jackson (https://github.com/FasterXML/jackson) extension module used to enhance performance using bytecode generation to replace use of Reflection for field access and method calls.
Overview. When using JSON format, Spring Boot will use an ObjectMapper instance to serialize responses and deserialize requests. In this tutorial, we'll take a look at the most common ways to configure the serialization and deserialization options. To learn more about Jackson, be sure to check out our Jackson tutorial.
Spring Framework and Spring Boot provide builtin support for Jackson based XML serialization/deserialization. As soon as you include the jackson-dataformat-xml dependency to your project, it is automatically used instead of JAXB2.
Your condition evaluation report shows the following:
"JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper": {
"notMatched": [
{
"condition": "OnBeanCondition",
"message": "@ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found beans of type 'com.fasterxml.jackson.databind.ObjectMapper' jacksonBuilder"
}
],
"matched": []
},
This means that the Spring Boot auto-configuration condition is backing off since your application already provides an opinion on the matter: there is already an ObjectMapper
bean named jacksonBuilder
; it is provided by the application or some configuration class in a library you're using.
In this case, this comes from a configuration class, as pointed out by the beans endpoint:
"jacksonBuilder": {
"aliases": [],
"scope": "singleton",
"type": "com.fasterxml.jackson.databind.ObjectMapper",
"resource": "class path resource [com/behalf/core/authorization_domain/config/AuthorizationDomainConfiguration.class]",
"dependencies": []
},
You should here get in touch with the maintainers of this AuthorizationDomainConfiguration
and let them know that they should avoid overriding the opinion of the application on JSON (de)serialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With