Gradle use correct version of dependency - java

Currently, my project needs Cassandra as the database, so, I used org.springframework.data:spring-data-cassandra:2.1.9.RELEASE as the solution, and I also used spring-security-core 5.1.5 as the solution, but within spring-security-core 5.1.5, seems it has org.springframework.data:spring-data-cassandra:2.1.6.RELEASE dependency.
So I am wondering how to fix this in gradle within IDEA.

I would suggest you to use cassandra:2.1.6 everywhere to avoid version conflicts. I don't think you have to rewrote any parts of your code.
Or you could try to remove 2.1.6 version with
compile.exclude group: 'com.example.x', module: 'x'
But it could cause spring-security to work unstable. So first solution preferable.

I suggest excluding org.springframework.data:spring-data-cassandra:2.1.6.RELEASE in spring-security-core 5.1.5
Refer this link how to exclude - https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/ModuleDependency.html#exclude-java.util.Map-

Related

Upgrade distant transitive dependencies in gradle

Ok Log4j has a vulnerability between 2.0 and <2.15. I've been charged with updating the versions to 2.15 in some java applications we have. In digging in, this is pretty easy with gradle
compile 'org.apache.logging.log4j:log4j-api:2.15.0'
compile 'org.apache.logging.log4j:log4j-core:2.15.0'
compile('io.sentry:sentry-log4j2:5.4.3'){
exclude group: 'org.apache.logging.log4j'
}
solves the issue. But, everything can't be that simple right? OF COURSE! We have an application that references an internal artifact where the internal artifact source code DOESN'T EXSIST. It'd be easy to do the above in the internal artifact and publish a new version, but noooo. The internal artifact source requires spring boot, so updating the main application like this does not solve the issue.
compile('org.apache.logging.log4j:log4j-api:2.15.0')
compile('org.apache.logging.log4j:log4j-core:2.15.0')
compile('com.xxxx:xxxxx:0.0.1'){ <--
exclude group: 'org.apache.logging.log4j'
}
While the internal artifact does not include log4j with this setup, spring boot cannot find the reference to log4j because springboot is encapsulated inside the internal artifact.
I've been working at this for some time. I've tried implementation constraints. I've tried downloading the artifact, unzipping, and trying to decompile the class objects into java, but the decompiler was doing some optimization and I couldn't determine the target java version based on the decompiled classes. Which is scary and would require alot of testing before going into production.
How the hell do I either, make the aforementioned log4j version available to this mysterious artifact or how to I force the artifact to use a different version.
P.S. I've ran gradle dependencies and its 2.x -> 2.15. I've confirmed everything works fine with this upgrade.
P.P.S. The artifact is built with maven. I don't know if that matters and I don't think it does.
P.P.P.S. I've edited this a few times to improve clarity, if this is not your first time here, please re-read.

Gradle: Springboot overriding dependencies (jersey and apache httpclient)

