httpclient conflict with classes now provided by Android - android-gradle-plugin

In Android Studio 3.4.1
app/build.gradle:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'org.apache.httpcomponents:httpclient:4.5.9'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
But I get error in this line;
implementation 'org.apache.httpcomponents:httpclient:4.5.9'
error:
httpclient defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for httpclient use HttpUrlConnection or okhttp instead), or repackaging the library using something like jarjar. more... (Ctrl+F1)

Check out this changelog for the Android API.
You should replace the Apache HTTP functions by HttpURLConnection or use this snipped in your build.gradle to continue using the now deprecated Apache libraries.
android {
useLibrary 'org.apache.http.legacy'
}

Related

Micronaut #SerdeImport annotation not working with Kotlin

I am working on developing an application using Micronaut framework with Kotlin language.
However, I am facing an issue where #SerdeImport annotation is not being recognized when using Micronaut with Kotlin.
I am getting the below error even after using the #SerdeImport annotation.
No serializable introspection present for type MarketSnapshot B.
Consider adding Serdeable. Serializable annotate to type MarketSnapshot B.
Alternatively if you are not in control of the project's source code,
you can use #SerdeImport(MarketSnapshot.class) to enable serialization of this type."}]}}
The same annotation works fine when using Java, however, it fails with the Kotlin program.
Below are the micronaut kotlin related dependencies that are used in build.gradle file
annotationProcessor 'io.micronaut:micronaut-inject-java'
annotationProcessor 'io.micronaut:micronaut-http-validation'
annotationProcessor 'io.micronaut.openapi:micronaut-openapi'
annotationProcessor 'io.micronaut.serde:micronaut-serde-processor'
kapt 'io.micronaut:micronaut-http-validation'
kapt 'io.micronaut:micronaut-inject-java'
implementation 'org.jetbrains.kotlin:kotlin-reflect:${kotlin}'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin}'
implementation 'io.micronaut.kotlin:micronaut-kotlin-runtime'
implementation 'io.micronaut.serde:micronaut-serde-jackson'
implementation 'io.micronaut:micronaut-management'
implementation 'io.micronaut:micronaut-http-client'
implementation 'io.micronaut:micronaut-jackson-databind'
implementation 'io.micronaut:micronaut-validation'
implementation 'jakarta.annotation:jakarta.annotation-api'
Do you have something like this in your build.gradle:
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("io.micronaut:micronaut-jackson-databind"))
.using(module("io.micronaut.serde:micronaut-serde-jackson:1.5.0"))
}
}
Also, think annotationProcessor 'io.micronaut.serde:micronaut-serde-processor' should be kapt("io.micronaut.serde:micronaut-serde-processor")
Micronaut Launch has a diff view to show the changes when adding a new feature.
For example: Micronaut Kotlin with serialization-jackson diff shows this for the changes to the build file:
dependencies {
kapt("io.micronaut:micronaut-http-validation")
+ kapt("io.micronaut.serde:micronaut-serde-processor")
implementation("io.micronaut:micronaut-http-client")
- implementation("io.micronaut:micronaut-jackson-databind")
implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
+ implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("jakarta.annotation:jakarta.annotation-api")
implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
## -57,3 +58,12 ##
annotations("com.example.*")
}
}
+
+
+
+configurations.all {
+ resolutionStrategy.dependencySubstitution {
+ substitute(module("io.micronaut:micronaut-jackson-databind"))
+ .using(module("io.micronaut.serde:micronaut-serde-jackson:1.5.0"))
+ }
+}

Data Class with Nullable Parameter in Kotlin 1.5.0 & 1.6.0 Throwing BackendException

