I am seeing some weirdness in my Gradle build. I have a Spring Boot app (which uses Gradle for its build) and am trying to pull in both the Hibernate Validator as well as Hibernate Core. Here's the dependencies declaration in my build.gradle file:
dependencies {
compile('org.springframework.boot:spring-boot-starter-web') {
exclude module: 'spring-boot-starter-tomcat'
}
compile(
'org.codehaus.groovy:groovy-all:2.4.12'
,'com.google.inject:guice:4.1.0'
,'ch.qos.logback:logback-classic:1.2.3'
,'org.slf4j:jul-to-slf4j:1.7.25'
,'org.apache.logging.log4j:log4j-to-slf4j:2.9.1'
,'commons-cli:commons-cli:1.4'
,'org.apache.commons:commons-lang3:3.7'
,'io.dropwizard.metrics:metrics-core:3.2.5'
,'io.dropwizard.metrics:metrics-json:3.2.5'
,'org.springframework.security:spring-security-jwt:1.0.9.RELEASE'
,'org.springframework.security.oauth:spring-security-oauth2:2.2.1.RELEASE'
,'io.jsonwebtoken:jjwt:0.9.0'
,'org.hibernate:hibernate-validator:6.0.7.Final'
,'mysql:mysql-connector-java:6.0.6'
,'org.hibernate:hibernate-core:5.2.12.Final'
,'com.h2database:h2:1.4.196'
,'org.springframework.boot:spring-boot-starter-jetty'
,'org.springframework.boot:spring-boot-starter-actuator'
,'org.springframework.boot:spring-boot-starter-security'
,'org.springframework.boot:spring-boot-starter-data-rest'
,'org.springframework.boot:spring-boot-starter-data-jpa'
)
dev('org.springframework.boot:spring-boot-devtools')
testCompile(
'org.spockframework:spock-core:1.0-groovy-2.4'
,'junit:junit:4.12'
)
}
When I run ./gradlew dependencies I get a huge output, but from the compile dependencies tree I see the following:
| +--- org.springframework.boot:spring-boot-starter:1.5.8.RELEASE
| +--- org.hibernate:hibernate-validator:5.3.5.Final -> 6.0.7.Final
| | \--- org.hibernate.validator:hibernate-validator:6.0.7.Final
| | +--- javax.validation:validation-api:2.0.1.Final -> 1.1.0.Final
| | +--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.1.Final
| | \--- com.fasterxml:classmate:1.3.1 -> 1.3.4
So to me it looks like spring-boot-starter:1.5.8.RELEASE is pulling in validation-api:2.0.1.Final but for some reason Gradle is selecting validation-api:1.1.0.Final for me...am I reading that correctly? In my IDE compile classpath I only see validation-api:1.1.0.Final, not 2.0.1.Final.
Why is Gradle selecting 1.1.0.Final instead of 2.0.1.Final? I ask because Hibernate Validator 5.x is not compatible with Validation API 1.x and when my app runs I get all sorts of Hibernate Validation-related errors.
Update
Some more output:
gradle -q dependencyInsight --configuration compile --dependency validation-api
javax.validation:validation-api:1.1.0.Final (selected by rule)
javax.validation:validation-api:2.0.1.Final -> 1.1.0.Final
\--- org.hibernate.validator:hibernate-validator:6.0.7.Final
\--- org.hibernate:hibernate-validator:6.0.7.Final
+--- compile
\--- org.springframework.boot:spring-boot-starter-web:1.5.8.RELEASE
+--- compile
\--- org.springframework.boot:spring-boot-starter-data-rest:1.5.8.RELEASE
\--- compile
The full compile configuration output can be found here.
The version is enforced by Spring Boot.
See the POM for the Spring Boot dependencies: http://search.maven.org/remotecontent?filepath=org/springframework/boot/spring-boot-dependencies/1.5.8.RELEASE/spring-boot-dependencies-1.5.8.RELEASE.pom and look for "javax-validation.version".
See https://docs.spring.io/platform/docs/Brussels-SR4/reference/html/getting-started-overriding-versions.html for more information on how to override Spring Boot versions.
I would recommend overriding directly "javax-validation.version" and "hibernate-validator.version" instead of redefining the dependencies.
There is some conflict with another dependency that is pulling the older 1.1.0 in the compile classpath.
This means that some other library which has higher priority in gradle build order is dependent the older 1.1.0 version.
You can see here more info on how to specify the gradle build order.
I met similar problems, then I found it caused by using the Dependency management in gradle:
plugins {
...
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8"
}
}
this dependency management impact the transitive dependency version solution. after comment it out. all the version is correct.
Related
In our project we are using the following Groovy dependency:
compile("org.codehaus.groovy:groovy-all:2.5.8")
The issue is that this dependency has multiple transitive dependencies, one of them is:
org.apache.ant:ant 1.9.13
which has some vulnerabilities and needs to get upgrade to version 1.10.8 which they got fixed at.
When I upgrade the parent groovy-all:2.5.8 to the latest version I can still see it gets the problematic org.apache.ant:ant 1.9.13 dependency:
+--- org.codehaus.groovy:groovy-all:3.0.6
| +--- org.codehaus.groovy:groovy:3.0.6 -> 2.5.10
| +--- org.codehaus.groovy:groovy-ant:3.0.6 -> 2.5.10
| | +--- org.codehaus.groovy:groovy:2.5.10
| | +--- org.apache.ant:ant:1.9.13
Is there any way forcing Gradle to brings back the version I need?
Enforce Version
You can override transitive dependency versions with gradle (see: gradle docs) using the constraints keyword:
constraints {
implementation('org.apache.ant:ant') {
version {
require '1.10.12'
reject '1.9.13'
}
because('Versions < 1.10.11 got several vulnerabilities: CVE-2021-36374, CVE-2021-36373, CVE-2020-11979')
}
}
Verify
The easiest way to verify that the dependency enforcement is working will be as follows:
./gradlew -q dependencyInsight --dependency ant
You'll then see something like this, indicating the accomplished upgrade of the version.
org.apache.ant:ant:1.9.13 -> 1.10.12
I work on a large project with multiple services and libraries, mostly in grails, with gradle builder. I'm trying to update a library (say logback) for security reasons.
I already updated it in one of our libraries (say our-logger), like so:
#our-logger/build.gradle
...
dependencies {
...
compile 'ch.qos.logback:logback-classic:1.2.3'
...
}
when I update a service (say our-service) to use the new version of our-logger i get logback included from other libraries, and gradle chooses the lower version coming through cobertura and some other dependencies, instead of the higher version coming through our-logger.
#our-service/build.gradle
...
apply plugin: 'cobertura'
...
dependencies {
...
compile 'our-logger:9.99' # safe now with logback-1.2.3
...
}
~/our-service $ ./gradlew dependencies
...
cobertura
\--- net.sourceforge.cobertura:cobertura:2.1.1
+--- ch.qos.logback:logback-classic:1.0.13 -> 1.1.11
| \--- ch.qos.logback:logback-core:1.1.11
...
compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
+--- org.grails:grails-dependencies:3.3.8
| +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE -> 1.5.15.RELEASE
| | +--- ch.qos.logback:logback-classic:1.1.11
| | | +--- ch.qos.logback:logback-core:1.1.11
...
+--- our-logger:9.99
| +--- ch.qos.logback:logback-classic:1.2.3 -> 1.1.11 (*)
How do I enforce logback-1.2.3 without explicitly declaring it in all services?
The gradle docs file this under Advanced Dependency Management. You should be able to satisfy your goal using excludes. There are other ways too Gradle Docs
compile(“some:other:dependency”) {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
I have declared a dependency for org.spockframework:spock-spring:1.1.d91bf785-groovy-2.4, but in runtime scope it is overridden to 1.0-groovy-2.4. Is there a way to figure out which dependency is overriding it?
1.0-groovy-2.4 is not present in any gradle file locally, and it is not visible when I run gradle dependencies in the shared-config project.
Here's gradle dependencies from the main-web project:
testCompile
[...]
+--- project :shared-config
| [...]
| +--- org.spockframework:spock-spring:1.1.d91bf785-groovy-2.4
[...]
runtime
[...]
+--- project :shared-config
| [...]
| +--- org.spockframework:spock-spring:1.1.d91bf785-groovy-2.4 -> 1.0-groovy-2.4
| | +--- org.spockframework:spock-core:1.0-groovy-2.4 -> 1.1.d91bf785-groovy-2.4
| | \--- org.codehaus.groovy:groovy-all:2.4.1 -> 2.4.12
dependencyInsight gives some insight:
$ gradle dependencyInsight --dependency org.spockframework:spock-spring:1.0-groovy-2.4 --configuration runtime
> Task :main-web:dependencyInsight
org.spockframework:spock-spring:1.0-groovy-2.4 (selected by rule)
org.spockframework:spock-spring:1.1.d91bf785-groovy-2.4 -> 1.0-groovy-2.4
\--- project :shared-config
\--- runtime
But the same command in the shared-config project doesn't yield any results:
No dependencies matching given input were found in configuration ':shared-config:runtime'
I have tried overriding the version without success:
configurations.all {
resolutionStrategy {
force "org.spockframework:spock-spring:1.1.d91bf785-groovy-2.4"
}
}
Seems like you are using spring boot as a parent or spring boot dependencies as a bom (dependency manager)
by default in latest spring boot versions 1.5 + spock.version is set to 1.0-groovy-2.4 that's why spock-core still have old version.
In order to fix this in gradle you need to override property spock.version in your gradle app. By adding spock.version = 1.1-groovy-2.4 to gradle.properties file.
Visit Spring doc for overriding dep properties to find more.
I have a Gradle build that splits up my JOOQ generated code into a separate jooq subproject that my api-svc project then depends on.
When I upgrade the jooq subproject to 3.10.1, for some reason Gradle decides to use 3.9.5 to build the api-svc instead. I have no idea why, and I have to override by adding an explicit dependency in my api-svc project to work around it.
How can I debug what's going on to see why Gradle is overriding the version?
My JOOQ subproject's definition:
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
...
classpath 'org.jooq:jooq-codegen:3.10.1'
...
}
}
...
dependencies {
compile 'org.jooq:jooq:3.10.1'
}
...
Here's the full version of the jooq subproject: https://bitbucket.org/snippets/shorn/64RnL5
And the inclusion in the api-svc project:
dependencies {
compile project(":idl")
compile project(":api-svc:jooq")
...
various other compile dependencies, spring-boot, etc.
When I do ./gradlew :api-svc:jooq:dependencies, it says:
------------------------------------------------------------
Project :api-svc:jooq
------------------------------------------------------------
...
compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
\--- org.jooq:jooq:3.10.1
...
But, when I do ./gradlew :api-svc:dependencies, it shows:
------------------------------------------------------------
Project :api-svc
------------------------------------------------------------
...
compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
+--- project :idl
| +--- org.apache.commons:commons-lang3:3.4
| \--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.8
| +--- com.fasterxml.jackson.core:jackson-core:2.8.8 -> 2.8.10
| \--- com.fasterxml.jackson.core:jackson-databind:2.8.8 -> 2.8.10
| +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0
| \--- com.fasterxml.jackson.core:jackson-core:2.8.10
+--- project :api-svc:jooq
| \--- org.jooq:jooq:3.10.1 -> 3.9.5
...
Full output here, if it helps: https://bitbucket.org/snippets/shorn/4x8eaG
So, you can see Gradle is choosing to use the 3.9.5 version of JOOQ instead of what I specified.
How do I debug why Gradle is doing that?
I can workaround this by adding jooq:3.10.1 as a direct compile dependency of the api-svc project - but that's redundant and as far as I understand, I shouldn't have to do that.
EDIT: Lukas Eder has pointed out in the comments that the root cause of the problem is the Spring has a dependency on JOOQ 3.9.5 and Gradle is using that. But the question is - how do I figure that out for myself without trawling through every dependency in my project, just in case they happen to have the reference that's messing up my build?
I made a post over on the Gradle forms to try and get an answer to this: https://discuss.gradle.org/t/how-do-i-debug-why-a-dependency-was-overridden/24572
There was some other discussion in private messages, but my conclusion is that Gradle has no way to debug these kind of dependency overrides.
If you found this question while trying to figure out a problem with your own build - the only advice seems to be that you need to dig through all your dependencies looking for the source of the conflict.
Alternatively, try a StackOverflow question or posting over on the Gradle forums.
I ran into a problem that puzzled me.
I use gradle build spring-boot project and i want package a runtime jar.
this is my dependencies :
buildscript {
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.5.RELEASE")
}
}
plugins {
id 'org.springframework.boot' version '1.5.5.RELEASE'
}
dependencies {
....
compile 'org.elasticsearch:elasticsearch:5.0.0'
compile 'org.elasticsearch.client:transport:5.0.0'
....
}
i run the cmd gradle dependencies :
+--- org.elasticsearch:elasticsearch:5.0.0 -> 2.4.5
| | +--- org.apache.lucene:lucene-core:5.5.4
| | +--- org.apache.lucene:lucene-backward-codecs:5.5.4
| | | \--- org.apache.lucene:lucene-core:5.5.4
| | +--- org.apache.lucene:lucene-analyzers-common:5.5.4
when i remove spring-boot plugin, Everything is normal.
i change spring-boot plugin version. some time There are some dependencies Will change the version.
please help me check it question, thx !