Using lambda in custom BindingAdapter using Android Databinding and Kotlin - kotlin

I'm trying to have a custom binding with a lambda handler for Android Databinding using Kotlin. It's working well as long as my ViewModel handler is explicitly returning Void. But if it returns Kotlin Unit instead, I get an error: cannot generate view binders java.lang.StackOverflowError.
Everything seems to be hooked-up correctly as all the other custom bindings works (convertBooleanToViewVisibility, toTestString and even customOnClick as long as I'm calling onClickVoid [see example below]).
The issue is when I'm trying to invoke a lambda returning Unit in my app:customOnClick instead of returning Void. In the example below, it's to invoke mainViewModel.onClick() instead of mainViewModel.onClickVoid(). There must be a way of making it work as the android:onClick is able to make to call to the Unit version. But if I'm using the same syntax for customOnClick calling onClick, I'm getting this error:
:app:kaptGenerateStubsDebugKotlin
Using kotlin incremental compilation
:app:kaptDebugKotlin
e: error: cannot generate view binders java.lang.StackOverflowError
e:
e: at android.databinding.tool.writer.Scope.access$getCurrentScope$cp(LayoutBinderWriter.kt:49)
e: at android.databinding.tool.writer.Scope$Companion.getCurrentScope(LayoutBinderWriter.kt:58)
e: at android.databinding.tool.writer.LayoutBinderWriterKt.scopedName(LayoutBinderWriter.kt:196)
e: at android.databinding.tool.expr.Expr.toCode(Expr.java:776)
e: at android.databinding.tool.writer.LayoutBinderWriterKt$callbackLocalName$2.invoke(LayoutBinderWriter.kt:203)
e: at android.databinding.tool.writer.LayoutBinderWriterKt$callbackLocalName$2.invoke(LayoutBinderWriter.kt)
e: at android.databinding.tool.ext.LazyExt.getValue(ext.kt:27)
e: at android.databinding.tool.writer.LayoutBinderWriterKt.getCallbackLocalName(LayoutBinderWriter.kt)
e: at android.databinding.tool.writer.LayoutBinderWriterKt.scopedName(LayoutBinderWriter.kt:197)
e: java.lang.IllegalStateException: failed to analyze: java.lang.RuntimeException: failure, see logs for details.
cannot generate view binders java.lang.StackOverflowError
at android.databinding.tool.writer.Scope.access$getCurrentScope$cp(LayoutBinderWriter.kt:49)
at android.databinding.tool.writer.Scope$Companion.getCurrentScope(LayoutBinderWriter.kt:58)
at android.databinding.tool.writer.LayoutBinderWriterKt.scopedName(LayoutBinderWriter.kt:196)
at android.databinding.tool.expr.Expr.toCode(Expr.java:776)
at android.databinding.tool.writer.LayoutBinderWriterKt$callbackLocalName$2.invoke(LayoutBinderWriter.kt:203)
at android.databinding.tool.writer.LayoutBinderWriterKt$callbackLocalName$2.invoke(LayoutBinderWriter.kt)
at android.databinding.tool.ext.LazyExt.getValue(ext.kt:27)
at android.databinding.tool.writer.LayoutBinderWriterKt.getCallbackLocalName(LayoutBinderWriter.kt)
at android.databinding.tool.writer.LayoutBinderWriterKt.scopedName(LayoutBinderWriter.kt:197)
.............................. (TRUNCATED) ...................................
at android.databinding.tool.expr.Expr.toCode(Expr.java:776)
at android.databinding.tool.writer.LayoutBinderWriterKt$callbackLocalName$2.invoke(LayoutBinderWriter.kt:203)
at android.databinding.tool.writer.LayoutBinderWriterKt$callbackLocalName$2.invoke(LayoutBinderWriter.kt)
at android.databinding.tool.ext.LazyExt.getValue(ext.kt:27)
at android.databinding.tool.writer.LayoutBinderWriterKt.getCallbackLocalName(LayoutBinderWriter.kt)
at android.databinding.tool.writer.LayoutBinderWriterKt.scopedName(LayoutBinderWriter.kt:197)
at org.jetbrains.kotlin.analyzer.AnalysisResult.throwIfError(AnalysisResult.kt:57)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:144)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:167)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:55)
at org.jetbrains.kotlin.cli.common.CLICompiler.exec(CLICompiler.java:182)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.execCompiler(CompileServiceImpl.kt:397)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.access$execCompiler(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:365)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$2$$special$$inlined$withValidClientOrSessionProxy$lambda$1.invoke(CompileServiceImpl.kt:798)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$2$$special$$inlined$withValidClientOrSessionProxy$lambda$1.invoke(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:825)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.access$checkedCompile(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$2.invoke(CompileServiceImpl.kt:797)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$2.invoke(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.ifAlive(CompileServiceImpl.kt:1004)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.ifAlive$default(CompileServiceImpl.kt:865)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:791)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.access$doCompile(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1.invoke(CompileServiceImpl.kt:364)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1.invoke(CompileServiceImpl.kt:99)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.ifAlive(CompileServiceImpl.kt:1004)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.ifAlive$default(CompileServiceImpl.kt:865)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:336)
at sun.reflect.GeneratedMethodAccessor86.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
... 39 more
FAILED
Any idea how to make it work with Unit so I do not need to change my ViewModel to explicitly return Void? for all my handlers?
Sample project
Project build.gradle
buildscript {
ext.kotlin_version = '1.1.3-2'
ext.plugin_version = '2.3.3'
repositories {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$plugin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Module (app) build.gradle
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
}
}
apply plugin: 'com.android.application'
apply plugin: "kotlin-android"
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 24
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.example.kotlindatabinding"
minSdkVersion 24
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
dataBinding {
enabled = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
kapt "com.android.databinding:compiler:$plugin_version"
}
kapt {
generateStubs = true
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
binding.setMainViewModel(MainViewModel())
}
}
MainViewModel.kt
class MainViewModel {
val myName: String
get() {
return "Hello world!"
}
fun onClick(){
Log.i("ME", "Logging...")
}
fun onClickVoid(): Void? {
onClick()
return null as Void?
}
}
Bindings.kt
object Bindings{
#BindingConversion
#JvmStatic fun convertBooleanToViewVisibility(isVisible: Boolean): Int {
// Working
return if (isVisible) View.VISIBLE else View.GONE
}
#BindingAdapter("customOnClick")
#JvmStatic fun setOnItemClicked(textView: TextView, consumer: (String) -> Any?) {
// Working
consumer("test")
}
#JvmStatic fun toTestString(input: Any) : String {
return "Test"
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="com.example.kotlindatabinding.Bindings"/>
<variable
name="mainViewModel"
type="com.example.kotlindatabinding.MainViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.kotlindatabinding.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{Bindings.toTestString(mainViewModel.myName)}"
android:visibility="#{mainViewModel.myName != null}"
android:clickable="true"
android:onClick="#{() -> mainViewModel.onClick()}"
app:customOnClick="#{(someInput) -> mainViewModel.onClickVoid()}" />
</LinearLayout>
</layout>

Well, very late response I suppose, but others might had the same issue:
As far as I see this is on a false assumption: databinding uses Java and doesn't know about Kotlin in general.
In order to set a listener via databinding you have to use a Java interface with a method. Kotlin lambdas are not like Java interfaces with a simple method since they contain functions, meaning they always return something (if not specified then Unit).
So to achieve setting a listener define a simple Java interface as a parameter in the binding adapter

Move this code outside the default config block. Put it inside
android {
dataBinding {
enabled = true
}
}

Related

Unable to instantiate application on path: DexPathList

I saw this problem and I don't know what caused it or how to solve it
Simply the application crashed with no reason and nothing weird!
this is the problem from logcat:
2021-12-01 00:08:56.105 27747-27747/com.example.halanchallenge E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.halanchallenge, PID: 27747
java.lang.RuntimeException: Unable to instantiate application com.example.halanchallenge.presentation.utils.manager.BaseApplication: java.lang.ClassNotFoundException: Didn't find class "com.example.halanchallenge.presentation.utils.manager.BaseApplication" on path: DexPathList[[zip file "/data/app/~~AByZTfuIHlZhPYmwpjE5lQ==/com.example.halanchallenge-B7fNXgixWuCCl0Iug8pygQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~AByZTfuIHlZhPYmwpjE5lQ==/com.example.halanchallenge-B7fNXgixWuCCl0Iug8pygQ==/lib/arm64, /system/lib64, /system/system_ext/lib64]]
at android.app.LoadedApk.makeApplication(LoadedApk.java:1332)
at android.app.ActivityThread.handleMakeApplication(ActivityThread.java:7469)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7440)
at android.app.ActivityThread.access$1400(ActivityThread.java:301)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2148)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.halanchallenge.presentation.utils.manager.BaseApplication" on path: DexPathList[[zip file "/data/app/~~AByZTfuIHlZhPYmwpjE5lQ==/com.example.halanchallenge-B7fNXgixWuCCl0Iug8pygQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~AByZTfuIHlZhPYmwpjE5lQ==/com.example.halanchallenge-B7fNXgixWuCCl0Iug8pygQ==/lib/arm64, /system/lib64, /system/system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.AppComponentFactory.instantiateApplication(AppComponentFactory.java:76)
at androidx.core.app.CoreComponentFactory.instantiateApplication(CoreComponentFactory.java:52)
at android.app.Instrumentation.newApplication(Instrumentation.java:1158)
at android.app.LoadedApk.makeApplication(LoadedApk.java:1324)
at android.app.ActivityThread.handleMakeApplication(ActivityThread.java:7469) 
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7440) 
at android.app.ActivityThread.access$1400(ActivityThread.java:301) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2148) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:246) 
at android.app.ActivityThread.main(ActivityThread.java:8506) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) 
Suppressed: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/example/halanchallenge/presentation/utils/manager/Hilt_BaseApplication;
at java.lang.VMClassLoader.findLoadedClass(Native Method)
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
... 15 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.halanchallenge.presentation.utils.manager.Hilt_BaseApplication" on path: DexPathList[[zip file "/data/app/~~AByZTfuIHlZhPYmwpjE5lQ==/com.example.halanchallenge-B7fNXgixWuCCl0Iug8pygQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~AByZTfuIHlZhPYmwpjE5lQ==/com.example.halanchallenge-B7fNXgixWuCCl0Iug8pygQ==/lib/arm64, /system/lib64, /system/system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 18 more
And this is my gradle file :
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'androidx.navigation.safeargs.kotlin'
id 'dagger.hilt.android.plugin'
id 'kotlin-parcelize'
}
android {
compileSdkVersion 31
defaultConfig {
applicationId "com.example.halanchallenge"
minSdkVersion 21
targetSdkVersion 31
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "BASE_URL", BASE_URL)
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
dataBinding {
enabled = true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.android.support:multidex:1.0.3'
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.38.1"
annotationProcessor "com.google.dagger:hilt-android-compiler:2.38.1"
annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0'
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
//GIF
implementation "com.airbnb.android:lottie:3.7.0"
// Glide
implementation 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation "com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2"
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1'
// Coroutine Lifecycle Scopes
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
//GSON
implementation 'com.google.code.gson:gson:2.8.7'
// Navigation Components
implementation "androidx.navigation:navigation-fragment-ktx:2.3.5"
implementation "androidx.navigation:navigation-ui-ktx:2.3.5"
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.github.martinstamenkovski:ARIndicatorView:2.0.0'
implementation 'com.amitshekhar.android:android-networking:1.0.2'
}
Gradle :
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.31"
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'
}
}
allprojects {
repositories {
google()
maven { url 'https://jitpack.io' }
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
And this is the BaseApplication
#HiltAndroidApp
class BaseApplication : Application()
What is the problem and how to solve it ?
I've been thinking about a solution for a long time and haven't found a solution!
I hope you can help me solve it.
Thank you :))
Try to update you Hilt dependencies to v2.40.2
// :app build.gradle START
plugins {
id 'kotlin-android'
id 'kotlin-kapt'
//...
id 'dagger.hilt.android.plugin'
}
android {
//...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
//...
}
dependencies {
//...
// hilt
implementation "com.google.dagger:hilt-android:2.40.2"
kapt "com.google.dagger:hilt-compiler:2.40.2"
}
// Allow references to generated code
kapt {
correctErrorTypes = true
}
// :app build.gradle END
// project build.gradle START
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.31"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.3"
//...
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.40.2'
}
}
// ...
// project build.gradle END