Recently updated from Kotlin 1.4.20 to 1.5.30.
I have this class which used to compile no problem
data class Optional<M>(val value: M?)
However, after upgrading, I get the following exception
org.jetbrains.kotlin.backend.common.BackendException: Backend Internal error: Exception during IR lowering
File being compiled: .../Optional.kt
The root cause java.lang.RuntimeException was thrown at: org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:50)
at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException(CodegenUtil.kt:239)
at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException$default(CodegenUtil.kt:235)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invokeSequential(performByIrFile.kt:68)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invoke(performByIrFile.kt:55)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invoke(performByIrFile.kt:41)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:29)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:29)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:43)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.doGenerateFilesInternal(JvmIrCodegenFactory.kt:191)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.generateModule(JvmIrCodegenFactory.kt:60)
at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.compileCorrectFiles(KotlinCodegenFacade.java:35)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.generate(KotlinToJVMBytecodeCompiler.kt:321)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:113)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:56)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:169)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:52)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:92)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:412)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:112)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:358)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally$default(IncrementalCompilerRunner.kt:300)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl$rebuild(IncrementalCompilerRunner.kt:119)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:170)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:81)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:607)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:96)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1658)
I get that it's telling me that Any's toString() method doesn't have a body as I can see that from looking at the source code.
What I don't understand is how to rectify it.
EDIT
Can confirm this still happens when upgrading to kotlin version 1.6.0.
It also happens in this data class:
data class Advertisement(
var id: String,
var image: String,
var navUrl: String?
)
My build.gradle file for this module looks like so:
apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.stustirling.redacted-gradle-plugin'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "io.reactivex.rxjava2:rxkotlin:$rxKotlinVersion"
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
implementation "com.jakewharton.timber:timber:$timberVersion"
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.google.dagger:dagger:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
implementation "org.json:json:$testOrgJsonVersion"
implementation "net.sf.biweekly:biweekly:$biweeklyVersion"
testImplementation "junit:junit:$junitVersion"
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
testImplementation "org.mockito:mockito-inline:$mockitoInlineVersion"
testImplementation "org.json:json:$testOrgJsonVersion"
}
redacted {
redactAllDataClasses true
redactClassName true
}
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
My Gradle couldn't find the redacted-gradle-plugin but both of your classes compiles with this minimalistic build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
val kotlinVersion = "1.6.0"
kotlin("jvm") version kotlinVersion
}
repositories {
mavenCentral()
}
Also, while looking at the redacted page at https://github.com/StuStirling/redacted-compiler-plugin, it says "Kotlin compiler plugins are not a stable API", so at least do a "./gradlew clean"!

Androidx Robolectric configuration

I'm trying to use Robolectric in my project but I have hit a snag and don't know how to resolve it. I think its a configuration issue since I am unable to get even the most basic tests to run.
Here are my dependencies;
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.navigation:navigation-fragment:2.2.2'
implementation 'androidx.navigation:navigation-ui:2.2.2'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
implementation 'androidx.preference:preference:1.1.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.guava:guava:28.2-android'
androidTestImplementation 'androidx.test:core-ktx:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation ('org.robolectric:robolectric:4.3.1') {
exclude group: "org.apache.maven"
}
If I don't include the exclude group directive I get a bunch of library conflicts.
Here is my first test;
#RunWith(RobolectricTestRunner::class)
class RoboTest {
#Test
fun test() {
Thread.sleep(9000)
}
}
When I try to run it i get the following stacktrace;
java.lang.NoClassDefFoundError: org.robolectric.util.inject.-$$Lambda$Injector$ZRemX9RoMk8gdKE-8yBtX0b79nc
at org.robolectric.util.inject.Injector.getProvider(Injector.java:310)
at org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:213)
at org.robolectric.util.inject.Injector.getInstance(Injector.java:197)
at org.robolectric.util.inject.Injector.getInstance(Injector.java:191)
at org.robolectric.internal.SandboxTestRunner.<init>(SandboxTestRunner.java:73)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:101)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:96)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at androidx.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:63)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at androidx.test.internal.runner.AndroidRunnerBuilder.runnerForClass(AndroidRunnerBuilder.java:153)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at androidx.test.internal.runner.TestLoader.doCreateRunner(TestLoader.java:73)
at androidx.test.internal.runner.TestLoader.getRunnersFor(TestLoader.java:104)
at androidx.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:793)
at androidx.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:547)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:390)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)
I've tried googling it but I don't think i've been able to find the same case I've been running into, I have also tried Invalidating cache/restarting which hasn't done anything.
Any help?
I moved the file to /test (unit test) from /androidtest and updated the dependencies accordingly;
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.navigation:navigation-fragment:2.2.2'
implementation 'androidx.navigation:navigation-ui:2.2.2'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
implementation 'androidx.preference:preference:1.1.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.guava:guava:28.2-android'
/*androidTestImplementation 'androidx.test:core-ktx:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'*/
testImplementation 'junit:junit:4.12'
testImplementation ('org.robolectric:robolectric:4.3.1')
The solution was alluded to in the docs.
Oh boy, do I have egg on my face.

