Exclude Package From Gradle Dependency - java

I'm experiencing an issue where multiple versions of the same class are showing up in my classpath. The class in question is javax.ws.rs.core.UriBuilder. The version I want to use is brought in by javax.ws.rs:javax.ws.rs-api:2.0.1. However, we also use the Jira rest client library which has a dependency on the older version of jersey (com.sun.jersey:jersey-core) which has included the java.ws packages bundled in it's jar.
Here is an example snippet from the build file:
dependencies {
compile 'com.atlassian.jira:jira-rest-java-client-core:2.0.0-m31'
compile 'javax.ws.rs:javax.ws.rs-api:2.0.1'
compile 'org.glassfish.jersey.core:jersey-client:2.17'
}
I can't remove com.sun.jersey:jersey-core as it uses different package name from the new version and would cause class def not found exceptions in the Jira client.
As far as I can tell, my options at this point are:
Revert to using Jersey 1.x and it's implementation of jsr311
Somehow have gradle exclude the javax.ws package from the old jersey client.
I'd like to keep using the newer version of jersey so #2 would be my ideal solution but I'm not sure if it's even possible. Does anyone know how to go about this? If that's not possible, I'm open to other suggestions.

You can exclude an transitive dependency module like this:
compile ('org.glassfish.jersey.core:jersey-client:2.17') {
exclude group: 'javax.ws.rs'
exclude module: 'javax.ws.rs-api'
}
ref: 50.4.7 here

I found out that com.sun.jersey:jersey-core:1.19 doesn't bundle the javax.ws.rs class files and instead lists them as a compile-time dependency. Adding this snippet to my build.gradle fixed the issue.
configurations.all {
resolutionStrategy {
// For a version that doesn't package javax.ws
force 'com.sun.jersey:jersey-core:1.19'
}
}

exclude the group and module as below.
Ex :
implementation('org.apache.httpcomponents:httpclient:4.5.13') {
exclude group: 'commons-codec', module: 'commons-codec'
}

Related

Same interface in 2 different dependency issue

I have conflict problem with dependencies.
My project has two dependencies like this:
dependencies {
provided group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
compile files('path/to/ABC.jar')
}
ABC.jar has its own dependency to javax.servlet:servlet-api:
dependencies {
provided group: 'javax.servlet', name: 'servlet-api', version: '2.5'
}
Here is the problem I am dealing with; I need to use ServletContext interface which is provided by both servlet-api libraries and the compiler uses wrong one.
Gradle auto-resolves version conflicts as described here.
But in my case it doesn't help, because it only works when a dependency has two different versions. In this case; although it's a newer version issue, the name has changed from javax.servlet:servlet-api to javax.servlet:javax.servlet-api. So gradle doesn't auto-resolve this conflict, because it doesn't seem to be a version issue.
The thing I tried was using excluding transitive dependency as described here.
compile files('path/to/ABC.jar') {
exclude group: 'javax.servlet'
}
But it didn't work, it seems exclude doesn't work on local 'jar' files.
Now, I don't know what else to do.
How can I exclude a dependency of a dependency which is added as a local file?
(If the first question doesn't have any answer yet) How can I say to the compiler to use the correct ServletContext interface?
compile files('path/to/ABC.jar') is a file dependency, a file dependency does not have any dependency information, so it does not introduce transitive dependencies. If this ABC.jar is a "fat" jar that has the dependency-classes included in the JAR, it is not suited for usage in something like Gradle, Maven or Ant/Ivy that is supposed to handle the dependencies. You would have to use a proper "thin" version of the dependency with the dependencies properly declared, or you need to "repackage" that JAR in your build script to exclude the dependency classes you don't want to pull in. No dependency management can do this for you.
You can execute gradlew dependencyInsight --configuration runtime --dependency javax.servlet:servlet-api or gradlew dependencies --configuration runtime to find out where the dependency really comes from.
Actually your example should not even compile if I see it correctly, because it should most probably be
compile files('path/to/ABC.jar'), {
exclude group: 'javax.servlet'
}
or
compile(files('path/to/ABC.jar')) {
exclude group: 'javax.servlet'
}
But as I said, with a local file dependency there are no transitive dependencies, so an exclude does not make sense at all anyway.
To make the Gradle version conflict magic work, you can simply tell Gradle that those libraries are actually the same library just with different coordinates by using a module replacement like
dependencies {
modules {
module('javax.servlet:servlet-api') {
replacedBy 'javax.servlet:javax.servlet-api'
}
}
}
Then Gradle sees them as the same library and can do its version conflict resolution magic. Whether the library that needs the old version still works with the new version is a different topic that you have to check and / or try yourself. This like always depends on whether the new version is backwards compatible to the old version.
I have no way to test this now, but I believe your syntax is wrong. I have some examples here that look different, in your case it would be:
compile(files('path/to/ABC.jar')) {
exclude group: 'javax.servlet'
}
As I say, I cannot test it now, check if it helps and give a comment.

Use a Library in the processor's generated classes

I'm developing a library to generate classes using annotations and processors. The generated classes should use Gson library from google.
My question is : Where should I add the Gson dependency ? I'm currently adding it into the processor build.gradle but when the classes are generated, Gson is not found and Android Studio is suggesting to add it to the app module.
build.gradle of the processor :
implementation project(':lib-annotation')
implementation 'com.squareup:javapoet:1.9.0'
implementation 'com.google.code.gson:gson:2.8.1'
implementation 'com.google.auto.service:auto-service:1.0-rc3'
build.gradle of the app :
implementation project(':lib-annotation')
annotationProcessor project(':lib-processor')
Any help would be greatly appreciated, thanks!
P.S. The project is meant to be a library. I expect the users to only include my library in their gradle file, not the "sub dependency".
Simply using implementation prevent you from using transitive dependency.
The main project can't use or invoke the dependencies you added to your library.
As reminded to docs the implementation configuration should be used to declare dependencies which are internal to the component.
So you have to use api OR compile instead of implementation or add a condition to your transitive library e.g :-
implementation ('com.google.code.gson:gson:2.8.1'){
transitive = true;
}
Besides the fact implementation hides the dependency and therefore keeping it out of the app's path (so if you need to expose Gson, avoid using implementation), the problem is due to being compiling/implementing the library module instead of using a regular aar/jar/apklib package. Try this:
-Add the Android Maven Gradle plugin to the library project and configurate it.
-Using the plugin, compile and install the library into your local maven repository.
-instead of using compile/api/implementation for adding the library to the app, include mavenLocal() into your build.gradle, and then add the library as a regular dependency. All the necessary dependencies should be there.
here's an example of the plugin, in case you need it: https://github.com/fcopardo/EnhancedMapView
follow this link, I have imported without any problems.
http://blog.madadipouya.com/2015/09/21/how-to-add-gson-library-to-android-studio-project/
Okay, I finally fixed the problem!
I had to add the Gson dependency into the processor build.gradle using implementation or compile :
implementation 'com.google.code.gson:gson:2.8.1'
And add the dependency again into the annotation build.gradle using compile :
compile 'com.google.code.gson:gson:2.8.1'
I think it wasn't working because the Gson dependency was in the processor build.gradle which is included using annotationProcessor 'lib-processor' (Somehow the "transitivity" wasn't applying). Therefore I put the Gson dependency in the annotation build.gradle since I include it using implementation 'lib-annotation' and it worked.
Hope it will help

