0

This is first time I try to create a library for SpringBoot application with autoconfiguration.

I have my configuration entrypoint configured like (some parts are redacted)

@AutoConfigurationPackage
@AutoConfigureAfter({RestTemplateAutoConfiguration.class, JacksonAutoConfiguration.class})
@AutoConfigureBefore({org.zalando.logbook.autoconfigure.LogbookAutoConfiguration.class})
@ConditionalOnWebApplication
@EnableConfigurationProperties({...})
@Configuration(...)
@ConditionalOnBean(ObjectMapper.class)
public class MyAutoConfiguration {

It works in one of projects, but fails in another. In the letter case I can see in the debug log that ObjectMapper bean is created before MyAutoConfiguration, yet it fails to pass the condition check

ObjectMapper is created:

        ///line ~800
       JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper matched:
          - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) did not find any beans (OnBeanCondition)

        ////line ~2080

   ........redacted.MyAutoConfiguration:
      Did not match:
         - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) did not find any beans of type com.fasterxml.jackson.databind.ObjectMapper (OnBeanCondition)
      Matched:
         - @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)

so as a newbie I would say that conditions are met as ObjectMapper is created way before MyAutoConfiguration, yet check fails. Why is that??

PS. I thought that it might be due to version missmach (different version used for building the library and different used in the runtime) but after checking version is the same in the lib and runtime

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • 1
    They aren't met. There is no bean of type `ObjectMapper`. It would be strange if an `@ConditionalOnBean` with the same bean as `@ConditionalOnMIssingBean` would both be `true`. It fails because yours is on a top-level bean, which is processed before the internal one from jackson. – M. Deinum Jun 12 '23 at 07:29
  • Is order of debug log relevant then? `JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper` (it did match its conditions) creates ObjectMapper if there is none already, and this is what I want to make use of. – Antoniossss Jun 12 '23 at 08:15
  • No it isn't relevant. Because, as stated, yours is on a top-level class. It is used at scanning time to determine if it should use this configuration or not. So basically the `@ConditionalOnBean(ObjectMapper.class)` and `@ConditionalOnMissingBean(ObjectMapper.class~)` are consulted on the same time. Given that that is the case it is impossible for both of them being `true`. Hence as stated use it on an internal configuration **or** just put it on the `@Bean` method you want to have executed. – M. Deinum Jun 12 '23 at 08:39
  • Ok, the most important thing (for me) is that you said that debug output order is irrelevant in this case while my thinking was based on assumption that order does matter - thus my thinking that ObjectMapper is absent, then it is created and then it comes to my configuration at which point it is alread there - as this is what is in logs. Ill try to refactor my configuration and we will see what will happen. – Antoniossss Jun 12 '23 at 08:45
  • @Antoniossss is MyAutoConfiguration class registered as autoconfiguration, i.e. mentioned in spring.factories or org.springframework.boot.autoconfigure.AutoConfiguration.imports files? – Andrey B. Panfilov Jun 12 '23 at 09:24
  • yes, it is in spring.factories file. – Antoniossss Jun 12 '23 at 10:23

0 Answers0