Maven dependency BOM camel-spring-boot-bom not working with Gradle - spring-boot

I'm trying to get the Apache Camel Spring Boot BOM working. However, it does neither work by
specifying it as a dependency with
dependencies {
implementation platform("org.apache.camel.springboot:camel-spring-boot-bom:${camelVersion}")
.
.
.
}
or
dependencies {
implementation "org.apache.camel.springboot:camel-spring-boot-bom:${camelVersion}"
.
.
.
}
Nor by using the dependencyManagement imports alongside other that are working
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
mavenBom "org.junit:junit-bom:${junitVersion}"
mavenBom "org.apache.camel:camel-bom:${camelVersion}"
mavenBom "io.github.openfeign:feign-bom:${feignVersion}"
mavenBom "org.apache.camel.springboot:camel-spring-boot-bom:${camelVersion}"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
together with the actual dependencies (without versions specified explicitly)
implementation "org.apache.camel.springboot:camel-csv-starter"
implementation "org.apache.camel.springboot:camel-rest-starter"
implementation "org.apache.camel.springboot:camel-seda-starter"
implementation "org.apache.camel.springboot:camel-direct-starter"
implementation "org.apache.camel.springboot:camel-jackson-starter"
implementation "org.apache.camel.springboot:camel-servlet-starter"
implementation "org.apache.camel.springboot:camel-zipfile-starter"
implementation "org.apache.camel.springboot:camel-resilience4j-starter"
implementation "org.apache.camel.springboot:camel-rest-openapi-starter"
implementation "org.apache.camel.springboot:camel-platform-http-starter"
implementation "org.apache.camel.springboot:camel-spring-boot-starter"
implementation "org.apache.camel.springboot:camel-platform-http-starter"
implementation "org.apache.camel.springboot:camel-spring-boot-dependencies"
and in both ways I'm getting
> Could not resolve all dependencies for configuration ':my-project:compileClasspath'.
The project declares repositories, effectively ignoring the repositories you have declared in the settings.
You can figure out how project repositories are declared by configuring your build to fail on project repositories.
See https://docs.gradle.org/7.5.1/userguide/declaring_repositories.html#sub:fail_build_on_project_repositories for details.
> Could not find org.apache.camel.springboot:camel-spring-boot-dependencies:.
Required by:
project :my-project
while directly using version numbers in individual dependencies like
dependencies {
implementation "org.apache.camel.springboot:camel-spring-boot-starter:${camelVersion}"
}
is perfectly working.
Why does it seem the Spring Boot Camel BOM is working "differently" than the other dependencies and how do I get it working?

The bom 'dependency' is actually just a reference for which version to use for any dependency you bring in within dependencies{ } specified in the bom (including transitive).
So for example:
dependencies {
implementation "org.apache.camel.springboot:camel-spring-boot-starter"
}
dependencyManagement {
imports {
mavenBom "org.apache.camel.springboot:camel-spring-boot-bom:${camelVersion}"
}
This code above if you see, camel-spring-boot-starter does not have a version specified to it, but it is still able to resolve because the version is specified within the bom file of camel-spring-boot-bom:${camelVersion}.
And just in case for reference here you can find the dependencies and the version your dependencies will resolve with, for example version 3.20.0 of bom: https://mvnrepository.com/artifact/org.apache.camel.springboot/camel-spring-boot-bom/3.20.0

I mistakenly had a second BOM org.apache.camel.springboot:camel-spring-boot-dependencies listed as a dependency, which caused the problem when I was removing the version number.
I've removed that from the dependencies now and used it as the BOM, as it fits my needs better.
According to the docs:
There is a curated camel-spring-boot-dependencies which is a generated
BOM that has adjusted the JARs that both Spring Boot and Apache Camel
may use to use single shared version that will not conflict. This BOM
is what is used to test camel-spring-boot itself. However Spring Boot
users may want to use pure Camel dependencies and hence why you can
use camel-spring-boot-bom that only has the Camel starter JARs as
managed dependencies. This may lead to a classpath conflict if a 3rd
party JAR from Spring Boot is not compatible with a Camel component.
https://camel.apache.org/camel-spring-boot/3.19.x/index.html#_camel_spring_boot_bom_vs_camel_spring_boot_dependencies_bom

Related

Is io.spring.dependency-management plugin required when using Spring Boot 2.3+ and Spring Cloud?

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

How to access version property from BOM with Gradle?

I'm migrating a small multi-module project from Maven to Gradle, to evaluate and (hopefully) to learn something.
subprojects {
group = "com.company.project-name"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
implementation platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
}
}
This is what I have so far. Despite a small problem it's already working. As you can see, I'm importing org.springframework.boot:spring-boot-dependencies as platform dependency / BOM (Bill of Materials). As far as I understand this is equivalent to a Maven parent. spring-boot-dependencies already defines almost everything I'm using in this project. However, I'm also using Lombok. Luckily Spring takes care of that too.
This work as expected for the compileOnly dependency org.projectlombok:lombok. The problem is the annotationProcessor. Compiling the project results in an error:
[...]
Execution failed for task [...].
> Could not resolve all files for configuration [...].
> Could not find org.projectlombok:lombok:.
Required by:
project [...]
[...]
If I change it to something like this:
annotationProcessor("org.projectlombok:lombok:1.18.20")
... it works. But I want Gradle to use the version definition for Lombok from spring-boot-dependencies, because I don't want to define it again myself. With Maven I could just use the Maven property lombok.version. So I also tried something like this:
annotationProcessor("org.projectlombok:lombok:${lombok.version}")
Unfortunately, this result in another error:
A problem occurred evaluating root project [...].
> Could not get unknown property 'lombok' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
What is the Gradle equivalent to access a defined version property from a platform dependency / BOM?
Have you tried this:
annotationProcessor platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
Make sure the annotationProcessor is on the top of the dependencies.
dependencies {
annotationProcessor platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
annotationProcessor("org.projectlombok:lombok")
implementation platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
compileOnly("org.projectlombok:lombok")
}

Spring-boot BOM does not contain a dependency for tomcat-dbcp

Spring-boot BOM does not contain a dependency for tomcat-dbcp.
I have a Spring MVC project where I use a database connection pool for Hibernate ORM connections. This project is deployed in Tomcat. In my IntelliJ Idea development environment I use Tomcat embedded, by using the spring-boot-starter-tomcat. But the spring-boot-starter-tomcat does not define a dependency to tomcat-dbcp. Hence I decided to explicitly define a dependency to tomcat-dbcp in my build.gradle.kts file.
I had hoped that the Spring-boot BOM would have contained tomcat-dbcp, so that I would not need to specify it's version number and rely on the Spring Boot dependency management system to handle it's version number for me. But the Spring-boot BOM does not contain a dependency for tomcat-dbcp. Can Spring-Boot add it?
I came up with the following hack so as to not hard code the version number for tomcat-dbcp. Just added the following code to the build.gradle.kts file after dependencies section.
configurations.all {
resolutionStrategy.eachDependency {
if (requested.group == "org.apache.tomcat.embed" && requested.name == "tomcat-embed-core") {
dependencies {
providedRuntime("org.apache.tomcat", "tomcat-dbcp", requested.version) //to use tomcat connection pool in tomcat embedded mode.
}
}
}
}

Gradle: Compile Dependencies

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.

maven parent pom dependency-management in gradle

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'
}

Resources