Leandro Cuvelo
Leandro Cuvelo

Reputation: 13

Android KOIN CRASH - Error Caused by: org.koin.core.error.DefinitionOverrideException: Already existing definition for [Singleton:'java.lang.String'

After updated koin and gradle, the following error prompt

Caused by: org.koin.core.error.DefinitionOverrideException: Already existing definition for [Singleton:'java.lang.String'] at java.lang.String::_root_

I don't know where is the cause of this error.

Here my Application files:

Class MyApplication --> With 2 modules, I'm importing startKoin from: import org.koin.core.context.GlobalContext.startKoin

class MyApplication : Application(), OnMapsSdkInitializedCallback {

override fun onCreate() {
    super.onCreate()

    startKoin{
        if(BuildConfig.DEBUG){

            androidLogger(Level.DEBUG)
            Timber.plant(Timber.DebugTree())
        }
        androidContext(this@MyApplication)
        modules(applicationModule, viewModelModule)
    }

    MapsInitializer.initialize(applicationContext, Renderer.LATEST, this)
}

override fun onMapsSdkInitialized(renderer: Renderer) {
    when (renderer) {
        Renderer.LATEST -> Timber.d("The latest version of the google maps renderer is used.")
        Renderer.LEGACY -> Timber.d("The legacy version of the google maps renderer is used.")
    }
}

}

MODULE 1 -- applicationModule

// declare a module
val applicationModule = module {

single { BuildConfig.SOME_STRING1 }

single { BuildConfig.SOME_STRING2 }

single { BuildConfig.SOME_STRING3 }

single { BuildConfig.SOME_STRING4 }

single {
    Environment(get(named("SOME_STRING1")),
        get(named("SOME_STRING2")),
        get(named("SOME_STRING3")),
        get(named("SOME_STRING4")), get())
} bind GrpcConfiguration::class
//endregion

//region Channel
single {
    GrpcChannelBuilder.Companion.prepare(get(), get())
}
//endregion

//region Repository
single { SomeDataRepository(get()) } bind SomeRepository::class

//endregion

//region XXXXProvider
single { XXXXProvider(get()) }

//endregion

//region REST API
single (named("RETROFIT")){
    Retrofit.Builder().client(get())
        .baseUrl("xxxxxxxxxx")
        .addConverterFactory(GsonConverterFactory.create())
        .build()
} bind Retrofit::class


//region REST API
single {
    val l = HttpLoggingInterceptor()
    l.level = HttpLoggingInterceptor.Level.BODY

    OkHttpClient.Builder().addInterceptor(l).build()
}


single {
    get<Retrofit>(named("RETROFIT")).create(XXXXService::class.java)
} bind XXXXService::class
//endregion

//region DB
single {
    MyAppDatabase.getDatabase(get()).someDao()
} bind SomeDao::class


//endregion

//region Util
single {
    DarkModeUtil()
} bind DarkModeUtil::class
//endregion

}

Module 2 -- viewModelModule (only for viewmodels)

// declare a module
val viewModelModule: Module = module {
    viewModel { HomeViewModel(get(), get(), get()) }

}

build.gradle(:app) KOIN dependencies:

def koin_version = "3.1.6" (I've tried with 3.2.2 and 3.2.1 and got the same error)

// Koin main features for Android
implementation "io.insert-koin:koin-android:$koin_version"
// No more koin-android-viewmodel, koin-android-scope, koin-android-fragment
// Java Compatibility
implementation "io.insert-koin:koin-android-compat:$koin_version"
// Jetpack WorkManager
implementation "io.insert-koin:koin-androidx-workmanager:$koin_version"
// Navigation Graph
implementation "io.insert-koin:koin-androidx-navigation:$koin_version"

ANDROID GRADLE PLUGIN VERSION: 7.2.2 GRADLE VERSION: 7.5 KOTLIN VERSION: 1.7.10

Upvotes: 1

Views: 2324

Answers (1)

ocos
ocos

Reputation: 2244

Caused by: org.koin.core.error.DefinitionOverrideException: 
Already existing definition for [Singleton:'java.lang.String'] at java.lang.String::_root_

The error indicates that there are many String type definitions without a qualifier.

These lines below are causing the problem.

single { BuildConfig.SOME_STRING1 }
single { BuildConfig.SOME_STRING2 }

If you would like to declare a definition with the same type, you can declare them by giving a name.

single(named("SOME_STRING1")) { BuildConfig.SOME_STRING1 }
single(named("SOME_STRING2")) { BuildConfig.SOME_STRING2 }
single(named("SOME_STRING3")) { BuildConfig.SOME_STRING3 }
single(named("SOME_STRING4")) { BuildConfig.SOME_STRING4 }

You already use named definitions to create an Environment object.

single {
    Environment(get(named("SOME_STRING1")), 
                get(named("SOME_STRING2")), ...

Hope this helps.

Upvotes: 3

Related Questions