I'm using mongodb with Spring Boot. Recently, my mongodb was upgraded to version 3.0.
I'm using the following Gradle dependencies for Spring:
buildscript {
ext {
springBootVersion = '1.2.6.RELEASE'
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
If I look on maven repositories for Gradle: 'org.springframework.boot:spring-boot-starter-data-mongodb:1.2.6.RELEASE', I see the following (http://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb/1.2.6.RELEASE):
The dependencies for the mongo-java-drivers are 2.12.5 under the "Version" column. I was wondering what the "Update" column is there for and how can I use the version of the mongo-java-drivers listed there instead (3.0.4)?
Since I'm using mongo 3.0, I would like to use the 3.0.4 java-drivers instead of 2.12.5 as I need to update my java-drivers to be at least 2.13 before they will work with my mongodb 3.0: http://docs.mongodb.org/manual/release-notes/3.0-scram/#upgrade-drivers
Just add the following dependency to your project dependencies:
compile 'org.mongodb:mongo-java-driver:3.0.4'
This will explicitly set there mongodb Java driver to the newest version and will overrun the transitive dependency version of spring-boot-starter-data-mongodb.
BTW, the "Updates" column means the newest version for a specific Artifact.
You can force the usage of a newer version of a dependency by just explicitly adding the dependency version that you want to use in the pom.xml.
Then Maven will use the explicitly specified version to compile.
FYI, you can exclude a dependency triggered by a direct dependency by using the exclude element.
See this doc to know how maven manages dependencies.
If you are using Gradle, see this page. In fact, you exclude the MongoDB transitive dependency triggered by spring boot and you explicitly add the latest version as a direct dependency.
Related
I'm using Gradle 6.6 to build my Spring Boot app. According to this post, the io.spring.dependency-management plugin is no longer needed since Gradle 5+ supports BOM files.
However, I receive the following error if I remove the plugin:
Could not run phased build action using connection to Gradle distribution 'https://services.gradle.org/distributions/gradle-6.6.1-bin.zip'.
Build file 'C:\my-app\build.gradle' line: 14
A problem occurred evaluating root project 'my-app'.
Could not find method dependencyManagement() for arguments [build_6e8ejdhnd2no2m9jw221sctmn3$_run_closure2#432e46e2] on root project 'my-app' of type org.gradle.api.Project.
Line 14 of my build.gradle file is referenced in the above error. Here are lines 14-18:
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8"
}
}
Is there another way to specify the required dependencies for Spring Cloud without using io.spring.dependency-management plugin?
dependencyManagement() is provided exclusively by the io.spring.dependency-management plugin. Which means you cannot use it if you don't use the plugin.
And in that case you have to use the gradle's platform capability.
In the post you linked there's an example of that.
To fix your build, remove the dependencyManagement part and add
implementation platform("org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8")
to your dependencies { }
Reference: https://docs.spring.io/dependency-management-plugin/docs/current/reference/html/#dependency-management-configuration-dsl
When executing (in gradle 6.5)
./gradlew dependencyInsight --dependency groovy-testng --configuration testRuntimeClasspath
I could find groovy-testng comes from groovy-all library which was added to our build.gradle. I wanted to update version of groovy-testng, so I decided to update groovy-all which, according to mvnrepository, contains groovy-testng in version 3.0.4, but still the version of groovy-testng was the old one and gradle didn't resolve it to the latest version:
org.codehaus.groovy:groovy-testng:2.5.12 (selected by rule)
variant "runtime" [
org.gradle.status = release (not requested)
org.gradle.usage = java-runtime
org.gradle.libraryelements = jar
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.version = 11
]
org.codehaus.groovy:groovy-testng:3.0.4 -> 2.5.12
\--- org.codehaus.groovy:groovy-all:3.0.4
\--- testRuntimeClasspath
I have found the line selected by rule but couldn't find any ResolutionStrategy in my project, so I started to comment out and see what causes this. It turned out it's a plugin org.springframework.boot together with io.spring.dependency-management causes this version to be downgraded. Why? And why only when both of them are included? I assume these plugins define some ResolutionStrategy? What is the easiest way to find out where is the ResolutionStrategy coming from?
The Spring Dependency Management plugin is rather heavy handed. If were you build your project with --info or -i, you will see a bunch of these logs:
Applying dependency management to configuration 'bootArchives' in project 'demo'
Applying dependency management to configuration 'archives' in project 'demo'
Applying dependency management to configuration 'default' in project 'demo'
Applying dependency management to configuration 'compile' in project 'demo'
Applying dependency management to configuration 'implementation' in project 'demo'
Applying dependency management to configuration 'runtime' in project 'demo'
Applying dependency management to configuration 'compileOnly' in project 'demo'
From my experience, the dependency management plugin will win/force itself to win.
I can see in your snippet, that you wanted 3.0.4 of Groovy, but Gradle resolved 2.5.12. If you look at the Spring Boot Dependencies BOM, you will see that 2.5.12 is the current version for Spring Boot 2.3.1: https://github.com/spring-projects/spring-boot/blob/2.3.x/spring-boot-project/spring-boot-dependencies/build.gradle#L365..L371
The Spring Boot Gradle plugin detects if the Spring dependency management plugin is present, and if so, configures the plugin to import the Spring Boot dependencies BOM: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/DependencyManagementPluginAction.java
From looking at the BOM: https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.3.1.RELEASE/spring-boot-dependencies-2.3.1.RELEASE.pom
You should be able to override the Groovy version like so:
ext {
set("groovy.version", "3.0.4")
}
The Spring dependency management plugin should pick that up and apply 3.0.4
If that doesn't solve your issue, then you have other plugins or configuration at play here that you will need to figure out.
I also suggest watching Managing Dependencies for Spring Projects with Gradle to learn the differences between Spring dependency management plugin and Gradle's native dependency management.
I have a Spring Boot project which uses "blessed" dependencies via the Gradle plugin. The dependencies block in my build.gradle file looks like this:
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-data-jpa"
compile "com.fasterxml.jackson.core:jackson-core"
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-csv"
}
(I've removed several other dependencies for brevity.)
The above code is broken because Spring Boot does not have a "blessed" version for the dataformat-csv extension.
All I want to do is get it to use the Spring Boot-derived version for jackson-core and use it for the jackson-dataformat-csv as well for consistency. How do I get the version number for that dependency if it's been derived by a plugin?
In a gradle project, I have my dependencies set as:
dependencies {
compile group: 'com.our_organization.lib', name: 'Libraries', version: '5.+'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
}
which uses the latest released version of Libraries, and works perfectly.
I then release my built jar to Artifactory via:
artifactory {
contextUrl = artifactory_contextUrl
publish {
repository {
repoKey = publicationRepoKey
username = artifactory_user
password = artifactory_password
maven = true
}
}
}
which for the most part works fine.
However, when I go to artifactory and get the xml for any given version, it's dependencies are listed as
<dependencies>
<dependency org="com.our_organization.lib" name="Libraries" rev="5.+" />
<dependency org="commons.io" name="commons.io" rev="2.4" />
</dependencies>
which means I am unable to link my version to the specific Libraries version that was used for its build.
What I'd like to do is have the dependency version given to artifactory be the specific resolved version that is used in the build.
I've scoped a couple of things, all very hacky, and feel there has to be a better way.
Here's what I've thought of / tried:
Resolving the dependency myself and setting the specific version in the gradle dependency dsl, so to gradle it looks like a specific version. Using ivy to get the resolved version of a dependency of proving to be harder that it should.
Mucking the xml after its written but before it's sent to artifactory. This is just bad on so many levels and prone to breaking in the future.
Using a seperate gradle project to determine the resolved version and write that to a properties file which is then used similarly to #1. This feels like overkill.
Overall, this seems like a simple for which, for the life of me, I can't find an appropriate solution.
I am not sure what Gradle will do with it in pom.xml, but you might try using the Artifactory's functionality to retrieving the latest version, instead of Gradle's one.
The post
In Gradle, how can I generate a POM file with dynamic dependencies resolved to the actual version used?
exactly solves this problem. But you have to use the maven-publish Plugin instead of the Artifactory Plugin.
In maven, you can declare depenencies versions in dependency management section.
Say I have such pom for managing default versions of some libraries for all of my projects (so I don't have to repeat them all over again and so I can ensure some consistency across all of my projects).
Then I have multiple projects(project A and project B) which have this pom set as parent pom. If in project A I want to use spring.jar, and I have spring.jar defined in dependency-management of A's parent pom, I don't have to define spring version in A's pom again, I just define that it depends on spring. So far it's ok, is pretty simple how to do it in gradle too (http://stackoverflow.com/questions/9547170)
What I'm wondering about is this situation:
Imagine that spring 3.0 depends on hibernate 3.0. In A's parent pom I have defined hibernate dependency in dependency-management section with version 3.1, but spring is not defined there. Spring is defined in A's pom (with version 3.0). Dependency resolution in maven for project A would result in fetching spring 3.0 and hibernate 3.1 - because despite fact that spring 3.0 depends on hibernate 3.0, dependency-management of A's parent pom overrides hibernate version, so 3.1 would be used instead.
Is there way of defining something similar in gradle? Note that I didn't have to specify hibernate in A's pom specificly and also it is not specified as dependency in A's parent pom - it is only in dependency-management section of A's parent pom.
The io.spring.dependency-management plugin allows you to use a Maven bom to control your build's dependencies:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:0.5.3.RELEASE"
}
}
apply plugin: "io.spring.dependency-management"
Next, you can use it to import a Maven bom:
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:1.1.4.RELEASE'
}
}
Now, you can import dependencies without specifying a version number:
dependencies {
compile 'org.springframework:spring-orm'
compile 'org.hibernate:hibernate-core'
}