How to resolve gradle dependency conflicts on library root dependency? - java

In my project I have two dependencies with okio as a transitive dependency conflict. In theory, gradle should solve it by choosing the highest version, but that didn't work.
I have been trying everything, since exclude until force the version from okio lib, but nothing works. Looking on external libraries path, I realized that one of the dependencies contains the okio as a path of the dependency, and I believe that this is the problem. But how can I solve this?
This is a simple gradle example with my two dependencies. Commented lines are my failed attempts to solve the problem:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.72'
}
repositories {
mavenCentral()
}
//configurations.all {
// resolutionStrategy.force('com.squareup.okio:okio:2.4.3')
//}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
// -> dependency one
implementation "com.squareup.retrofit2:retrofit:2.7.2"
// implementation ("com.squareup.retrofit2:retrofit:2.7.2"){
// exclude group: 'com.squareup.okio'
// }
// -> dependency two
implementation "com.eternitywall:java-opentimestamps:1.18"
// implementation ("com.eternitywall:java-opentimestamps:1.18") {
// exclude group: 'com.squareup.okio'
// }
// implementation "com.squareup.okio:okio:2.4.3"
// implementation "com.squareup.okio:okio"
// constraints {
// implementation("com.squareup.okio:okio:2.4.3") {
// because 'transitive version conflict'
// }
// }
}
To get the error, just have a Main.kt file with the code:
import okhttp3.OkHttpClient
fun main(args: Array<String>) {
OkHttpClient.Builder()
}
And the error obtained is:
Exception in thread "main" java.lang.NoSuchMethodError: 'boolean okio.ByteString.startsWith(okio.ByteString)'
at okio.Options.of(Options.java:64)
at okhttp3.internal.Util.<clinit>(Util.java:73)
at okhttp3.OkHttpClient.<clinit>(OkHttpClient.java:124)
at okhttp3.OkHttpClient$Builder.<init>(OkHttpClient.java:449)
at MainKt.main(Main.kt:4)
And finally, this is the library root that I mentioned from dependence with the included okio
I will be very grateful if you can help me.
Thanks in advance!!

Well, it seems that the only solution is to separate the app into modules, placing each dependency in a different module. Even though I was reluctant it was the only way I found.

Related

android build error: can't find symbol class IntDef

Using Android Studio to build the android version of a react native app. I just received
'error: cannot find symbol class IntDef'
It's used in the following code:
#IntDef(flag = true, value = { Information.BATTERY, Information.RSSI, Information.API_VERSION, Information.LED,
Information.APPLICATION_VERSION })
the bottom of my dependencies block looks like this:
implementation 'androidx.multidex:multidex:2.0.0'
implementation 'androidx.legacy:legacy-support-core-utils:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.0'
Do I need to make an import at the top of this file..or is do I need to add to the build.gradle such as implementation 'androidx.appcompat:appcompat:1.0.0'
inside the dependencies block?
I had the same issues except it was with ArrayMap, this was fixed by adding
compile "com.android.support:support-core-utils:24.2.0"
in the dependencies
You probably will have to include the following in your build.gradle file:
dependencies {
implementation 'com.android.support:support-annotations:28.0.0'
}
And the import statement in your class would be such :
import android.support.annotation.IntDef;

Model cannot be cast to ModelRealmProxyInterface

I'm trying to use Realm-java library built from source, I have used the below JARs and AARs
a jar file for the Realm Gradle plugin
an aar file for the Realm library
a jar file for the annotations
a jar file for the annotations
processor
I have added Realm-annotations-processor as below in dependencies
kapt project(':realm-annotations-processor-5.8.0')
When we do
val realm = Realm.getDefaultInstance()
try {
realm.executeTransaction { realmInstance ->
realmInstance.copyToRealm(user)// ClassCastException thrown
}
} finally {
realm.refreshAndClose()
}
The precise exception we have encountered is:
UserModel cannot be cast to io.realm.com_example_mobile_test_auth_model_UserModelRealmProxyInterface
Finally Solved this myself , I had missed registering the Realm-Transformer which is responsible for generating the RealmProxy.
We need to add below code to build.gradle of required module/app
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "io.realm:realm-transformer:5.8.0"
}
}
import io.realm.transformer.RealmTransformer
android.registerTransform(new RealmTransformer(rootProject))
I had this problem, I tried many solutions, but only this
realm.deleteAll();
could help me

Annotation processors must be explicitly declared now

