[issue] Dagger doesn't compile or doesn't give a right error message when ViewModelFactory is implemened on Kotlin rather than on Java
Gelassen opened this issue · 4 comments
The issue
I observe some bizarre behavior of dagger
when some of my dagger annotated classes are implemented on kotlin rather than on java. In my current case it is just hide a correct error message, in others cases it just doesn't compile, but everything compiles well when return back kotlin code to java code.
I can not give a code sample to reproduce (just prepared a WIP commit and new branch to reproduce the issue, see DI package), but it happens at least three times to report this. Unfortunately I did invest enough investigation time to speed up a development, so I just keep some classes on a Java.
@Module
public abstract class TestViewModelModule {
@Binds
public abstract ViewModelFactory bindViewModelFactory(ViewModelFactory viewModelFactory);
@Binds
@IntoMap
@ViewModelKey(MachinesViewModel.class)
abstract MachinesViewModel bindMachinesViewModel(MachinesViewModel vm);
}
Hi @Gelassen , I tried the branch and it did build. I tried converting TestViewModelModule
to Kotlin and it builds as well. Could you share the error message you saw and how I can reproduce this?
Hello @kuanyingchou,
After I have switched from my dev branch
to issue branch
I get an exception:
java.nio.file.FileAlreadyExistsException: /home/gelassen/Workspace/Personal/manufacturer/manufactory-knowledge-management-system/mobile/app/build/generated/ksp/debug/java/io/github/gelassen/manufactory_knowledge_management/di/ViewModelFactory_Factory.java
at java.base/sun.nio.fs.UnixCopyFile.copy(UnixCopyFile.java:573)
at java.base/sun.nio.fs.UnixFileSystemProvider.copy(UnixFileSystemProvider.java:257)
at java.base/java.nio.file.Files.copy(Files.java:1305)
at com.google.devtools.ksp.IncrementalUtilKt.copyWithTimestamp(IncrementalUtil.kt:80)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.updateFromShadow(KotlinSymbolProcessingExtension.kt:473)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:371)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:77)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:256)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:247)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:115)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:247)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.repeatAnalysisIfNeeded(KotlinToJVMBytecodeCompiler.kt:181)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.repeatAnalysisIfNeeded(KotlinToJVMBytecodeCompiler.kt:181)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:87)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:43)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:165)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:50)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:104)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:48)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1523)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Running $ ./gradlew clean
and compile again solves this issue. Ksp stage is alpha, so it might be related to a lack of full support of ksp
in dagger
. Please consider to automate run of ./gradlew clean
when developer switch from one branch to another. From dagger perspective it might be not possible, but they same company develop both dagger and its dev environment, so it just requires organizational and product decisions, therefore it is possible. [feature-request]
I am able to compile this code because TestViewModelModule
is added in AppComponent
and it is written on pure Java. If you replace TestViewModelModule
by ViewModelModule
which is written on kotlin, you will get on compilation:
[ksp] /home/gelassen/Workspace/Personal/manufacturer/manufactory-knowledge-management-system/mobile/app/src/main/java/io/github/gelassen/manufactory_knowledge_management/di/AppComponent.kt:17: [Dagger/MissingBinding] @javax.inject.Named("MACHINE_VIEW_MODEL_FACTORY") io.github.gelassen.manufactory_knowledge_management.di.ViewModelFactory cannot be provided without an @Provides-annotated method.
@javax.inject.Named("MACHINE_VIEW_MODEL_FACTORY") io.github.gelassen.manufactory_knowledge_management.di.ViewModelFactory is injected at
[io.github.gelassen.manufactory_knowledge_management.di.InjectorModule_ProvideMachineFragmentInjector.MachineFragmentSubcomponent] io.github.gelassen.manufactory_knowledge_management.ui.MachineFragment.viewModelFactory
io.github.gelassen.manufactory_knowledge_management.ui.MachineFragment is injected at
[io.github.gelassen.manufactory_knowledge_management.di.InjectorModule_ProvideMachineFragmentInjector.MachineFragmentSubcomponent] dagger.android.AndroidInjector.inject(T) [io.github.gelassen.manufactory_knowledge_management.di.AppComponent → io.github.gelassen.manufactory_knowledge_management.di.InjectorModule_ProvideMachineFragmentInjector.MachineFragmentSubcomponent]
Steps to reproduce are:
$ git clone https://github.com/Gelassen/manufactory-knowledge-management-system.git
$ git checkout issue/google-issue-ticket
- Go to
AppComponent
and replaceTestViewModelModule
byViewModelModule
- Compile
Expected behavior:
App is successfully compiled and launched (screen with camera asking you for permissions)
Observed behavior:
App doesn't compile successfully with an error message described above
Hi, @Gelassen , thanks for the steps. I was able to reproduce the error. I think it's because the return type of bindViewModelFactory
in ViewModelModule.kt
is different from TestViewModelModule.java
. After making them the same I was able to compile:
- abstract fun bindViewModelFactory(viewModelFactory: ViewModelFactory): ViewModelProvider.Factory
+ abstract fun bindViewModelFactory(viewModelFactory: ViewModelFactory): ViewModelFactory
As for the branch changing issue I think it's outside Dagger's scope. Maybe a Git hook is better for the job.
@kuanyingchou , thank you for invested time into this and spotted issue in my codebase. Glad to hear the issue is on my side.
Also thank you for Git hook recommendation https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks, so far I don't have necessity to use it and be familiar with it.
The issue can be closed, but if you have a chance to be familiar with this codebase and have deep expertise in dagger could you please to take a look on this issue?
This is out of the scope, but it is just about asking a favor.