How to find overlap dependencies in a Gradle or Maven Project - spring-boot

I have a Spring Boot Project with this two Dependencies.
id 'org.springframework.boot' version '2.7.2'
....
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'com.google.code.gson:gson:2.8.8'
My problem here is that Eureka client brings gson dependency 2.9 into the project. So at least the version 2.8.8 specification is useless here.
I want to keep the gradle file clean. Is there an easy way to find dependency overlaps like this?
I have exactly the same situation in my Maven project. A solution for Maven would be nice too.

run:
gradle dependencies
You will get a tree showing where all of the dependencies come from and which have been overruled by later versions.
See the documentation at https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html
The solution I would use for Maven is to convert it to a Gradle project to make my life easier for this and everything else to come.

Related

Gradle dependency scopes

I was experimenting a little bit with Gradle but as mainly being a Maven user, some dependency scopes are confusing me …
Some are identical to Maven:
compile -> compile
runtime -> runtime
compileOnly -> provided
but I also encounter implementation which sounds like the parent element of Maven POM but then again also not.
Can somebody explain me what is implementation and some other if they exist and I didn’t mention here (test versions of above are clear no need to explain)?
And if implementation is not like parent on Maven, how can we have the parent POM effect of Maven in Gradle?
As commented, please have a look at the documentation or even at this recent webcast (disclaimer: I am co-presenting that webcast)
As for the Maven comparison, view migrating / learning from Maven to Gradle the same as moving from subversion to git: while some vocabulary is the same, understanding the model of the later helps more than comparing.
In short:
Do not use compile or runtime in Gradle, they are deprecated.
implementation relates to dependencies that are required to compile and run your application.
compileOnly and runtimeOnly should be self-explanatory in the context of the above
The java-library plugin adds the api configuration which is reserved for dependencies that consumers of your library will need to compile.
There is no direct equivalent to a Maven parent pom. Whether you are talking about plugins, build config or dependencies, the way to centralize are different. Have a look at the documentation on multi-project authoring.

Comparing Maven project dependencies

Is there a simple way to list the differences between the artefacts added to the classpath by one version of a Maven project and another?
Here is the problem I'm trying to solve. If I change the version of an artefact declared in a Maven project, the list of transitive dependencies added to the classpath by the dependency may change. I want know what those changes are before I commit a change to a dependency version. The primary reason I want to know what transitive dependencies will change on the classpath when I change the version number of declared dependency is concern that changing the version number of a declared dependency may cause the version of a transitive dependency to change to one that has a security vulnerability in it.
At the moment, I'm using the dependencies plugin tree goal to produce a before and after change dependency tree and then comparing the two by eye. This is not ideal.
I also know of a way to achieve my goal using the OWASP dependency check Maven plugin but this also seem not ideal.
Can anyone suggest a better solution to my problem that using the dependencies plugin or the OWASP dependency check plugin? Is there a Maven plugin to produce what I need?
Thanks
Please try
mvn dependency:list
It will list all the dependencies with version information.
now you can see the difference using any diff checker tool online.

What is the difference between an app dependency and a module dependency/plugin?

When using some 3rd party libraries, I add a dependency to my module's build.gradle file.
compile 'com.android.support:appcompat-v7:24.1.1'
Or I add a plugin
apply plugin: 'com.neenbedankt.android-apt'
Some other times, the library requires adding a dependency to my app's build.gradle file.
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
What is the difference between these dependencies and plugins?
Why can't they all be set in a single build.gradle file?
All suggestions are appreciated, I'm having trouble searching for info on this
Three things. Gradle plugin, module dependency, a build dependency which is placed on the classpath of the build tool.
A plugin is how Gradle knows what tasks to use. There are many plugins. For more info, see Gradle - Plugin Documentation
A dependency is a library that is compiled with your code. The following line makes your module depend on the Android AppCompat V7 library. For the most part, you search Maven or Jcenter for these.
compile 'com.android.support:appcompat-v7:24.1.1'
The classpath setting is needed for Gradle, not your app. For example, this allows this includes the Gradle Build Tools for Android into the classpath, and allows Gradle to build apps.
classpath 'com.android.tools.build:gradle:2.1.2'
Why can't they all be in one build.gradle file?
They probably can be. It is simply more modular to not.
I got this answer from a colleague, and this helped me understand. "A gradle plugin is like the tools you use to build the app. The dependencies are the libraries included in the app. A gradle plugin is usually the tasks - like ktlint, etc."
I didn't understand this myself so here is what i found. My answer is based on gradle build tool.
Plugins:
Add additional tasks, repositories, new DSL elements, configuration for classpaths/build/run or dependency management for subsequent development. Plugins are developed for a larger scope of development like java, kotlin or spring-boot.
Dependencies:
modules/libraries for tasks like http, serialization or database are dependencies stored remotely at repositories or locally that are needed at runTime, test or build are resolved by gradle in a configured fashion.
Sources:
Spring boot gradle plugin: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin
Gradle documentation on plugins/dependencies: https://docs.gradle.org/current/userguide/plugins.html
https://docs.gradle.org/current/userguide/core_dependency_management.html
Remote repositories:
https://mvnrepository.com/
In simple words:
Plugins are used to add some additonal features to the software/tools(like Gradle). Gradle will use the added plugins at the time of building the App.
Dependecies are used to add some addtional code to your source code, so a dependency will make some extra code (like Classes in Java) in the form of library available for your source code.

