2

I am moving my application to kotlin, and one of my files has an autowire map for the implementation of a strategy pattern. Spring falls to inject the beans when I change this file to kotlin

I have already tried lateinit, @jvmfield and others. I have been making changes and looking at the resulting decompilied java to see if its clear why there is an error. It look like its becuase the hashmap in the java version does not have show the type.

 Hashmap vs HashMap<String,Object>

Java version before change. This gathered all beans of type AudienceService and injected them into this map

@Autowired
    private Map<String, AudienceService> audienceServiceMap = new HashMap<>();

Kotlin version:

    @Autowired
    private lateinit var audienceServiceMap : HashMap<String, AudienceService>

Java decompiled version of the above kotlin code

   @Autowired
   private HashMap audienceServiceMap;

Error by spring

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'audienceContext': Unsatisfied dependency expressed through field 'audienceServiceMap'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.HashMap<java.lang.String,

1 Answers1

3

If you refer to audienceServiceMap as a Map<String, AudienceService> instead of HashMap<...>, Spring will have an easier time of finding your bean and injecting it. Generally, it is a good idea to program to an interface and not an implementation.

Without seeing where you are declaring the audienceServiceMap Bean, I'm only guessing, but I suspect Spring considers it a Map, not a (Java) HashMap because you do something like this:

@Bean
fun audienceServiceMap() = mapOf(...)

By doing that (or something like it), Spring sees audienceServiceMap as a Map, not the more specific HashMap.

Todd
  • 30,472
  • 11
  • 81
  • 89