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.

Failure to resolve lists (generics)

See original GitHub issue

Describe the bug If you register two lists and then resolve one inside a bean, the list contains elements of the wrong type. Probably not just limited to lists, but other generics.

To Reproduce

import org.junit.Test
import org.koin.KoinContext
import org.koin.dsl.module.applicationContext
import org.koin.standalone.StandAloneContext
import kotlin.reflect.KClass

class Type1
class Type2
class Type3(val list: List<Type1>)

class ListsTest {

    @Test
    fun `list resolution failure`() {

        val type1Element = Type1()
        StandAloneContext.startKoin(
            listOf(
                applicationContext {
                    bean { listOf(type1Element) }
                },
                applicationContext {
                    bean { listOf(Type2()) }
                },
                applicationContext {
                    bean {
                        Type3(get())
                    }
                }
            )
        )

        (StandAloneContext.koinContext as KoinContext).get<Type3>().list `should equal` listOf(type1Element)
    }
}
java.lang.AssertionError: 
Expected :[Type1@77b52d12]
Actual   :[Type2@2d554825]

And if you try to use the contents of the list, you will get a class cast error.

(StandAloneContext.koinContext as KoinContext).get<Type3>().list.forEach {  }
->
java.lang.ClassCastException: Type2 cannot be cast to Type1

Expected behavior Type3 instance should have been resolved with the list of Type1 that was registered.

Koin project used and used version (please complete the following information): koin-core version 0.9.3

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:18 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
arnaudgiulianicommented, Aug 23, 2018

Ok, sorry.

I rewrite your initial test with Koin 1.0:

class Type1
class Type2
class Type3(val list: List<Type1>)


class GenericLists : KoinTest {

    @Test
    fun `list resolution failure`() {

        val type1Element = Type1()
        
        startKoin(
            listOf(
                module {
                    single { listOf(type1Element) }
                },
                module {
                    single { listOf(Type2()) }
                },
                module {
                    single {
                        Type3(get())
                    }
                }
            )
        )

        assertEquals(get<Type3>().list, listOf(type1Element))
    }
}

I got an BeanOverrideException at start. Then, it’s protected against that case.

Then to fix it, the name workaround as you mentioned:

startKoin(
            listOf(
                module {
                    single("default") { listOf(type1Element) }
                },
                module {
                    single { listOf(Type2()) }
                },
                module {
                    single {
                        Type3(get("default"))
                    }
                }
            )
        )

I can add it to the documentation/quick refs to help people on such subject.

1reaction
westonalcommented, Aug 12, 2018

The name work around in full.

class Type1
class Type2
class Type3(val list: List<Type1>)

class ListsTest {

    @Test
    fun `work around`() {

        val type1Element = Type1()
        StandAloneContext.startKoin(
                listOf(
                        applicationContext {
                            bean("List<Type1>") { listOf(type1Element) }
                        },
                        applicationContext {
                            bean { listOf(Type2()) }
                        },
                        applicationContext {
                            bean {
                                Type3(get("List<Type1>"))
                            }
                        }
                )
        )

        (StandAloneContext.koinContext as KoinContext).get<Type3>().list `should equal` listOf(type1Element)
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Error about creating array of Generic List in Java
First Code. List<Integer>[] array = (List<Integer>[]) new Object[size];. The reason why the first code fails is because casting does not ...
Read more >
Restrictions on Generics (The Java™ Tutorials > Learning ...
Because the Java compiler erases all type parameters in generic code, you cannot verify which parameterized type for a generic type is being...
Read more >
Drools user can not use a generic type for a function's ...
[ function getMinFrom (line:4): Unable to resolve type List<String> while building function. java.lang.ClassNotFoundException: Unable to ...
Read more >
[#GROOVY-8856] Trait with generic will fail compilation if it ...
Trait with generic will fail compilation if it has a static method that return the defined generic type. Status: Assignee: Priority: Resolution:.
Read more >
11. Generic Lists
// remove the object at position 55 list.remove(55); This latter version which would fail because it attempts to assign the return value (an...
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