Android - Glide ".placeholder" method not recognized

I have a recycler view. In the adapter's onBindViewHolder method I have the following code to load an image:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Log.i("TEST-APP", "Binding View Holder")
Glide.with(context)
.load(items[position])
.placeholder(R.drawable.animated_loading_icon)
.into(holder.imageView)
}
However, Android Studio is saying that "placeholder" is an unresolved reference. This is confusing because the documentation indicates that this is the correct way to load a placeholder.
What am I doing wrong?
Also, here are my imports in the RecyclerViewAdapter class
package com.example.myname.recylerviewtest
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.*
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.recyclerview_item_column.view.*
Lastly, here are my dependencies in build.gradle:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
api 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
As shown in the Glide documentation:
Most options in Glide can be applied using the RequestOptions class
and the apply() method.
Use request options to apply (among others):
Placeholders
Transformations
Caching Strategies
Component specific options, like encode quality, or decode Bitmap configurations.
So, if you want to use placeholder, you have two options.
One of them is to do it this way:
Glide.with(context)
.load(items[position])
.apply(RequestOptions()
.placeholder(R.drawable.animated_loading_icon)
)
.into(holder.imageView)
And the other option would be to implement the Generated API

Unity 5.6 custom gradle configuration with Fabric

I would like to configure Fabric dependencies for Unity Android build using gradle. I'm now exporting the project and using Android Studio to get rid of the errors and then prepare a custom working "mainTemplate.gradle" so I can build directly from Unity 5.6.
Here are the configured dependencies as Unity suggested:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// other dependencies
compile project(':answers')
compile project(':beta')
compile project(':crashlytics')
compile project(':crashlytics-wrapper')
compile project(':fabric')
compile project(':fabric-init')
}
Each of the Fabric folders is treated as a library that has its own gradle config.
Here are the errors I'm getting (due to a file used in same namespace of two "libraries"):
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lio/fabric/unity/crashlytics/android/BuildConfig;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lio/fabric/unity/android/BuildConfig;
I tried adding the following but it did not work:
android {
dexOptions {
preDexLibraries = false
}
I also tried without success:
task androidReleaseJar(type: Jar, dependsOn: assembleRelease) {
from "$buildDir/intermediates/classes/release/"
exclude '**/BuildConfig.class'
}
Here is how I solved this issue:
By default each fabric folder is treated as a project however only "fabric" needs to be handled as one since it contains a "res" folder and an "AndroidManifest.xml" file with required meta data values. So I just kept only "fabric" as a project and changed the other dependencies to be handled as simple *.jar files.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile fileTree(dir: 'fabric-init/libs', include: ['*.jar'])
compile fileTree(dir: 'crashlytics-wrapper/libs', include: ['*.jar'])
compile fileTree(dir: 'crashlytics/libs', include: ['*.jar'])
compile fileTree(dir: 'beta/libs', include: ['*.jar'])
compile fileTree(dir: 'answers/libs', include: ['*.jar'])
compile project(':fabric')
}
and in Settings.gradle I keep only one project reference:
//include 'answers'
//include 'beta'
//include 'crashlytics'
//include 'crashlytics-wrapper'
include 'fabric'
//include 'fabric-init'
You can disable generation of BuildConfig java class by changes in only one file (without Fabric modifications). Place this at end of Plugins/Android/mainTemplate.gradle for all your problem projects:
['crashlytics', 'crashlytics-wrapper', 'fabric', 'fabric-init'].each { name ->
project(":$name").tasks.whenTaskAdded { task ->
if (task.name == 'generateDebugBuildConfig' || task.name == 'generateReleaseBuildConfig' ) {
task.enabled = false
}
}
}