java.lang.NoClassDefFoundError: android.databinding.DataBinderMapperImpl when running Espresso tests - android

Data binding setup:
apply plugin: 'kotlin-kapt'
android {
dataBinding {
enabled = true
}
}
dependencies {
kapt "com.android.databinding:compiler:3.1.0"
}
The fragment class which uses data binding:
class LandingFragment : Fragment(), Injectable {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val dataBinding = LandingFragmentBinding.inflate(inflater, container, false)
return dataBinding.root
}
}
Every time the Espresso test is run for this fragment, I get the following exception:
java.lang.NoClassDefFoundError: android.databinding.DataBinderMapperImpl
at android.databinding.DataBindingUtil.<clinit>(DataBindingUtil.java:32)
at com.sc.databinding.LandingFragmentBinding.inflate(LandingFragmentBinding.java:42)
at com.sc.ui.landing.LandingFragment.onCreateView(LandingFragment.kt:32)
...

A bit late, but I resolved this issue by adding DataBinding compiler with kapt as a test dependency:
kaptAndroidTest 'androidx.databinding:databinding-compiler:3.3.2'
Or the version not from AndroidX if your project is not using Jetpack yet.

Add
kaptTest "androidx.databinding:databinding-compiler:+"
to dependencies on build.gradle files of all your modules.

I run into this very error. I did 2 things:
1. Added kaptAndroidTest 'androidx.databinding:databinding-compiler:3.5.1' in gradle
2. Used the databinding, that is to say, I create a fake bool variable and injected it for real in a view. It would seem that you cannot just use databinding for retrieving the views instead of issuing the dreaded findViewById. You have to use it at least once in your module. Once you use it you are fine for all the other classes in your module.

