question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Inject of bean from a different context

See original GitHub issue

Describe the bug We tried to switch to Koin from Dagger but we run into some strange behavior with the context feature. If we create an object which loads a module inside a class which gets injected we are getting a scope error.

I’ve created a super small project like the following:

The MainActivity starting Koin and injecting an class Sdk

class MainActivity : AppCompatActivity() {
    val sdk: Sdk by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startKoin(listOf(AppModule().module))
        sdk.toString()
    }
}

The AppModule only has one bean for the Sdk

class AppModule {

    val module = applicationContext {
        bean { Sdk() }
    }
}

The Sdk class itself contains a Backend object (no injection, only the object)

class Sdk {
    val backend: Backend = Backend()

    init {
        backend.toString()
    }
}

The Backend-class itself is a KoinComponent loading a BackendModule and injecting a class called Bar. Consider this a library with its oun context.

class Backend : KoinComponent {

    val bar: Bar by inject()

    init {
        loadKoinModules(listOf(BackendModule().module))
        bar.toString()
    }
}

BackendModule includes a bean inside a context with name “backend”

class BackendModule {

    val module = applicationContext {
        context("backend") {
            bean { Bar() }
        }
    }
}

The line in the Sdk class where the Backend gets created is crashing with the following stacktrace:

06-22 12:09:13.092 30620-30620/com.example.mirko.testcontextrelease W/System.err: org.koin.error.ContextVisibilityException: Can't resolve 'com.example.mirko.testcontextrelease.Bar' for definition Bean[class=com.example.mirko.testcontextrelease.Sdk].
    	Class 'com.example.mirko.testcontextrelease.Bar' is not visible from context scope Scope[ROOT]
        at org.koin.KoinContext.getVisibleBeanDefinition(KoinContext.kt:111)
        at org.koin.KoinContext.resolveInstance(KoinContext.kt:77)
        at com.example.mirko.testcontextrelease.Backend$$special$$inlined$inject$1.invoke(KoinComponent.kt:114)
        at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131)
        at com.example.mirko.testcontextrelease.Backend.getBar(Unknown Source:7)
        at com.example.mirko.testcontextrelease.Backend.<init>(Backend.kt:14)
        at com.example.mirko.testcontextrelease.Sdk.<init>(Sdk.kt:4)
        at com.example.mirko.testcontextrelease.AppModule$module$1$1.invoke(AppModule.kt:8)
        at com.example.mirko.testcontextrelease.AppModule$module$1$1.invoke(AppModule.kt:5)
06-22 12:09:13.093 30620-30620/com.example.mirko.testcontextrelease W/System.err:     at org.koin.core.instance.InstanceFactory.createInstance(InstanceFactory.kt:58)
        at org.koin.core.instance.InstanceFactory.retrieveInstance(InstanceFactory.kt:26)
        at org.koin.KoinContext$resolveInstance$$inlined$synchronized$lambda$1.invoke(KoinContext.kt:85)
        at org.koin.KoinContext$resolveInstance$$inlined$synchronized$lambda$1.invoke(KoinContext.kt:23)
        at org.koin.ResolutionStack.resolve(ResolutionStack.kt:23)
        at org.koin.KoinContext.resolveInstance(KoinContext.kt:80)
        at com.example.mirko.testcontextrelease.MainActivity$$special$$inlined$inject$1.invoke(AndroidExt.kt:179)
        at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131)
        at com.example.mirko.testcontextrelease.MainActivity.getSdk(Unknown Source:7)
