we have a code that looks somewhat like this small example:
// this is a class that is injected into a view model, it is injected once, as a parameter// it is used in multiple functions in the view model, some of them may happen one after another or even at onceclass UseCaseProvider(repository: Repository) { val useCaseMap = HashMap<Class<*>, UseCase<*, *>>() private val clearFiltersUseCase by lazy { ClearFiltersUseCase(repository) } // maaaany more usecases made in the exact same way... private fun <INPUT, OUTPUT> register(useCase: UseCase<INPUT, OUTPUT>) { useCaseMap[useCase::class.java] = useCase } internal inline <reified T: UseCase<*, *>> get(): T { if(!useCaseMap.containsKey(T::class.java)){ when(T::class) { ClearFiltersUseCase -> register(clearFiltersUseCase) // maaaany more similar lines else -> throw IllegalStateException("UseCase not registered") } } return useCaseMap[T::class.java] as T }}// example usage in the view model: // useCaseProvider.get<ClearFiltersUseCase>().invoke() // .invoke() is always suspend
and we get a class cast exception, null being cast into an UseCase class, any ideas why that might be happening?
we have a similar usecase provider in another module, but instead of using lazy & the register function it just creates and saves the instances in a hashmap once the provider is created and it does not crash, thus my suspicion that somehow lazy is at fault here?
I'm accepting any ideas (race conditions for lazy {}, thread-safety were my only ideas, but I wasn't able to reproduce the crash)