I have a very simple springboot application for testing purposes.
Here my build.gradle:
plugins {
id 'org.springframework.boot' version '2.1.0.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mandas:docker-client:2.0.2'
}
org.mandas:docker-client:2.0.2 has a transitive dependency on org.glassfish.jersey.core:jersey-client:2.28. However gradle then pulls version 2.27 instead of 2.28.
If I run ./gradlew dependencyInsight --dependency org.glassfish.jersey.core:jersey-client I get the following output:
org.glassfish.jersey.core:jersey-client:2.27 (selected by rule)
...
org.glassfish.jersey.core:jersey-client:2.27
\--- org.glassfish.jersey.connectors:jersey-apache-connector:2.27
\--- org.mandas:docker-client:2.0.2 (requested org.glassfish.jersey.connectors:jersey-apache-connector:2.28)
\--- compileClasspath
org.glassfish.jersey.core:jersey-client:2.28 -> 2.27
\--- org.mandas:docker-client:2.0.2
\--- compileClasspath
It seems that spring-boot-starter-web somehow has a dependency on org.glassfish.jersey.core:jersey-client:2.27. However, if I print all my dependencies with ./gradlew dependencies I do not see a dependency on org.glassfish.jersey.core:jersey-client:2.27 from spring-boot-starter-web.
However, searching a bit around the web, i found another way in tracking down a dependency:
grep -r "2.27" ~/.gradle/caches/modules-2/files-2.1/*
Like this i was able to track down where version 2.27 was introduced. It seems to be declared in the following poms:
spring-boot-dependencies-2.1.0.RELEASE.pom
spring-boot-autoconfigure-2.1.0.RELEASE.pom
My question now is manifold:
First of all, why does spring-boot-starter-web depend on jersey? I was always under the impression that if we want to explicitly use jersey over the spring implementation we would include spring-boot-starter-jersey.
Why can't I see that spring-boot-starter-web depends on org.glassfish.jersey.core:jersey-client:2.27 when running ./gradlew dependencies. Obviously there must be a dependeny on it somewhere as it downgrades the version.
Why is version 2.28 downgraded to version 2.27? How can I know which policy is applied by spring boot in order to make a choice for a specific version.
The application is running perfectly fine, but now as i got a version conflict, how should i best handle this? Is it a viable option to just use v2.28 instead of v2.27. I think this also refers to my first answer on why spring-boot is actually using jersey.
I know these are multiple questions, however I think it is better to ask them in one question instead of spreading them over multiple ones, as they are all related to the same context.
BTW: This is not only happening with org.glassfish.jersey.core:jersey-client. Exactly the same thing applies to org.apache.httpcomponents:httpclient.
Thanks for your help!
First of all, why does spring-boot-starter-web depend on jersey? I was always under the impression that if we want to explicitly use jersey over the spring implementation we would include spring-boot-starter-jersey.
It doesn't. Rather, it depends on Tomcat. You are correct that you would need the jersey starter for auto-configuring that.
Why can't I see that spring-boot-starter-web depends on org.glassfish.jersey.core:jersey-client:2.27 when running ./gradlew dependencies. Obviously there must be a dependeny on it somewhere as it downgrades the version.
Because it doesn't. More on that below.
Why is version 2.28 downgraded to version 2.27? How can I know which policy is applied by spring boot in order to make a choice for a specific version.
This is the underlying problem. I will explain it below.
The application is running perfectly fine, but now as i got a version conflict, how should i best handle this? Is it a viable option to just use v2.28 instead of v2.27. I think this also refers to my first answer on why spring-boot is actually using jersey.
It depends. In my experience, your dependencies could break both by upgrading and downgrading a transitive dependency compared to that they have been built and tested against, even if it is just a minor version (I am looking at you, SnakeYAML!) So you really just have to give it a shot. Usually it is safer to upgrade than to downgrade, but sometimes it will still cause problems.
Here's the deal with the Jersey downgrade.
The Spring Dependency Management plugin is used to control the versions of your dependencies, both the direct and the transitive ones.
When you apply both the dependency management plugin and the Spring Boot plugin, the latter will apply its default versions, which comes from the Spring Boot BOM. You can check which dependencies are managed and in what versions by running gradle dependencyManagement.
The idea with all this is that you get a set of dependencies that are known to work well with each other. If you like a different version of one of the managed dependencies, you will have to configure it using the dependencyManagement extension (as documented here).
This is why your Jersey dependency gets downgraded.
I personally don't use the Spring dependency management plugin as I like the way you work with dependencies in plain Gradle. So I usually just do something like this:
plugins {
id 'org.springframework.boot' version '2.1.0.RELEASE'
id 'java'
}
dependencies {
implementation platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
}
In this case, it will by default use the dependencies from the Spring Boot BOM, but not downgrade them if anyone needs a newer version. But it will upgrade them if needed, and you also don't have to specify a version yourself if you don't want to, in which case it will use the one from the BOM.

What is the spring-boot-configuration-processor ? Why do people exclude libraries from it? Why is it invisible in dependency tree?

Introduction
So I noticed the following line in the gradle file of the jhipster project:
annotationProcessor ("org.springframework.boot:spring-boot-configuration-processor") {
exclude group: 'com.vaadin.external.google', module: 'android-json'
}
https://github.com/jhipster/jhipster-sample-app-gradle/blob/9e9c3db8f3bedba4b1efd85ecb6ff3f12a5f596a/build.gradle#L230
We also used the same configuration in Maven for another project to solve the following problem: Maven transient dependency (library/jar vaadin json) is not being excluded
Questions
And now I have the following questions:
What does the spring-boot-configuration-processor dependency do?
Why is it necessary to sometimes exclude dependencies from the processor?
Why doesn't the processor necessarily appear in the mvn-dependency tree?
Why are exclusions used with processor in situations where it's very difficult to exclude a dependency?
spring-boot-configuration-processor is an annotation processor that generates metadata about classes in your application that are annotated with #ConfigurationProperties. This metadata is used by your IDE (Eclipse, IntelliJ, or NetBeans) to provide auto-completion and documentation for the properties when editing application.properties and application.yaml files. You can learn a bit more about it in the relevant section of Spring Boot's reference documentation.
Since Spring Boot 1.5.10, the exclusion is no longer necessary as com.vaadin.external.google:android-json is no longer a dependency of spring-boot-configuration-processor.
What does the spring-boot-configuration-processor dependency do?
It scans the libraries in the build and sees what properties they use so as to inform the IDE
Why is it necessary to sometimes exclude dependencies from the processor?
Maven libraries can clash sometimes - the one you reference was excluded by JHipster because it led to errors when on the classpath together with another library in JHipster's dependencies
Why doesn't the processor necessarily appear in the mvn dependency:tree?
It does for me on the jhipster-sample-app. Presumably you're referring to the comment on the linked issue stating that the android-json library isn't in the tree. I've asked there about that.
Why are exclusions used with processor in situations where it's very difficult to exclude a dependency?
This is a dependency clash issue like any other really, it just happens that the processor is bringing in the key dependency (or rather was, as #Andy Wilkinson points out com.vaadin.external.google:android-json is no longer used by the processor)

Maven plugin dependency conflict

I have a bit of a thorny maven dependency problem. A plugin in a parent pom.xml requires guava v10 and a dependency in the module I'm trying to build requires guava v18. Not exactly sure how to proceed as both are needed but maven resolves in favor of v10, which crashes the dependency at runtime. I tried skipping the plugin as outlined here (although I'm not sure if it's a good idea), but that didn't help. How do I dig my way out of this?
Please reference to this post and try to use exclusion to exclude the guava version you don't want to use

Dependency org.json:json:20090211 is ignored for debug as it may be conflicting with the internal version provided by Android

While I am running android studio, the warning below appears:
Dependency org.json:json:20090211 is ignored for debug as it may be conflicting with the internal version provided by Android.
In case of problem, please repackage with jarjar to change the class packages
How can I resolve this error?
Thank you.
CommonsWare answer is correct. Dependency org.json:json:20090211 is ignored for debug as it may be conflicting with the internal version provided by Android.
If you are using gradle dependency try excluding org.json from the package.
compile ('com.your.dependency.name:0.0.0'){
exclude group: 'org.json', module: 'json'
}
This one worked for me.
It would appear to be that you are trying to use some Java dependency that is not set up for Android. Most likely, it is whatever dependency you just added. That could be for org.json:json, or it could be for something else that has a transitive dependency on org.json:json.
If you added the dependency on org.json:json yourself, just use the copy of those classes that are in the Android SDK.
If you added a dependency on something else, and it is what is requiring org.json:json, talk to the developers of the library you are trying to use and discuss with them how best to use that library on Android.

Categories