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

Subcomponent MembersInjector error in 2.51 #4352

Closed
jude-pinto opened this issue Jul 12, 2024 · 1 comment · Fixed by #4368
Closed

Subcomponent MembersInjector error in 2.51 #4352

jude-pinto opened this issue Jul 12, 2024 · 1 comment · Fixed by #4368

Comments

@jude-pinto
Copy link

Summary

  • Using dagger.android, there is an error injecting a callback that is implemented on an Activity/Fragment.
  • This only happens on 2.51 and 2.51.1
  • It does not occur on 2.50.
  • Reproducible on attached sample project
  • The DaggerApplicationComponent has a compilation error

Details

Attached is a sample project with the setup detailed in the next section below.

@ContributesAndroidInjector is leveraged, and a SubComponent is auto-generated as a result for MainActivity. The class BazPlugin needs a dependency BazCallback, which is implemented by MainActivity.

Note: BazCallback is member-injected into BazPlugin.

When building the project, there is an error:

/DaggerIssue11Jul2024/app/build/generated/source/kapt/debug/com/example/daggerissue11jul2024/DaggerApplicationComponent.java:90: error: incompatible types: BazPlugin cannot be converted to BazCallback
      BazPlugin_MembersInjector.injectIBaz(instance, instance);
                                                     ^

As of writing this issue, this error only appears when using dagger version 2.51.1 or 2.51. When reverting back to 2.50, the issue disappears.

Looking at the (generated) DaggerApplicationComponent, it singles out the 2nd parameter on line 90.

Screenshot 2024-07-11 at 3 41 36 PM

Note: It appears line 59 private final MainActivity instance; and line 89 private BazPlugin injectBazPlugin(BazPlugin instance) both refer to an instance. Back in version 2.50, this variable is arg0 instead of instance.

WaldoCallback and WaldoPlugin use constructor injection, and in that situation, this issue does not occur.

Before making any changes, any feedback on this issue would be appreciated.

Setup

Application and Component

class DaggerIssueApplication: DaggerApplication() {
    val applicationComponent = DaggerApplicationComponent.create()
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return applicationComponent
    }
}

@Component(
    modules = [AndroidInjectionModule::class, ActivityModule::class]
)
interface ApplicationComponent: AndroidInjector<DaggerIssueApplication> {

}

Modules

In addition to AndroidInjectionModule, the following Module are used

@Module
abstract class ActivityModule {
    @ContributesAndroidInjector(modules = [MainActivityModule::class])
    abstract fun provideMainActivity(): MainActivity
}

@Module
abstract class MainActivityModule {
    @Binds
    abstract fun provideBazCallback(mainActivity: MainActivity): BazCallback

    @Binds
    abstract fun provideWaldoCallback(mainActivity: MainActivity): WaldoCallback

}

Activity

class MainActivity : DaggerAppCompatActivity(), BazCallback, WaldoCallback {

    @Inject
    lateinit var pluginRegistry: PluginRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    }

    override fun onResume() {
        super.onResume()
        pluginRegistry.init()
    }

    override fun bazBaz() {

    }

    override fun waldo() {

    }
}

Supporting Classes

interface BazCallback {
    fun bazBaz()
}

class BazPlugin @Inject constructor() {
    @Inject lateinit var iBaz: BazCallback
}

interface WaldoCallback {
    fun waldo()
}

class WaldoPlugin @Inject constructor(
    private val waldoCallback: WaldoCallback
) {
}

class PluginRegistry @Inject constructor(
    private val bazPlugin: BazPlugin,
    private val waldoPlugin: WaldoPlugin
) {
    fun init() {

    }
}

Sample Project

Attached sample project. Build the app and the error will show during compilation.

DaggerIssue11Jul2024.zip

@Chang-Eric
Copy link
Member

Thanks for the detailed write up and repro! I'm not exactly sure why this changed between 2.50 and 2.51, however, usually arg0 is what happens when the parameter name is lost across compilation boundaries. I'm guessing that that has been hiding the underlying issue most of the time.

I think I've found the issue so will have a change out for that hopefully soon.

@Chang-Eric Chang-Eric self-assigned this Jul 12, 2024
copybara-service bot pushed a commit that referenced this issue Jul 22, 2024
…fields of the same name in the component.

Fixes #4352.

RELNOTES=Fixes #4352. Fix an issue where the parameter name "instance" could conflict with fields of the same name in the component.
PiperOrigin-RevId: 651913313
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants