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

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

Related

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

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

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 use JPA metamodel with gradle, intellij IDEA?

I am using java 8, spring boot 2.0.0, spring-data-jpa(spring-boot-starter-data-jpa), gradle, intellij. I've been trying to use JPA Metamodel, but having difficulty on finding how to configure.
Metamodels for Entity classes aren't just generated.
I guessed it would be simple, but now it seems that can be wrong. How can I use it?
JDK11 / Gradle 5.0 / Hibernate 5.3.7.Final
sourceSets.main.java.srcDirs += "${buildDir}/generated"
compileJava {
options.annotationProcessorGeneratedSourcesDirectory = file("${buildDir}/generated")
}
dependencies {
annotationProcessor("javax.xml.bind:jaxb-api")
annotationProcessor("org.hibernate:hibernate-jpamodelgen")
}
Generated Metamodel classes will be generated at 'build/generated'
If you are using JDK8 or Hibernate 5.4+, annotationProcessor("javax.xml.bind:jaxb-api") may unnecessary.
I did this the other day using the scalified metamodel gradle plugin (https://plugins.gradle.org/plugin/com.scalified.plugins.gradle.metamodel). I'm using Spring Boot 2.0.5, but I don't see why it wouldn't work the same with Spring Boot 2.0.0. I'm using Gradle 4.8.1 as well.
Below is an excerpt of my build.gradle.
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath (
"org.springframework.boot:spring-boot-gradle-plugin:2.0.0",
"gradle.plugin.com.scalified.plugins.gradle:metamodel:0.0.1");
}
}
apply plugin: "com.scalified.plugins.gradle.metamodel"
// The plugin will default to the latest version of Hibernate if this is not specified
metamodel {
hibernateVersion = '5.2.14.Final' // For Spring Boot 2.0.0
hibernateVersion = '5.2.17.Final' // For Spring Boot 2.0.5
}
This builds the metamodal files under src/generated and they can be used in your code. I had to also change an IntelliJ setting because IntelliJ's Build Automatically excludes some Gradle tasks that could be long running. See Automatically run Gradle task in project build with IntelliJ IDEA and https://youtrack.jetbrains.com/issue/IDEA-175165 for more details.
This setting I changed to overcome this is: Preferences->Build/Execution/Deployment->Gradle->Runner->Delegate IDE build/run actions to Gradle. An alternative would be to run the metamodelCompile gradle task manually as needed. That would lessen the time to rebuild by a little if you aren't frequently change your entities.

error when upgrading Spring Boot version in Vaadin Gradle project

I have a Gradle project that uses Spring Boot + Vaadin.
The Gradle plugins for Spring Boot and Vaadin configured as follows:
buildscript {
ext {
springBootVersion = '1.3.7.RELEASE'
}
...
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "fi.jasoft.plugin:gradle-vaadin-plugin:0.11.1"
}
}
The Vaadin version is specified as follows:
vaadin {
version '7.6.8'
widgetset 'com.vaadin.DefaultWidgetSet'
}
Vaadin dependencies are specified as follows:
dependencies {
compile 'com.vaadin:vaadin-spring-boot-starter:1.0.0'
compile 'com.vaadin:vaadin-server:${vaadin.version}'
compile 'com.vaadin:vaadin-client:${vaadin.version}'
...
}
This works fine, but as soon as I change the Spring Boot version to
springBootVersion = '1.4.0.RELEASE'
then I get the error:
Illegal character in path at index 89:
https://oss.sonatype.org/content/repositories/vaadin-snapshots/com/vaadin/vaadin-server/${vaadin.version}/vaadin-server-${vaadin.version}.pom
Update
Groovy (which Gradle uses) supports String interpolation only when using double quotes (") so changing the Vaadin dependencies to
dependencies {
compile "com.vaadin:vaadin-spring-boot-starter:1.0.0"
compile "com.vaadin:vaadin-server:${vaadin.version}"
compile "com.vaadin:vaadin-client:${vaadin.version}"
...
}
fixes it. Now the real question is why the single quotes work fine if I downgrade Spring Boot to 1.3.7-RELEASE.
If you are using a recent Spring Boot version you should upgrade your Gradle Vaadin plugin. Recent versions of the plugin has much better support for Spring Boot.
Here is a guide to get you started https://github.com/johndevs/gradle-vaadin-plugin/wiki/Creating-a-Spring-Boot-Project

How to exclude jersey 1.x dependencies when running tests with gradle

We have a web service project that relies on Netflix's Eureka and it has a dependency on Jersey client 1.x.
Our project is using gradle and in the project we have our src, unit, integration, and functional tests. For our functional tests we have a jar that we import in the testCompile gradle section that wraps a Jersey client to send requests to the web service.
Now my question is how can I get the netflix Jersey client dependency to be ignored in the testCompile so I can use the new Jersey 2.x client for the functional tests?
Build Scripts below:
Main service build script excerpt:
dependencies {
compile 'com.netflix.eureka:eureka-client:1.1.97'
compile 'com.sun.jersey:jersey-bundle:1.18'
testCompile 'some.domain:service-test-client:1.0.1'
}
service test client relevant parts:
dependencies {
compile 'org.glassfish.jersey.core:jersey-client:2.19'
compile 'org.glassfish.jersey.connectors:jeresey-apache-connector:2.19'
}
Relevant parts of the Eureka Client gradle script from github:
ext {
githubProjectName = 'eureka'
awsVersion='1.9.3'
servletVersion='2.5'
jerseyVersion='1.11'
governatorVersion='1.3.3'
archaiusVersion='0.6.5'
blitzVersion='1.34'
mockitoVersion='1.9.5'
junit_version='4.10'
mockserverVersion='3.9.2'
jetty_version='7.2.0.v20101020'
}
dependencies {
compile "com.sun.jersey:jersey-core:$jerseyVersion"
compile "com.sun.jersey:jersey-client:$jerseyVersion"
compile 'com.sun.jersey.contribs:jersey-apache-client4:1.11'
compile 'org.apache.httpcomponents:httpclient:4.2.1'
}
With the above setup I get method not found errors because when the tests are running some of the jersey 1.x classes are taking precedence over the classes brought in with the test-client jar.
You can use gradle dependency monitoring to find out what libraries are bringing in jersey.
./gradlew dependencies
You can pipe that into a file, and less your way into finding out who's bringing in jersey 1.*.
Then, just exclude it from those specifically, and compile your own:
compile("com.example.library:artifactId:x.y.z"){
exclude group:'org.glassfish.jersey', module:jersey-common
}
compile('org.glassfish.jersey.core:jersey-common:2.4.1')
I got same problem with jersey 1.x vs glassfish 2.x with Eureka (but with Spring Cloud). I'm trying this:
compile ("org.springframework.cloud:spring-cloud-starter-eureka:1.0.0.RELEASE")
{
exclude group:'com.sun.jersey', module: 'jsr311-api'
}
But then Eureka doesn't work for me...
I think I will try to switch to Eureka 2.0 with different jersey, but without spring cloud:
https://github.com/Netflix/eureka/wiki/Eureka-2.0-Architecture-Overview
http://mvnrepository.com/artifact/com.netflix.eureka check Eureka2 dependencies
maybe you can use them?

Resources