Error:Execution failed for task ':laMusique2May2016:javaPreCompileRelease'.
> 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.
- auto-value-1.1.jar (com.google.auto.value:auto-value:1.1)
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 am seeing this issue, but the problem is auto-value-1.1.jar is not in my gradle files
Even i had the same problem and finally i solved my problem by adding this to app level gradle file
android{
....
defaultConfig{
....
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
}
buildTypes {
...
}
hope its solved someone's problem
You should explicitly add annotation processors in gradle. Putting the following in your gradle dependencies should fix it:
annotationProcessor 'com.google.auto.value:auto-value:1.1'
However, as others have already mentioned, you should probably figure out which of your existing dependencies was using auto-value to assert whether or not you really need it. Annotation processors ultimately slow down your build time so don't include it if it's unnecessary.
Adding annotationProcessor dependencies not work for me, instead I drop this line inside build.gradle at arbitrary places works:
android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true
Annotation processors can be declared with annotationProcessor instead of implementation/compile like we used to declare earlier.
implementation 'com.google.auto.value:auto-value:1.1'
compile 'com.google.auto.value:auto-value:1.1'
Should be replaced with
annotationProcessor 'com.google.auto.value:auto-value:1.1'
For me, this issue happened because jitpack wasn't placed as the last entry in root grade.
allprojects {
repositories {
// ... other repositories
maven { url "https://jitpack.io" }
}
}
The solution was taken from #hotchemi comment in https://github.com/permissions-dispatcher/PermissionsDispatcher/issues/535#issuecomment-432190926

How to shade a transitive dependency in Gradle?

Is there a way to shadow a particular (transitive) dependency in Gradle? My situation: I have a project that depends directly on com.amazonaws:aws-java-sdk-emr:1.10.33 and org.apache.hadoop:hadoop-aws:2.7.1, but hadoop-aws in turns depends on com.amazonaws:aws-java-sdk-emr:1.7.4 which screws the final JAR, but I need both anyway.
Is it currently possible to do something like this?
shadowJar {
relocate('com.amazonaws', 'shadowedstuff.awsjdk') {
include(dependency('com.amazonaws:aws-java-sdk:1.7.4'))
}
}
Or a not-so-dirty workaround for it?
Thanks!
NOTE: shading the aws-sdk which my projects depends on directly is not an option. This is a simplification and in the original setup some reflection is going on.
Yes, you can use the shadow plugin for Gradle to which has a very similar syntax to your example:
// Configuring Filtering for Relocation
shadowJar {
relocate('junit.textui', 'a') {
exclude 'junit.textui.TestRunner'
}
relocate('junit.framework', 'b') {
include 'junit.framework.Test*'
}
}
Apologies if I've misunderstood your situation and it is in fact more complex but it looks like the exclusion can just be provided in the dependency declaration?
dependencies {
...
compile('org.apache.hadoop:hadoop-aws:2.7.1') {
exclude group: 'com.amazonaws', module: 'aws-java-sdk'
}
...
}
You can try the resolutionStrategy (https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html) to force a particular version.
Example from a projet:
configurations {
testImplementation.extendsFrom compileOnly
all {
resolutionStrategy {
// Force jackson 2.4.4 for Spark
force 'com.fasterxml.jackson.core:jackson-core:2.4.4', 'com.fasterxml.jackson.core:jackson-databind:2.4.4', 'com.fasterxml.jackson.core:jackson-annotations:2.4.4'
force 'com.google.guava:guava:23.6-jre'
}
}
}

Gradle: Override transitive dependency by version classifier

One of the dependencies declared in my project has a transitive dependency on 'com.google.guava:guava:15.0'. But my application deployed on WAS/Weblogic doesn't work due to a CDI issue which has been fixed in 'com.google.guava:guava:15.0:cdi1.0'. (same version, but with classifier) I need to tell gradle to use this jar during build and packaging. I am trying to figure out how we can override this transitive dependency with a jar specific version classifier.
Tried the following approaches:
Added the dependency explicitly: compile 'com.google.guava:guava:15.0:cdi1.0'. But both jars got included in the resultant WAR.
Added the dependency explicitly and defined a resolution strategy:
configurations.all {
resolutionStrategy {
force 'com.google.guava:guava:15.0:cdi1.0'
}
}
Even this didn't work.
Defined a resolution strategy to check and change the version.
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
if (details.requested.group + ":" + details.requested.name == 'com.google.guava:guava') {
details.useVersion "15.0:cdi1.0"
//details.useTarget "com.google.guava:guava:15.0:cdi1.0"
}
}
}
Even this didn't work.
Need your suggestions on how this issue can be tackled.
Currently classifiers are not yet taken into account when it comes to resolutionStrategies. A workaround for you might excluding the transitive Guava library when declaring your dependencies and adding the Guava cdi1.0 version explicitly:
dependencies {
compile ("org.acme:someDependency:1.0"){
exclude group: 'com.google.guava', module: 'guava'
}
compile "com.google.guava:guava:15.0:cdi1.0"
}
I came across a more elegant approach which is simply:
compile ("com.google.guava:guava:15.0:cdi1.0") {
force = true
}
Explanation
Setting force = true for a dependency tells gradle to use the specified version in case of a version conflict
implementation( group: 'commons-codec', name: 'commons-codec'){
version{
strictly "[1.15]"
}
}
This works for me with gradle 6.6.1
The documentation link for strictly can found here https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints
Gradle 4.5.1 has the function DependencySubstitutions. Here an example to replace a dependency:
configurations.each {
c -> c.resolutionStrategy.dependencySubstitution {
all { DependencySubstitution dependency ->
if (dependency.requested.group == 'org.json') {
dependency.useTarget 'com.vaadin.external.google:android-json:0.0.20131108.vaadin1'
}
}
}
}
This will not work if the same dependency is pointed by some other jar. Sureshot way to exclude the dependency
configurations {
all*.exclude group: 'com.google.guava', module:'guava-jdk5'
}
Since force = true is deprecated, relevant solution is to use strictly(...) version, e.g.:
dependencies {
// no need to exclude transitive spring-data-relational from this dependency
implementation("org.springframework.data", "spring-data-r2dbc", "1.1.0.RC1")
implementation("org.springframework.data", "spring-data-relational").version {
strictly("2.0.0.RC1")
}
}
P.S. tested on Gradle 6.3
Try this:
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
// https://docs.gradle.org/current/userguide/resolution_rules.html
if (details.requested.group == 'com.google.guava' && details.requested.name == 'guava') {
details.useVersion '15.0:cdi1.0'
}
}
}
try this its working perfectly in my case in App level in build.gradle file
android {
configurations {
all*.exclude module: 'conceal'
all*.exclude module: 'bcprov-jdk15on'
}
}

Categories

Resources