Example:
implementation(group: 'org.seleniumhq.selenium', name: 'selenium-remote-driver', version: '3.13.0')
implementation(group: 'com.mypack', name: "old-library", version: '1.0')
Problem is that old-library throws
java.lang.NoClassDefFoundError: org/openqa/selenium/remote/SessionNotFoundException which is missing in newer selenium versions.
Unfortunately I have no access to source code.
Question - is it possible to say only for old-library to use old selenium version?
okay, that's not possible. as I get from the Gradle Slack chat:
than there is no way to solve it without dependency package relocation
actually, in this case problem not even on classpath level, because if 2 dependencies have the same id Gradle have to choose one of them.
If you change only dependnecy id, you will have problems on runtime, because 2 dependencies with many conflicting classes will be on the same classpath. It’s valid for Java, but which version will be choosed on classpath resolution depends on classloader and you cannot rely on this
Related
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.
I understand there is library dependency management in Springboot so that the correct version of starter kits will be picked for the Springboot version. However I do not fully understand how the third-party libs' versions are controlled.
For example, in build.gradle file, we can use a lib like this:
implementation('org.liquibase:liquibase-core') .
I know that Gradle's logic is to pick the latest version if no version is specified. I am not sure if there are any tools like a lock file to lock down ALL the versions used by this application, or we have to specify the version like:
compileOnly 'org.projectlombok:lombok:1.18.4' ?
So that we can be confident that all the libs used in the team are identical.
The best practice recommended by gradle is to declare dependencies without versions and use dependency constraints.
dependencies {
implementation 'org.liquibase:liquibase-core'
}
dependencies {
constraints {
implementation 'org.liquibase:liquibase-core:3.6.2'
}
}
I have a project that uses gradle and mavenCentral() (plus mavenLocal()). It has enough dependencies that I can't go through them one by one.
Given the name of a .jar file in build/install/x/lib, how do I find out the chain of transitive dependencies that caused it to be included?
update: I discovered gradle dependencies. The output shows:
org.apache.commons:commons-jexl:2.1.1
\---- commons-logging:commons-logging:1.1.1 -> 1.1.3
What does this mean? 1.1.1 is the version I expect, and 1.1.3 is the version I seem to actually end up using. Looking at the pom for commons-jexl it looks like it does indeed list logging:1.1.1 as a requirement. What's going on? Is there a way for me to tell it to avoid certain versions, or force it to use the version it was set to?
The problem in my case is that it's including a -SNAPSHOT version and I'd rather it didn't. In fact I probably want it to just use the version numbers I'm asking for instead of the most recent it can find.
Dependencies of gradle-managed project have their own dependencies (they're called transitive). It may happen (and happens quite often) that two different dependencies has the same (group and module) dependency but in the different version). This is the case with commons-logging:commons-logging. In this case there are two transitive dependencies one versioned with 1.1.1 and the second one with 1.1.3. If both of the libraries will be included in the final artifact it may result in a conflict and exception. To prevent such situation gradle tries to resolve mentioned version resolution problems by picking (by default) the latest version. It's indicated with the right arrow -> see here. You can exclude transitive dependencies from a particular dependency. This chapter of manual might be useful.
I have the problem that Gradle is pulling in two versions of a library, which is causing runtime issues. These versions are both necessary, and are dependencies of two of the dependencies I have. Library A needs Library C version x, and Library B needs Library C version y. At runtime, the incorrect version of Library C is used, causing a NoSuchFieldError. Is this something I can resolve in Gradle? Or is it more of an issue for my IDE/JVM options?
In general Gradle will do the right thing by choosing the latest version of a library when there are dependency conflicts. However for various reasons this may not always work correctly. To get around this you can tell Gradle explicitly to not include a certain transitive dependency during its resolution. Here is an example:
compile (group:'com.project', name:'library', version:'1.0') {
// These lines will exclude these other libraries from being included
exclude module: 'groovy-all'
exclude module: 'log4j'
exclude module: 'commons-lang'
}
You can make this more fine grained if you need to, but I've found excluding modules seems to work well for me.
I currently have a project that I have performed an aqua scan on, and it identified the jackson-databind-2.9.8.jar I'm currently using as a critical vulnerability, and has recommended me to replace with version 2.10. To update this, while ensuring all other dependencies/code works fine, I've tried the following code in my build.gradle file, where group_name:microservice-event:0.2.+ shows up on the list of gradle dependencies and apparently brings in the 2.9.8 jar that is causing problems:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.10'
implementation('*group_name*:microservice-event:0.2.+') {
exclude group: 'com.fasterxml.jackson.core', module: 'jackson-databind'
}
I've also removed the implementation '*group_name*:microservice-event:0.2.+' line I previously had in my build.gradle file.
However, now the project fails to build and I have no idea why. Would anyone know of how to write code in the build.gradle file to successfully exclude old jars/dependencies, while allowing for newer jars (as I've tried to do with the line implementation 'com.fasterxml.jackson.core:jackson-databind:2.10'). Note that I do not want to update the spring boot version.
When Gradle encounters two different versions of the same dependency, it will perform a conflict resolution. It defaults to choosing the highest version number.
However, because many libraries like Jackson consists of a number of individual modules like jackson-databind and jackson-core, you may end up in a situation where there is a mismatch between the different versions.
To align them, you can use the Jackson BOM and Gradle's platform dependency mechanism. It looks like this (choose only one of the depencendies below):
dependencies {
// Enforce the specified version
implementation(enforcedPlatform("com.fasterxml.jackson:jackson-bom:2.10.4"))
// Align all modules to the same version, but allow upgrade to a higher version
implementation(platform("com.fasterxml.jackson:jackson-bom:2.10.4"))
}
You don't need to exclude anything from your other dependencies.
If you encounter problems with the use of Jackson after upgrading, you should have a look at the release notes for 2.10 and check if you might be hit by any of the compatibility changes. Of cause, if the problem is in a third-party library, it might be more difficult to fix. But you may try the latest version in the 2.9 line (which is 2.9.10 at this time) and see if the vulnerability is fixed here.