06-22 12:09:13.094 30620-30620/com.example.mirko.testcontextrelease W/System.err:     at com.example.mirko.testcontextrelease.MainActivity.onCreate(MainActivity.kt:19)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
06-22 12:09:13.095 30620-30620/com.example.mirko.testcontextrelease W/System.err:     at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
06-22 12:09:13.096 30620-30620/com.example.mirko.testcontextrelease D/AndroidRuntime: Shutting down VM
06-22 12:09:13.098 30620-30620/com.example.mirko.testcontextrelease E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mirko.testcontextrelease, PID: 30620
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mirko.testcontextrelease/com.example.mirko.testcontextrelease.MainActivity}: org.koin.error.BeanInstanceCreationException: Can't create bean Bean[class=com.example.mirko.testcontextrelease.Sdk] due to error :
    	org.koin.error.ContextVisibilityException: Can't resolve 'com.example.mirko.testcontextrelease.Bar' for definition Bean[class=com.example.mirko.testcontextrelease.Sdk].
    	Class 'com.example.mirko.testcontextrelease.Bar' is not visible from context scope Scope[ROOT]
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: org.koin.error.BeanInstanceCreationException: Can't create bean Bean[class=com.example.mirko.testcontextrelease.Sdk] due to error :
    	org.koin.error.ContextVisibilityException: **Can't resolve 'com.example.mirko.testcontextrelease.Bar' for definition Bean[class=com.example.mirko.testcontextrelease.Sdk].
    	Class 'com.example.mirko.testcontextrelease.Bar' is not visible from context scope Scope[ROOT]**
        at org.koin.core.instance.InstanceFactory.createInstance(InstanceFactory.kt:63)
        at org.koin.core.instance.InstanceFactory.retrieveInstance(InstanceFactory.kt:26)
        at org.koin.KoinContext$resolveInstance$$inlined$synchronized$lambda$1.invoke(KoinContext.kt:85)
        at org.koin.KoinContext$resolveInstance$$inlined$synchronized$lambda$1.invoke(KoinContext.kt:23)
        at org.koin.ResolutionStack.resolve(ResolutionStack.kt:23)
        at org.koin.KoinContext.resolveInstance(KoinContext.kt:80)
        at com.example.mirko.testcontextrelease.MainActivity$$special$$inlined$inject$1.invoke(AndroidExt.kt:179)
        at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131)
        at com.example.mirko.testcontextrelease.MainActivity.getSdk(Unknown Source:7)
        at com.example.mirko.testcontextrelease.MainActivity.onCreate(MainActivity.kt:19)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        	... 9 more

It can not resolve Bar in Backend of scope ROOT - but this seems to be wrong.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
arnaudgiulianicommented, Jun 23, 2018

Things should be clearer in 1.0.0. Wait the next weeks for new documentation 👍

1reaction
Bodo1981commented, Jun 23, 2018

Maybe i can help you: You have two modules: AppModule and BackendModule

The Sdk class is provided in the AppModule with root context. The Backend class which you want to inject in the Sdk class needs a Bar class which is provided in the BackendModule in another context “backend”.

So the usage of context is the following:

root: knows only classes/interfaces/… from the root context backend: knows classes from the root context AND the backend context

So your problem is that the Sdk class from the root context needs injects a Backend class which needs a class (Bar) from the backend context. And this is not visible in the root context. See the error message:

Can't resolve 'com.example.mirko.testcontextrelease.Bar' for definition Bean[class=com.example.mirko.testcontextrelease.Sdk].
    	Class 'com.example.mirko.testcontextrelease.Bar' is not visible from context scope Scope[ROOT]
Read more comments on GitHub >

github_iconTop Results From Across the Web

Inject a bean from another application context? - Stack Overflow
Bean is just an object in JVM. You certainly cannot use an object from one JVM in another JVM straightforward. But you can...
Read more >
Choosing from multiple beans in the context - Manning
I define two beans of type Parrot using the @Bean annotation in the configuration class. Don't forget we still have to add @ComponentScan...
Read more >
Injecting Spring Beans into Unmanaged Objects - Baeldung
In a Spring application, injecting one bean into another bean is very common. However, sometimes it's desirable to inject a bean into an ......
Read more >
Introduction to Contexts and Dependency Injection - Quarkus
It creates and destroys the instances of beans, associates the instances with a designated context, and injects them into other beans.
Read more >
Contexts and Dependency Injection (CDI) for the Java EE ...
In order to use the beans you create, you inject them into yet another bean that can then be used by an application,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found