kotlin:Internal Error occurred while analyzing this expression

I am using navigation safeargs for passing arguments from one Fragment to another .
However , after I rebuild the project ,I could not parse the augument I had sent .I got an error below:
Internal Error occurred while analyzing this expression:
org.jetbrains.kotlin.descriptors.InvalidModuleException: Accessing invalid module descriptor <production sources for module FavDishKT.app> is a module[ModuleDescriptorImpl#10578057]
at org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl.assertValid(ModuleDescriptorImpl.kt:62)
at org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl.getPackage(ModuleDescriptorImpl.kt:84)
at org.jetbrains.kotlin.resolve.lazy.FileScopeFactory.createScopesForFile(FileScopeFactory.kt:62)
at org.jetbrains.kotlin.resolve.lazy.FileScopeFactory.createScopesForFile$default(FileScopeFactory.kt:61)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl$cache$1.invoke(FileScopeProvider.kt:48)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl$cache$1.invoke(FileScopeProvider.kt:46)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl.getFileScopes(FileScopeProvider.kt:53)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProvider$DefaultImpls.getFileResolutionScope(FileScopeProvider.kt:30)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl.getFileResolutionScope(FileScopeProvider.kt:40)
at org.jetbrains.kotlin.resolve.lazy.DeclarationScopeProviderImpl.getResolutionScopeForDeclaration(DeclarationScopeProviderImpl.java:60)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor.getOuterScope(LazyClassDescriptor.java:353)
at org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport$scopeForClassHeaderResolution$1.invoke(ClassResolutionScopesSupport.kt:44)
at org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport$scopeForClassHeaderResolution$1.invoke(ClassResolutionScopesSupport.kt:43)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageM...
My configures:
build.gradle(project:FavDishKT)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.0"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
def nav_version = "2.3.2"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
**build.gradle(Module:FavDishKT.app)**
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
// For more details visit https://developer.android.com/guide/navigation/navigation-pass-data#Safe-args
id 'androidx.navigation.safeargs.kotlin'
id 'kotlin-parcelize'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.gearsrun.favdishkt"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation("androidx.recyclerview:recyclerview:1.2.1")
// For control over item selection of both touch and mouse driven selection
implementation("androidx.recyclerview:recyclerview-selection:1.1.0")
implementation 'com.airbnb.android:lottie:3.4.1'
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.makeramen:roundedimageview:2.3.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation("com.squareup.okhttp3:okhttp:4.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
implementation 'com.google.code.gson:gson:2.8.7'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
}
dependencies {
//room
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
}
My idea is to pass the dish item from the homepage to another details page ,as follow ,Therefor ,I will need to pass a entity which names :FavDish
FavDish entity:
#Parcelize
#Entity(tableName = "fav_dishes_table")
data class FavDish(
#PrimaryKey(autoGenerate = true) val id:Int = 0,
#ColumnInfo val image:String,
#ColumnInfo(name = "image_source")val imageSource:String,
#ColumnInfo val title:String,
#ColumnInfo val type:String,
#ColumnInfo val category:String,
#ColumnInfo val ingredients:String,
#ColumnInfo(name = "cooking_time") val cookingTime:String,
#ColumnInfo(name = "instructions") val directionToCook:String,
#ColumnInfo(name = "favorite_dish") var favoriteDish:Boolean = false,
):Parcelable
And then , I have modified the navigation.xml ,from the AllDishes page to the DishDetailsFragment , and pass the entity reference as aguments :
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mobile_navigation"
app:startDestination="#+id/navigation_all_dishes">
<fragment
android:id="#+id/navigation_all_dishes"
android:name="com.gearsrun.favdishkt.view.fragments.AllDishesFragment"
android:label="Home"
tools:layout="#layout/fragment_all_dishes" >
<action
android:id="#+id/action_navigation_all_dishes_to_dishDetailsFragment"
app:destination="#id/dishDetailsFragment" />
</fragment>
<fragment
android:id="#+id/navigation_favorite_dishes"
android:name="com.gearsrun.favdishkt.view.fragments.FavoriteFragment"
android:label="Favorite"
tools:layout="#layout/fragment_favorite_dishes" >
<action
android:id="#+id/action_navigation_favorite_dishes_to_dishDetailsFragment"
app:destination="#id/dishDetailsFragment" />
</fragment>
<fragment
android:id="#+id/navigation_random_dish"
android:name="com.gearsrun.favdishkt.view.fragments.RandomFragment"
android:label="Random"
tools:layout="#layout/fragment_random_dish" />
<fragment
android:id="#+id/dishDetailsFragment"
android:name="com.gearsrun.favdishkt.view.fragments.DishDetailsFragment"
android:label="fragment_dish_details"
tools:layout="#layout/fragment_dish_details" >
<argument
android:name="dishDetails"
app:argType="com.gearsrun.favdishkt.model.entities.FavDish"/>
</fragment>
</navigation>
From my AllDishsFragment (home page ) ,I use findNavController,and navigate to the detailsDishFragment ,and pass the entity to it :
class AllDishesFragment : Fragment(){
private var _binding: FragmentAllDishesBinding? = null
private val binding get() = _binding!!
private val mFavDishViewModel :FavDishViewModel by viewModels{
FavDishViewModelFactory((requireActivity().application as FavDishApplication).repository)
}
private lateinit var mFavDishAdapter: FavDishAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentAllDishesBinding.inflate(inflater, container, false)
val root: View = binding.root
binding.imgAddHome.setOnClickListener {
val intent = Intent(context,AddUpdateActivity::class.java)
startActivity(intent)
}
binding.rvHome.layoutManager = GridLayoutManager(requireActivity(),2)
mFavDishAdapter = FavDishAdapter(this)
binding.rvHome.adapter = mFavDishAdapter
mFavDishViewModel.allDishesList.observe(viewLifecycleOwner){dishes->
dishes.let{
if(it.isNotEmpty()){
binding.rvHome.visibility=View.VISIBLE
binding.txtNotice.visibility=View.GONE
mFavDishAdapter.getAllDishes(it)
}else{
binding.rvHome.visibility =View.GONE
binding.txtNotice.visibility=View.VISIBLE
}
}
}
return root
}
fun dishDetails(favDish: FavDish){
if(requireActivity() is MainActivity){
(activity as MainActivity?)!!.hideBottomNavigationView()
}
findNavController().navigate(AllDishesFragmentDirections.actionNavigationAllDishesToDishDetailsFragment(favDish))
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
And the DetailDishFragment ,where it should receive the args and parse it occured the error :
class DishDetailsFragment : Fragment() {
private val mFavDishViewModel : FavDishViewModel by viewModels{
FavDishViewModelFactory((requireActivity().application as FavDishApplication).repository)
}
private var mBinding : FragmentDishDetailsBinding? =null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mBinding = FragmentDishDetailsBinding.inflate(inflater,container,false)
return mBinding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val args:DishDetailsFragmentArgs by navArgs()
args.let{
try {
Glide.with(requireActivity())
.load(it.dishDetails.image)
}catch(e: IOException){
}
}
}
}
And the problem description :
Internal Error occurred while analyzing this expression:
org.jetbrains.kotlin.descriptors.InvalidModuleException: Accessing invalid module descriptor <production sources for module FavDishKT.app> is a module[ModuleDescriptorImpl#10578057]
at org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl.assertValid(ModuleDescriptorImpl.kt:62)
at org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl.getPackage(ModuleDescriptorImpl.kt:84)
at org.jetbrains.kotlin.resolve.lazy.FileScopeFactory.createScopesForFile(FileScopeFactory.kt:62)
at org.jetbrains.kotlin.resolve.lazy.FileScopeFactory.createScopesForFile$default(FileScopeFactory.kt:61)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl$cache$1.invoke(FileScopeProvider.kt:48)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl$cache$1.invoke(FileScopeProvider.kt:46)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl.getFileScopes(FileScopeProvider.kt:53)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProvider$DefaultImpls.getFileResolutionScope(FileScopeProvider.kt:30)
at org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl.getFileResolutionScope(FileScopeProvider.kt:40)
at org.jetbrains.kotlin.resolve.lazy.DeclarationScopeProviderImpl.getResolutionScopeForDeclaration(DeclarationScopeProviderImpl.java:60)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor.getOuterScope(LazyClassDescriptor.java:353)
at org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport$scopeForClassHeaderResolution$1.invoke(ClassResolutionScopesSupport.kt:44)
at org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport$scopeForClassHeaderResolution$1.invoke(ClassResolutionScopesSupport.kt:43)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageM...
Could anyone helps ?Thank you so much in advance !!
install and uninstall kotlin plugin.it Worked for me
For My case, I had the same issue but it was only happening in one particular project, The rest were okay so I tried upgrading the build Gradle plugin of the specific project to 7.3.0 and It worked. You can try to see if this helps
Invalid Cache Restart with both vcs and system cache option selected can resolved this issue. It worked for me.
Update: These warnings frequently coming in Dolphin Version of Android Studio(stable) causing faliure of auto suggestion and layout rendering. If you want to get rid of them for stable version you can use Chipmunk version or try canary channels of dolphin.
Updating ktx implementation and syncing gradle worked for me!

SQLDelight: Unresolved reference AndroidSqliteDriver in Kotlin Multiplatform App

I try add sqldelight to my Kotlin Multiplatform App, but AndroidSqliteDriver unresolved reference. I dont understand why.
I clear cache and regenerate all, but it dont work too.
AndroidSqliteDriver:
package com.rompos.deactivator
import com.squareup.sqldelight.android.AndroidSqliteDriver
import android.content.Context
lateinit var appContext: Context
actual fun createDB() : Server {
val driver = AndroidSqliteDriver(Server.Schema, appContext, "Server.db")
return Server(driver)
}
build.gradle(common):
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
id("com.squareup.sqldelight")
}
kotlin {
//select iOS target platform depending on the Xcode environment variables
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios") {
binaries {
framework {
baseName = "SharedCode"
}
}
}
jvm("android")
// Common Main
sourceSets["commonMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
implementation("io.ktor:ktor-client-core:1.3.2")
implementation("com.squareup.sqldelight:runtime:1.4.0")
}
// Android Main
sourceSets["androidMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib")
implementation("com.squareup.sqldelight:android-driver:1.4.0") {
exclude(group = "com.squareup.sqldelight", module = "runtime-jdk")
}
}
// iOS Main
sourceSets["iosMain"].dependencies {
implementation("com.squareup.sqldelight:native-driver:1.4.0")
}
}
build.gradle(android):
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlinx-serialization'
apply plugin: 'com.squareup.sqldelight'
android {
compileSdkVersion 30
buildToolsVersion "30.0.1"
defaultConfig {
applicationId "com.rompos.deactivator"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-
optimize.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/*.kotlin_module'
}
buildFeatures {
dataBinding true
}
}
dependencies {
implementation project(':SharedCode')
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "androidx.core:core-ktx:1.3.1"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "com.google.android.material:material:1.2.0"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation
"androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.navigation:navigation-fragment-ktx:2.3.0"
implementation "androidx.navigation:navigation-ui-ktx:2.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-
android:1.3.7"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-
runtime:0.20.0"
implementation "io.ktor:ktor-client-android:1.3.2"
implementation "com.squareup.sqldelight:android-
driver:$sqldelight_version"
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-
core:3.2.0'
}
build.gradle(project):
buildscript {
ext {
ext.kotlin_version = '1.3.72'
sqldelight_version = "1.4.0"
}
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-
plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-
serialization:$kotlin_version"
classpath "com.squareup.sqldelight:gradle-
plugin:$sqldelight_version"
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
I use:
gradle: 6.1.1
gradle plugin: 4.0.1
kotlin: 1.3.72
upd: Add code
you only have a jvm target jvm("android") and not an android target. you need an android library or application target to use the android library.
EDIT: To add an android target:
//build.gradle(common)
plugins {
...
// assuming your building a library. use application otherwise
id("com.android.library")
id("kotlin-android")
}
...
android {
// fill in your library or app info here
}
kotlin {
android { // creates androidMain/Test source sets
// ex: publishLibraryVariants("release", "debug")
}
ios() { ... }
val commonMain by getting { ... }
val androidMain by getting { ... }
...
}
Make sure you're using at least Android Studio 4.1.
You should only need to include the SQLDelight plugin in your common build.gradle.
build.gradle
...
apply plugin: "com.squareup.sqldelight" in the common build.gradle
...
sourceSets {
commonMain.dependencies {
...
// SQL Delight
implementation "com.squareup.sqldelight:runtime:${Versions.sqlDelight}"
implementation "com.squareup.sqldelight:coroutines-extensions:${Versions.sqlDelight}"
}
androidMain.dependencies {
...
// SQL Delight
implementation "com.squareup.sqldelight:android-driver:${Versions.sqlDelight}"
implementation "com.squareup.sqldelight:coroutines-extensions-jvm:${Versions.sqlDelight}"
}
iOSMain.dependencies {
...
// SQL Delight
implementation "com.squareup.sqldelight:ios-driver:${Versions.sqlDelight}"
}
}

Can't import dependencies for Kotlin multi platform common

I am trying out Kotlin multi-platform and trying to setup all my dependencies for it. Starting with commonMain
I am trying to add Koin and Ktor dependencies to the common portion but I cant seem to be able to use any of them.
This is my Gradle script
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.3.61'
}
repositories {
google()
jcenter()
mavenCentral()
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
defaultConfig {
applicationId 'org.jetbrains.kotlin.mpp_app_android'
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName '1.0'
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'org.koin:koin-android:2.0.1'
implementation 'org.koin:koin-androidx-viewmodel:2.0.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
}
kotlin {
android("android")
// This is for iPhone emulator
// Switch here to iosArm64 (or iosArm32) to build library for iPhone device
iosX64("ios") {
binaries {
framework()
}
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib-common')
implementation 'org.koin:koin-ktor:2.0.1'
implementation 'org.koin:koin-core:2.0.1'
// HTTP
implementation "io.ktor:ktor-client-core:1.2.6"
implementation "io.ktor:ktor-client-json:1.2.6"
implementation "io.ktor:ktor-client-serialization:1.2.6"
// Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.2.1"
}
}
commonTest {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
}
androidMain {
dependencies {
implementation kotlin('stdlib')
}
}
androidTest {
dependencies {
implementation kotlin('test')
implementation kotlin('test-junit')
}
}
iosMain {
}
iosTest {
}
}
}
// This task attaches native framework built from ios module to Xcode project
// (see iosApp directory). Don't run this task directly,
// Xcode runs this task itself during its build process.
// Before opening the project from iosApp directory in Xcode,
// make sure all Gradle infrastructure exists (gradle.wrapper, gradlew).
task copyFramework {
def buildType = project.findProperty('kotlin.build.type') ?: 'DEBUG'
def target = project.findProperty('kotlin.target') ?: 'ios'
dependsOn kotlin.targets."$target".binaries.getFramework(buildType).linkTask
doLast {
def srcFile = kotlin.targets."$target".binaries.getFramework(buildType).outputFile
def targetDir = getProperty('configuration.build.dir')
copy {
from srcFile.parent
into targetDir
include 'app.framework/**'
include 'app.framework.dSYM'
}
}
}
In the Sample.kt file that was generated when I created the project I tried to setup Koin in the main method
fun main() {
startKoin {
// declare modules
modules(myModule)
}
println(hello())
}
but startKoin cannot be resolved.
I cleaned/rebuilt the project, did a gradle sync and still cant import koin or any other dependency so what am I missing
Koin is not multiplatform capable. We have [multiplatform forks][1], but would need to chat about which to use and what version. We're still discussing multiplatform strategy.
Ktor's dependencies are more complex than that. See below. I removed your other dependencies for clarity, but you should leave them obviously :)
sourceSets {
commonMain {
dependencies {
implementation "io.ktor:ktor-client-core:1.2.6"
implementation "io.ktor:ktor-client-json:1.2.6"
implementation "io.ktor:ktor-client-serialization:1.2.6"
}
}
androidMain {
dependencies {
implementation "io.ktor:ktor-client-core-jvm:1.2.6"
implementation "io.ktor:ktor-client-json-jvm:1.2.6"
implementation "io.ktor:ktor-client-serialization-jvm:1.2.6"
}
}
iosMain {
dependencies {
implementation "io.ktor:ktor-client-ios:1.2.6"
implementation "io.ktor:ktor-client-core-native:1.2.6"
implementation "io.ktor:ktor-client-json-native:1.2.6"
implementation "io.ktor:ktor-client-serialization-native:1.2.6"
}
}
}
[1]: https://github.com/kpgalligan/koin/tree/kpg/khan

Kotlin annotation processor: can't make it work

My gradle build:
buildscript {
ext.kotlin_version = '1.1.4-3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: "kotlin-kapt"
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
kapt {
processors = "libs.orm.codeGenerators.ModelProcessor" //PROCESSOR
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "com.google.auto.service:auto-service:1.0-rc3"
}
The processor is not in separate module.
Processor does nothing, in #process it simply throws, to see if it's working.
#AutoService(Processor::class)
#SupportedSourceVersion(SourceVersion.RELEASE_8)
class ModelProcessor : AbstractProcessor() {
override fun process(annotations: MutableSet<out TypeElement>?, roundEnv: RoundEnvironment): Boolean {
throw(Throwable("foo"))
return true
}
override fun getSupportedAnnotationTypes() : MutableSet<String> {
return mutableSetOf<String>("*")
}
}
But absolutely nothing happens. No error, nothing.
How can I make it work?
In my practices, AutoService just ignore kotlin classes. You have to use a java class instead, or write your own META-INF:
main/resources/META-INF/services/javax.annotation.processing.Processor
and contains: your.package.ModelProcessor