How two know when a maven project has the same transitive dependenciy twice of different versions?

I have to add a new dependency to a maven project. This dependency has four transitive dependencies(according to http://mvnrepository.com/) and between them, there is spring-data-jpa jar.
The maven project I am working in has many dependencies configured in the pom so I understand there could be a big possibility that there is already a spring-data-jpa dependency in the project(transitive or not).
When you work in a large project with many dependencies and you have to add a new one, how to check if there is already the same transitive dependency of a different version? I have to check manually the transitive dependencies for each direct dependency configured? Has maven a warning for this situation?
How maven works in this situation? I mean, there could be two spring-data-jpa jars of different versions(this would be a problem) or maven resolves this in another way?
The simple answer is that the dependency plugin can tell you. The longer answer is that there are a number of different situations to consider about transitive dependency management, and how the plugin helps and what to do about it differs for each one.
Maven automatically chooses which dependency to include if two dependencies have the same coordinates (groupId, artifactId) with different versions. Broadly speaking, it picks the version that's highest in the tree - effectively overriding dependencies defined in downstream transitive dependency poms. So, if you have two different versions of exactly the same dependency then you will still only find one version of the dependency on the relevant classpath.
The dependency plugin can help you identify this situation by highlighting points where its made a decision, but you probably want to use the dependencyManagement section of your top-level pom to ensure that the dependencies which you bring in are the ones you expect.
Separate difficulties can arise when a dependency changes its groupId or artifactId. Then you can get two dependencies on the classpath - one with an old version on the old coordinates and one with the new version on the new coordinates. As examples, Spring, Hibernate and Apache commons have all found themselves doing this at some point or another. In this case all you can do is use to the dependency plugin to identify duplicated dependencies and then use exclusions tags to explicitly exclude them as transitive dependencies from the dependencies which are pull them in.
It's important to note that all of this dependency management can cause unintended breakage. If the thing that your application depends on really does depend on some specific version of a package as a transitive dependency then you can break it by overriding that version. So testing the features that you use is essential.
Have you tried the Maven Dependency Plugin? There's some useful goals you can run, such as mvn dependency:tree etc.

Statically linking maven and gradle dependencies

I am using the hector & astyanax projects. These projects used to require maven, and now astyanax requires gradle.
I would like to statically link one of these projects to my java project (which is not built using maven/gradle). I am not interested in updating the version of astyanax every time they make a new release. I am not interested in mavenizing/gradelizing my own project.
So, two problems arise: 1. Getting the astyanax jars. 2. Getting the depenedency Jars.
At first, not having time to thoroughly understand maven (get off my lawn!), I copied all of the jar files in my global .maven directory into my project, and linked to them. Problem is, it's a pretty messy solution.
Is there an easier way to get all jars needed to use a gradle/maven library? (While I don't mind using gradle to build astyanax, I don't want to use it to build my own project).
Getting jars for distribution, seems like a very basic use case, am I missing a simple way here?
astyanax is published to maven central as com.netflix.astyanax:astyanax:1.56.42. Any build tool (Grails, Maven, Gradle, Buildr, SBT) that resolves from Maven can make a dependency on Astyanax and have its dependencies transitively downloaded. That fact that it's built with Gradle doesn't change how it's consumed.
From your question, it's unclear how you want to resolve these libraries. If you don't want to use a tool (Grails, Maven, Gradle, Buildr, SBT), then you'll have to manually navigate every dependencies and its dependencies from Maven Central. It's quite uncommon for a modern java project to manually download dependencies anymore, the practicalness given the complex dependencies graph make it prohibitive.

Resources