Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using kotlin Collection then @Autowire Collection<SomeInterface> does not work correctly [SPR-15940] #20494

Open
spring-projects-issues opened this issue Sep 8, 2017 · 1 comment
Assignees
Labels
for: team-attention in: core in: kotlin
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Sep 8, 2017

Mario Zagar opened SPR-15940 and commented

Using:

  • spring-framework 5.0.0.RC3 (also tested wth 1.5.6.RELEASE, problem also present)
  • kotlin-stdlib 1.1.4-3

Following test fails when autowiring kotlin Collection @Autowired lateinit var beans : Collection.

When using java.util.Collection autowiring works as expected.

Not really sure if this is kotlin issue or spring issue.

Here's the test:

package spring.autowire.test

import org.assertj.core.api.Assertions
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringRunner

interface FirstInterface
interface SecondInterface
interface ThirdInterface

class Bean1 : FirstInterface, SecondInterface, ThirdInterface
class Bean2 : FirstInterface, SecondInterface, ThirdInterface
class Bean3 : FirstInterface, SecondInterface, ThirdInterface
class Bean4 : FirstInterface, SecondInterface, ThirdInterface

@Configuration
open class TestSpringConfig {
    @Bean open fun bean1() : Bean1 = Bean1()
    @Bean open fun bean2() : FirstInterface = Bean2()
    @Bean open fun bean3() : SecondInterface = Bean3();
    @Bean open fun bean4() : ThirdInterface = Bean4();
}

@RunWith(SpringRunner::class)
@ContextConfiguration(classes = arrayOf(TestSpringConfig::class))
class KotlinAutowireTest {
    @Autowired
    lateinit var beans : Collection<SecondInterface> // test passes if I use java.util.Collection<SecondInterface>

    @Test
    fun test() {
        Assertions.assertThat(beans)
                .extracting{it.javaClass.name}
                .containsOnly(
                        "spring.autowire.test.Bean1",
                        "spring.autowire.test.Bean2",
                        "spring.autowire.test.Bean3",
                        "spring.autowire.test.Bean4"
                )
    }
}

Test output:

java.lang.AssertionError: 
Expecting:
  <["spring.autowire.test.Bean1", "spring.autowire.test.Bean3"]>
to contain only:
  <["spring.autowire.test.Bean1",
    "spring.autowire.test.Bean2",
    "spring.autowire.test.Bean3",
    "spring.autowire.test.Bean4"]>
but could not find the following elements:
  <["spring.autowire.test.Bean2", "spring.autowire.test.Bean4"]>

Affects: 5.0 RC3

1 votes, 3 watchers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Sep 11, 2017

Sébastien Deleuze commented

I had a look to this repro test and found that MutableCollection is working as expected while indeed Collection (the Kotlin one) ones returns 2 beans. After comparing both cases, I found that the difference of behavior comes from GenericTypeAwareAutowireCandidateResolver#checkGenericTypeMatch which could behave differently because of Kotlin declaration-site variance:

  • Collection is declared as interface Collection<out E>
  • MutableCollection is declared as interface MutableCollection<E>

Juergen Hoeller I have added a unit test in this branch to compare Kotlin MutableCollection and Collection, do you have any thoughts about this behavior being related to our generics comparison algorythm having to be tuned to support Kotlin declaration-site variance or if the issue could be on Kotlin side?

@spring-projects-issues spring-projects-issues added type: bug status: waiting-for-triage in: core and removed type: bug labels Jan 11, 2019
@sdeleuze sdeleuze self-assigned this Jun 6, 2019
@sdeleuze sdeleuze added this to the 5.2 M3 milestone Jun 6, 2019
@sdeleuze sdeleuze removed the status: waiting-for-triage label Jun 6, 2019
@sdeleuze sdeleuze removed this from the 5.2 M3 milestone Jun 10, 2019
@sdeleuze sdeleuze added this to the 5.2 RC1 milestone Jun 10, 2019
@sdeleuze sdeleuze added the for: team-attention label Jun 17, 2019
@sdeleuze sdeleuze removed this from the 5.2 RC1 milestone Jul 8, 2019
@sdeleuze sdeleuze added this to the 4.3.25 milestone Jul 8, 2019
@sdeleuze sdeleuze removed this from the 4.3.25 milestone Jul 8, 2019
@sdeleuze sdeleuze added this to the 5.2 RC2 milestone Jul 8, 2019
@sdeleuze sdeleuze removed this from the 5.2 RC2 milestone Sep 2, 2019
@sdeleuze sdeleuze added this to the 5.2 GA milestone Sep 2, 2019
@sdeleuze sdeleuze removed this from the 5.2 GA milestone Sep 9, 2019
@sdeleuze sdeleuze added this to the 5.3 M1 milestone Sep 9, 2019
@jhoeller jhoeller removed this from the 5.3 M1 milestone Feb 24, 2020
@jhoeller jhoeller added this to the 5.3 M2 milestone Feb 24, 2020
@jhoeller jhoeller removed this from the 5.3 M2 milestone Aug 7, 2020
@jhoeller jhoeller added this to the 5.3 RC1 milestone Aug 7, 2020
@sdeleuze sdeleuze removed this from the 5.3 RC1 milestone Aug 26, 2020
@sdeleuze sdeleuze added this to the 5.x Backlog milestone Aug 26, 2020
@sdeleuze sdeleuze added the in: kotlin label Jan 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: team-attention in: core in: kotlin
Projects
None yet
Development

No branches or pull requests

3 participants