How can I force specific jar with version from in my `gradle.build`?

I have tried to exclude some jar from my build like that
configurations.runtime.exclude (group:'com.google.guava' , module: 'guava', version: '22.0')
and got an error that version is not a recognized filed.
How can I force specific jar with version from in my gradle.build?
I know I can remove without version, but i do want to use same jar with lower version.
That jar is not pulled directly, but via other dependent jar
You can't provide a version when you exclude a dependency.
Just do like this :
configurations.runtime.exclude group:'com.google.guava', module: 'guava'
edit, try this according to your comment :
configurations.runtime {
resolutionStrategy {
force 'com.google.guava:guava:your.lower.version'
}
}

Stetho-Timber library issue with new Timber version 4.1.2

While I was trying to use stetho-timber Library in my Android application I faced this problem:
Error:Module 'com.facebook.stetho:stetho-timber:1.3.1' depends on one
or more Android Libraries but is a jar
What's wrong?!
After inspecting in its codes I found that it uses timber v3.0.1!
Just add this to your build.gradle dependencies tag to exclude timber within the stetho library,
cause it is an old version and conflicts with new one:
dependencies {
compile ("com.facebook.stetho:stetho-timber:1.3.1") {
exclude group: "com.jakewharton.timber", module: "timber"
}
.
.
.
I have recently found Facebook Stetho Library and using it is fantastic, give it a try! :)

Gradle: excluding a jar from runtime dependencies

I need to exclude a jar from runtime dependency via Gradle.
I am getting this error:
Caused by: java.lang.IllegalStateException: Conflicting persistence unit definitions for name 'ldb-jpa': file:/D:/EricFrancis/shared/build/libs/shared.jar, file:/D:/EricFrancis/shared/build/resources/main
I'm trying to exclude the jar.
How do I tell gradle to do this?
Without more information (Gradle version, relevant parts of build script, etc.), it's hard to say. But since this isn't a Maven or Ivy dependency, I'd consider not adding it in the first place.
It turns out that I did not understand how configurations worked.
I was able to exclude the jar via:
configurations {
testRuntime {
exclude module: 'share'
}
testCompile {
exclude module: 'share'
}
}

Categories

Resources