I have the same this issue, and fixed by adding
kapt {
generateStubs = true
}
in build.gradle app (all module if using dataBinding)
apply plugin: 'kotlin-kapt'
android {
...
dataBinding {
enabled = true
}
}
kapt {
generateStubs = true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
implementation "androidx.core:core-ktx:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
kapt "com.android.databinding:compiler:$android_plugin_version"
}
In build.gradle project
buildscript {
ext.kotlin_version = '1.3.70'
ext.android_plugin_version = '3.5.2'
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$android_plugin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

Add dataBinding = true to android { } in your build.gradle file, and everything will be fine, hope this help..
build.gradle:
android {
// skip ..
buildFeatures {
//noinspection DataBindingWithoutKapt
dataBinding = true
viewBinding true
}
// skip ..
}

Try to add the android-apt plugin as per this stackoverflow answer:
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

Related

Android Tests failing when using Hilt caused by ClassCastException

I have been writing kotlin code for android apps for quite some time, but I decided to also start writing testing code too for my apps. I have been facing some problems though with the use of Hilt. What I tried is :
import android.app.Application
open class AbstractApplication: Application()
#HiltAndroidApp
class IgmeApplication : IgmeAbstractApplication() {
#Inject
lateinit var authenticationManager: AuthenticationManager
....
}
and then in the Android Test Directory:
import dagger.hilt.android.testing.CustomTestApplication
#CustomTestApplication(AbstractApplication::class)
open class HiltTestApplication
import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
class HiltTestRunner : AndroidJUnitRunner() {
override fun newApplication(
cl: ClassLoader?,
className: String?,
context: Context?
): Application {
return super.newApplication(cl,HiltTestApp::class.java.name, context)
}
}
my Test class :
#HiltAndroidTest
class AuthenticationTest{
#get:Rule
var hiltRule = HiltAndroidRule(this)
#Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
Assert.assertEquals("com.crowdpolicy.onext.igme", appContext.packageName)
}
#Before
fun setUp() {
// Populate #Inject fields in test class
hiltRule.inject()
}
#After
fun tearDown() {
}
}
my app level gradle file :
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'com.google.firebase.firebase-perf' // Firebase Performance monitoring
id 'androidx.navigation.safeargs.kotlin'
id 'dagger.hilt.android.plugin'
id 'kotlin-parcelize'
id 'com.google.protobuf'
}
Properties localProperties = new Properties()
localProperties.load(new FileInputStream(rootProject.file('local.properties')))
Properties keyStoreProperties = new Properties()
keyStoreProperties.load(new FileInputStream(rootProject.file('keystore.properties')))
android {
buildToolsVersion "30.0.3"
ndkVersion localProperties['ndk.version']
signingConfigs {
release {
storeFile file(keyStoreProperties['key.release.path'])
keyAlias 'igme-key'
storePassword keyStoreProperties['key.release.keystorePassword']
keyPassword keyStoreProperties['key.release.keyPassword']
}
}
compileSdkVersion 30
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
}
defaultConfig {
applicationId "com.crowdpolicy.onext.igme"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "com.crowdpolicy.onext.igme.HiltTestRunner"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
debuggable false
//signingConfig signingConfigs.release
firebaseCrashlytics {
// Enable processing and uploading o FirebaseCrashlytics.getInstance()f native symbols to Crashlytics
// servers. By default, this is disabled to improve build speeds.
// This flag must be enabled to see properly-symbolicated native
// stack traces in the Crashlytics dashboard.
nativeSymbolUploadEnabled true
unstrippedNativeLibsDir "$buildDir/ndklibs/libs"
}
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
ndk.debugSymbolLevel = "FULL" // Generate native debug symbols
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/rxjava.properties'
}
kotlinOptions {
jvmTarget = '1.8'
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
android.buildFeatures.viewBinding = true
dependencies {
// Testing-only dependencies
testImplementation 'junit:junit:4.13.2'
// Core library
androidTestImplementation 'androidx.test:core:1.4.0'
// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
// Assertions
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.ext:truth:1.4.0'
// Espresso dependencies
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-web:$espresso_version"
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$espresso_version"
// The following Espresso dependency can be either "implementation"
// or "androidTestImplementation", depending on whether you want the
// dependency to appear on your APK's compile classpath or the test APK
// classpath.
androidTestImplementation "androidx.test.espresso:espresso-idling-resource:$espresso_version"
//Dagger
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
// region Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
implementation "androidx.hilt:hilt-navigation-fragment:$hilt_fragment_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version" // or : kapt 'com.google.dagger:hilt-compiler:2.37'
// Testing Navigation
androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
// region Hilt testing - for instrumentation tests
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
// Make Hilt generate code in the androidTest folder
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
// endregion
// For local unit tests
testImplementation 'com.google.dagger:hilt-android-testing:2.37'
kaptTest 'com.google.dagger:hilt-compiler:2.37'
androidTestImplementation 'com.google.dagger:hilt-android-testing:2.37'
}
}
kapt {
correctErrorTypes true
javacOptions {
// These options are normally set automatically via the Hilt Gradle plugin, but we
// set them manually to workaround a bug in the Kotlin 1.5.20: https://github.com/google/dagger/issues/2684
option("-Adagger.fastInit=ENABLED")
option("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
}
}
// https://github.com/google/protobuf-gradle-plugin
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:$protobuf_version"
// path = localProperties["protoc.dir"]
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
}
(Above I added only the dependencies used for testing )
project gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.20"
ext.google_version = '4.3.4'
ext.timberVersion = '4.7.1'
ext.event_bus = '3.2.0'
ext.gson_version = '2.8.6'
ext.retrofit2_version = '2.9.0'
ext.datastore_version = '1.0.0-rc02'
ext.rxkotlin_version = '3.0.1'
ext.rxandroid_version = '3.0.0'
ext.lifecycle_version = '2.3.1'
ext.dagger_version = '2.37'
ext.hilt_version = '2.37'
ext.hilt_fragment_version = '1.0.0'
ext.nav_version = '2.3.5'
ext.fragment_version = '1.3.6'
ext.androidXTestCoreVersion = '1.4.0'
ext.espresso_version = '3.4.0'
ext.lottie_version = '3.6.1'
ext.facebook_version = '9.0.0'
ext.protobuf_version = '3.15.8'
ext.protobuf_gradle_plugin_version = '0.8.16'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.gms:google-services:$google_version"
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
classpath 'com.google.firebase:perf-plugin:1.4.0'
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath "com.google.protobuf:protobuf-gradle-plugin:$protobuf_gradle_plugin_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
}
I followed the official documentation from dagger-hilt in this page : https://dagger.dev/hilt/testing.html, but I am still getting this error :
Caused by: java.lang.ClassCastException: com.crowdpolicy.onext.igme.HiltTestApplication cannot be cast to android.app.Application
at android.app.Instrumentation.newApplication(Instrumentation.java:997)
at android.app.Instrumentation.newApplication(Instrumentation.java:982)
at com.crowdpolicy.onext.igme.HiltTestRunner.newApplication(HiltTestRunner.kt:14)
at android.app.LoadedApk.makeApplication(LoadedApk.java:617)
and I do not know how to fix it, because I am really new to testing and it is the first time facing it !
line 14 in HIltTestRunner is :
return super.newApplication(cl,HiltTestApp::class.java.name, context)
I had the same Problem, while Testing i got a ClassCastException: HiltTestApplication cannot be cast to AbcApp (my Application class).
Solution is the #CustomTestApplication annotation, see Dagger Docs or Android Dev Docs and the use of the generated class
<interfacename>_Application.
Further on be aware that just using IgmeApplication (or AbcApp in my case) is not possible when it uses the #HiltAndroidApp annotation, see open Issue. Then you have to make an open class AbstractApplication: Application() like the questioner did. Which is then subclassed by your Application (AbcApp in my case or IgmeApplication in questioners case) and subclassed by the created class from annotation #CustomTestApplication. like:
#CustomTestApplication(AbstractApplication::class)
interface CustomTestApplicationForHilt
Note that interface is used instead of open class, but it also works with open class like the questioner did.
The created class is then CustomTestApplicationForHilt_Application which has to be used, when calling newApplication in your Testrunner class, like:
class HiltTestRunner : AndroidJUnitRunner() {
override fun newApplication(cl: ClassLoader?, className: String?, context: Context?): Application {
return super.newApplication(cl, CustomTestApplicationForHilt_Application::class.java.name, context)
}
}
Note that you can choose the name of the interface for the #CustomTestApplication annotation (here CustomTestApplicationForHilt) like you want, but the ending _Application will be added to the class name when the annotation is processed while building the app. Also note that the class will not be available before the build.

Integrate Library module built with Kotlin Coroutines dependency issue

I am building a library module that using coroutines.
My library do the following:
get config from the app module
create a fragment that implemented CoroutineScope (ContentListingFragment)
ContentListingFragment handle all it's process fetching data from the network and show them
from the app module:
We should able to get an instance from the ContentListingFragment and add it to a container
The issue: when I am building the app, I am getting the following error:
Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
class nabed.apps.nabedutilslibrary.ui.base.ContentListingFragment, unresolved supertypes: kotlinx.coroutines.CoroutineScope
below is the library module build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "kotlin-kapt"
apply plugin: 'androidx.navigation.safeargs'
android {
compileSdkVersion 28
buildToolsVersion "29.0.0"
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
androidExtensions{
experimental = true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
// Navigation
implementation "android.arch.navigation:navigation-fragment:$navigation_version"
implementation "android.arch.navigation:navigation-ui:$navigation_version"
implementation "android.arch.navigation:navigation-fragment-ktx:$navigation_version"
implementation "android.arch.navigation:navigation-ui-ktx:$navigation_version"
//Kotlin Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0-RC1"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
How to handle this without changes on the app module?
You have to change the dependencies declaration in your library's build.gradle:
//Kotlin Coroutines
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0-RC1"
api keyword will expose these dependencies to the app module
****put this code in build.gradel file in dependencies block and click on sync****
//Kotlin Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"
If you are not going to use Coroutines in the app module but would like to use it in the library, decision with api dependencies not the best one. In this way your app module will be also dependent on Coroutines.
I think, better to remove CoroutineScope implementation from ContentListingFragment and create CoroutineScope object as a ContentListingFragment member.
class ContentListingFragment : Fragment() {
private val job = Job()
private val coroutineScope = object : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.IO
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
coroutineScope.launch { ... }
}
override fun onDestroyView() {
super.onDestroy()
job.cancelChildren()
}
}
Also, LifecycleScope form lifecycle-runtime-ktx may be a the easiest solution. It will remove CoroutineScope creation boilerplate code.
class ContentListingFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch { ... }
}
}

Could not resolve com.squareup.sqldelight:runtime:1.1.3

I tried to integrate sqldelight in my Multiplatform library project for Android/iOS but I'm having several unresolved dependency errors when syncing gradle.
ERROR: Unable to resolve dependency for ':SharedCode#debug/compileClasspath': Could not resolve com.squareup.sqldelight:runtime:1.1.3.
ERROR: Unable to resolve dependency for ':SharedCode#debug/compileClasspath': Could not resolve com.squareup.sqldelight:runtime-jvm:1.1.3.
ERROR: Unable to resolve dependency for ':SharedCode#release/compileClasspath': Could not resolve com.squareup.sqldelight:runtime:1.1.3.
ERROR: Unable to resolve dependency for ':SharedCode#release/compileClasspath': Could not resolve com.squareup.sqldelight:runtime-jvm:1.1.3.**
Gradle version 5.1.1
Gradle Plugin 3.4.0
sqldelight 1.1.3
enableFeaturePreview('GRADLE_METADATA') is present in my settings.gradle
My project gradle file looks like this:
buildscript {
ext {
kotlin_version = '1.3.31'
ktor_version = '1.2.1'
ktor_json_version = '1.2.1'
kotlinx_coroutines_version = '1.2.1'
serialization_version = '0.11.0'
sqldelight_version = '1.1.3'
dokka_version = '0.9.16'
}
repositories {
google()
jcenter()
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:$dokka_version"
classpath "com.squareup.sqldelight:gradle-plugin:$sqldelight_version"
}
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
}
task clean(type: Delete) {
setDelete rootProject.buildDir
}
my SharedCode lib gradle file:
apply plugin: 'kotlinx-serialization'
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'com.squareup.sqldelight'
group = 'com.example.multiplatform'
version = '1.0'
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 15
}
buildTypes {
release {
minifyEnabled false
}
}
}
dependencies {
// Specify Kotlin/JVM stdlib dependency.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
implementation "com.squareup.sqldelight:runtime:1.1.3"
testImplementation 'junit:junit:4.12'
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'org.jetbrains.kotlin:kotlin-test'
androidTestImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'ios') {
binaries {
framework('SharedCode')
}
}
fromPreset(presets.android, 'androidLib')
}
sourceSets {
commonMain {
dependencies {
//HTTP
implementation "io.ktor:ktor-client-json:$ktor_json_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlinx_coroutines_version"
//Kotlinx serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
//sqldelight
implementation "com.squareup.sqldelight:runtime:$sqldelight_version"
}
}
androidLibMain {
dependencies {
//HTTP
implementation "io.ktor:ktor-client-json-jvm:$ktor_json_version"
implementation "io.ktor:ktor-client-serialization-jvm:$ktor_version"
//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinx_coroutines_version"
//Kotlinx serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
//sqldelight
implementation "com.squareup.sqldelight:android-driver:$sqldelight_version"
}
}
iosMain {
dependencies {
//HTTP
implementation "io.ktor:ktor-client-ios:$ktor_version"
implementation "io.ktor:ktor-client-json-native:$ktor_json_version"
implementation "io.ktor:ktor-client-serialization-native:$ktor_version"
//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$kotlinx_coroutines_version"
//kotlinx serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
//sqldelight
implementation "com.squareup.sqldelight:ios-driver:$sqldelight_version"
}
}
}
}
sqldelight {
MyApp {
packageName = 'com.example.multiplatform'
}
}
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("SharedCode", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$#\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
I was solved this problem.
First: Apply sqldelight plugin right to all project:
apply plugin: 'com.squareup.sqldelight'
sqldelight {
MyDatabase {
packageName = "ru.trendagent.database"
sourceFolders = ["sqldelight"]
}
}
In android section add:
packagingOptions {
...
exclude 'META-INF/*.kotlin_module'
}
remove all implementations of sqldelight from CommonMain section
add implementation to AndroidMain section:
implementation "com.squareup.sqldelight:android-driver:1.1.3" //DataBase
add implementation to iosMain section if need:
implementation "com.squareup.sqldelight:ios-driver:1.1.3"//DataBase
add Metadata settings to gradle to settings.gradle file:
enableFeaturePreview("GRADLE_METADATA") // IMPORTANT!
Fully clean gradle files, reset gradle wrapper and other.
Don't use kotlin 1.4.0. It unsupport sqldelight 1.1.3 version
Change gradle to latest version. You can download latest gradle manually and set it on IDE. You need gradle 5.3.1 or latest (5.1.1 unsupported)
If error will remain - change IDE to intellij idea comunity edition
This is seems to me as an error occurred due to offline gradle or invalid cache as this error is not specific to com.squareup.sqldelight. To resolve this issue follow the following steps:
File
Settings
Build, Execution, Deployment
Gradle
Uncheck offline work
and then try to invalidate the cache and restart from file menu. Hope it helps!
Change this
classpath "com.squareup.sqldelight:gradle-plugin:$sqldelight_version"
Following
classpath "com.squareup.sqldelight:runtime:$sqldelight_version"
you are passing wrong metadata to sqldelight change with my solution it will work
The Gradle part of the readme of the library indicates, that gradle plugin is needed. There's no such sqldelight library as runtime. They only have android-driver, ios-driver and sqlite-driver.
Using the DroidConKotlin app project as an example, I upgraded gradle from 5.1.1 to 5.3.1 and it resolved all the dependencies issues.
You likely are trying to use a dependency on dependant libraries or even applications and not only in commonMain module. Just change:
commonMain {
dependencies {
...
implementation "com.squareup.sqldelight:runtime:$sqldelight_version"
}
}
to
commonMain {
dependencies {
...
api "com.squareup.sqldelight:runtime:$sqldelight_version"
}
}
Also change it on dependencies section
And do the same with any other dependency uncorrecly resolved
This can happen for example if you define a class that implements an interface provided by the dependency and you use or extend that class on dependant libraries or applications (Just an example of millions that could be).
If this is your case, for further understanding, just take a look to this answer:

Kapt Annotation processors must be explicitly declared now

I'm trying to develop a Kotlin AnnotationProcessor library, and I can't figure why I get this error:
Error:Execution failed for task ':app:javaPreCompileDebug'.
> Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor. Please add them to the annotationProcessor configuration.
- compiler.jar (project :compiler)
Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior. Note that this option is deprecated and will be removed in the future.
See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.
I know that as mentionned I could use includeCompileClasspath = true and I tried it and it works fine. But as mentionned, it's deprecated, soon removed, and it is expected to be used for libraries you don't use according to android doc.
So I'm looking for a cleaner solution.
App module
Hello.kt
#HelloGenerated
class Hello(){
override fun showLog() {
Log.i(Hello::class.simpleName, "${Gahfy_Hello().getName()}")
}
}
Build.gradle
dependencies{
kapt project(":compiler")
compileOnly project(":compiler")
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}
Compiler module
HelloGenerated.kt
#Target(AnnotationTarget.CLASS)
#Retention(AnnotationRetention.SOURCE)
annotation class HelloGenerated
I also tried without Target and Retention and have same issue
HelloGenerator.kt
#SupportedAnnotationTypes("net.gahfy.HelloGenerated")
class HelloGeneratedInjectorProcessor: AbstractProcessor() {
override fun getSupportedAnnotationTypes(): MutableSet<String> {
return mutableSetOf(HelloGenerated::class.java.name)
}
override fun getSupportedSourceVersion(): SourceVersion {
return SourceVersion.latest()
}
override fun process(annotations: MutableSet<out TypeElement>, roundEnv: RoundEnvironment): Boolean {
val annotation = annotations.firstOrNull { it.toString() == "net.gahfy.HelloGenerated" } ?: return false
for (element in roundEnv.getElementsAnnotatedWith(annotation)) {
val className = element.simpleName.toString()
val `package` = processingEnv.elementUtils.getPackageOf(element).toString()
generateClass(className, `package`)
}
return true
}
private fun generateClass(className: String, `package`: String) {
val kotlinGeneratedPath = (processingEnv.options["kapt.kotlin.generated"] as String).replace("kaptKotlin", "kapt")
val kaptKotlinGenerated = File(kotlinGeneratedPath)
val source = "package $`package`\n\nclass Lachazette_$className(){fun getName():String{return \"World\"}}"
val relativePath = `package`.replace('.', File.separatorChar)
val folder = File(kaptKotlinGenerated, relativePath).apply { if(!exists()){mkdirs()} }
File(folder, "Lachazette_$className.kt").writeText(source)
}
companion object {
const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
}
}
build.gradle
apply plugin: 'java-library'
apply plugin: 'kotlin'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
resources/META-INF/services/javax.annotation.processing.Processor
net.gahfy.HelloGenerator
I'm now looking for a cleaner solution than just includeCompileClasspath = true.
Some information:
kapt works well, I'm using it with Dagger and BindingAdapter without any problem
My annotation processor is well processed when building, and the message in the log is the good one when I set includeCompileClasspath = true
Thank you very much
Not sure if this is 100% related to your problem but I had the same error after moving auto-value to kapt. I solved it by declaring the auto-value dependency as both kapt and annotationProcessor.
So in your case:
dependencies{
kapt project(":compiler")
annotationProcessor project(":compiler")
compileOnly project(":compiler")
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}

Unresolved reference async in Kotlin

I am trying to perform network operation async in Kotlin. I read it you can do async using async function. I am getting below error, can anyone guess what could be the issue ?
Unresolved reference: async
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
async() {
val forecastWeather = ForecastRequest("302015").execute()
Log.d("Test", forecastWeather.toString())
}
}
ForecastRequest.kt
class ForecastRequest(val zipcode: String) {
companion object {
private val APP_ID = "XYZ"
private val URL = "http://api.openweathermap.org/data/2.5/" +
"forecast/daily?mode=json&units=metric&cnt=7"
private val COMPLETE_URL = "$URL&APPID=$APP_ID&q="
}
fun execute(): ForecastResponse {
val forecastJsonStr = java.net.URL(COMPLETE_URL + zipcode).readText()
return Gson().fromJson(forecastJsonStr, ForecastResponse::class.java)
}
}
Top level build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.1.2-4'
repositories {
maven { url 'https://maven.google.com' }
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'https://maven.google.com' }
jcenter()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Module level build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.williams.thirddemo"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
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 "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.code.gson:gson:2.8.1'
}
async is available inside kotlinx.couroutines
Make sure that you added the dependency in your gradle file:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
Also make sure that the async is called on a coroutine scrope such as GlobalScope.
val deferredResult = GlobalScope.async {
}
I see async function is available in anko library not Kotlin library itself. https://github.com/Kotlin/anko
I resolved by adding this dependency in build.gradle compile "org.jetbrains.anko:anko-commons:0.10.1" as this is not available in Kotlin itself.
I see that async is deprecated now, library suggests to use doAsync instead.
doAsync {
val forecastWeather = ForecastRequest("302015").execute()
uiThread {
Log.d("Test", forecastWeather.toString())
}
}
Different Kotlin libraries can have different implementations of async that do different things.
If you wanted the general async-await function from the core library, make sure you have a dependency to kotlinx.coroutines
if you are using Deferred , make sure you import kotlinx.coroutines.Deferred, there is also a chance you import firebase Deferred

Categories

Resources