How to disable DataSourceHealthIndicator bean in Spring Boot? - java

I have application with spring-boot-starter-actuator dependency. When I add my error handling library as dependency, application fails to start with the following message
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
After a bit research, I found out the error handling library introduces transitive dependency of spring-boot-starter-data-jpa which in turn causes actuator autoconfiguration to automatically introduce DataSourceHealthIndicator bean. This bean fails on missing database connection, but the application actually doesn't use database at all. However, the logging library requires the JPA dependency at runtime, so I can't exclude it.
I tried to set the following application property: management.health.db.enabled=false, but I still get the same error on startup. I can't find any documentation how to disable DataSourceHealthIndicator bean and leaving other autoconfiguration intact.

Related

Spring dependency injection not finding repository bean after adding spring-boot-starter-data-redis dependency

I have this spring boot project (version 2.3.3.RELEASE) that uses Spring Webflux and Spring Data and R2DBC. It was working fine until I added the following dependency:
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
After this, Spring can't start because it can't resolve the dependency for this object:
interface BookingCountRepository : ReactiveCrudRepository<BookingCount, String> {
...
}
The error message is the following:
2021-12-22 10:20:59,916 [main] ERROR [] o.s.b.d.LoggingFailureAnalysisReporter - __***************************_APPLICATION FAILED TO START_***************************__Description:__Parameter 1 of constructor in xx.xx.xx.xx.BookingService required a bean of type 'xx.xx.xx.xx.BookingCountRepository' that could not be found.___Action:__Consider defining a bean of type 'xx.xx.xx.xx.BookingCountRepository' in your configuration._
If I remove the spring-boot-starter-data-redis dependency, the problem stops happening.
My hunch is that it's probably a dependency hell issue, with a conflict between org.springframework.boot:spring-boot-starter-data-r2dbc and org.springframework.boot:spring-boot-starter-data-redis. But I don't know for sure.
Did anyone have trouble with this? If you did, how did you solve this problem?
FYI: JVM Runtime is OpenJDK 11, language is Kotlin, and spring boot version is 2.3.3.RELEASE
I was able to find a solution, therefore I'm posting here, since others may face the same problem.
The cause of the problem is that multiple spring data modules (r2dbc and redis) were being used in the same project. Since ReactiveCrudRepository is a generic interface that can be assigned to both Redis and R2DBC, something must be done to ensure Spring DI loads the correct spring data modules.
The solution, in this case, is making BookingCountRepository inherit directly from R2dbcRepository:
interface BookingCountRepository : R2dbcRepository<BookingCount, String> {
...
}
After that, everything will work correctly.
More information in the docs:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.multiple-modules
Note: Some approaches, like informing basePackages in the #EnableR2dbcRepositories annotations didn't work.

Spring Boot mongoTemplate not found

I have Spring Boot app that creates a RESTful API. It wants to automatically connect to port 27017, I believe because it contains a transitive dependency to MongoDB.
But I don't want it to auto-connect to MongoDB because that server may not yet have started, thus throwing an error.
So I exclude the Mongo AutoConfiguration classes from the app like so:
#SpringBootApplication(exclude = {
MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class
})
But then I get this error:
Parameter 0 of constructor in com.whatev.MyLogImpl required a bean named 'mongoTemplate' that could not be found.
Why does it need an mongoTemplate when I'm excluding Mongo AutoConfiguration?
But nonetheless, I then added a new #Configuration class containing MongoTemplate, but I get:
Parameter 0 of constructor in com.whatevz.MongoFileService required a bean of type 'org.springframework.data.mongodb.gridfs.GridFsTemplate' that could not be found.
- Bean method 'gridFsTemplate' not loaded because auto-configuration 'MongoDataAutoConfiguration' was excluded
True, I excluded the MongoDataAutoConfiguration class. But I don't want to also exclude gridFsTemplate if that's gonna cause a problem. Sheesh.
All I want to do is not see an error when I start my app if MongoDB is not yet running.

CGLIB errors converting a weblogic spring web app to springboot app

I am attempting to convert an existing spring weblogic application to a spring boot embedded tomcat application.
There are lots of moving parts so it's hard to show any code, I'm hoping there is some general answer that might clue me in to the issue.
Under weblogic, using the spring-framework 4.3.6.RELEASE libraries, the application deploys fine. It has no problems creating the different service, repository and component beans.
However, when I migrate it to Spring Boot 1.5.1.RELEASE, I get the following error:
2017-06-21 17:08:16,402 [ERROR] SpringApplication reportFailure (815) - Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'alertEventServiceImpl': Unsatisfied dependency expressed through field 'alertEventDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'alertEventDaoImpl' defined in URL [jar:file:/Users/username/Development/source/carma-war/target/carma-war-2.0.0-SNAPSHOT.war!/WEB-INF/lib/protocol-manager-1.8.0-SNAPSHOT.jar!/org/ihc/hwcir/protocol/dao/AlertEventDaoImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl
Many of our service classes are final as they shouldn't be extended. Since there are so many that are final, I wanted to minimize the amount of code in our different libraries that we modify to make this work.
I thought because the bean creation process works under weblogic, it should work under spring boot.
Things I have tried to force not using the cglib proxies:
All implementations implement interfaces already
In beans created via xml, added <aop:scoped-proxy proxy-target-class="false"/>
In beans created through annotations, added (example for service bean)
#Service
#Scope(proxyMode = ScopedProxyMode.INTERFACE)
However, in the end, I'm perplexed as to why spring can create beans (the classes marked as final) under the weblogic container but unable to do so under the embedded tomcat spring-boot container.
Spring Boot by default uses class based proxies, which will not work with final classes/methods.
To disable this add spring.aop.proxy-target-class=false to the application.properties to enable JDK Dynamic Proxies instead of class based proxies. (And revert your modifications).
NOTE: To have everything take into account the spring.aop.proxy-target-class you might need to upgrade to Spring Boot 1.5.3 as some final patches where made to include this property in parts that were missed in previous versions.
See the following issues for more information 8434, 8869 and 8887.
I was unable to make this work using M. Deinums' answer using spring.aop.proxy-target-class=false.
What worked for me was to add in the application.properties file
spring.dao.exceptiontranslation.enabled=false
Please note that this option disables proxy creation for repositories.
And in my spring boot application configurer the annotation to handle transactions without using a proxy class.
#EnableTransactionManagement(proxyTargetClass = false)
This is using Spring Boot version 1.5.1.RELEASE.

Does Spring Boot automatically resolve message keys in javax and hibernate validation annotations

I was writing a Spring Boot Application. I wanted to know does Spring Boot automatically resolve message keys in javax and hibernate validation annotations. For example:
#NotEmpty(message = "${message.key}")
String name;
I have provided #PropertySource in my application with message properties file and file is also in my classpath. The keys are resolving with #Value but they are not being resolved in validation annotations.
What could be the reason for this?
Do I need configure a message source bean? Because I have seen examples working without configuring the message source bean.
Are your messages in the correct place? Spring Boot automatically registers a MessageSource bean for you, so you should put your messages in the src/main/resources/messages.properties file. If you have enabled the auto-configuration and also have hibernate-validator dependency on the classpath, everything should work out of the box.
Also #PropertySource is related to application's configuration properties and not messages so the fact that it's not resolving them is to be expected ^^

Disable transaction manager in Spring Boot application

How to disable transaction manager in Spring Boot application?
I have this exception :
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined
Because of #Transactional annotations (I use these annotations in an other app, so I can't remove, but there is a way to ignore it? By disable transaction manager?).
I guess you have three choices:
remove the annotation
supply a transaction manager
exclude the configuration class that adds #EnableTransactionManagement
In a Spring Boot app you only get #EnableTransactionManagement if you are using JDBC or JPA, so really there should be a transaction manager already. The only reason I can see for one not being there is you have spring-jdbc on the classpath but no database. If you have spring-tx and spring-jdbc on your classpath already (which seems to be the case) you can just add an in-memory database (e.g. h2) to get a transaction manager. That seems like the best solution to me. But you could also exclude DataSourceTransactionManagerAutoConfiguration in your #EnableAutoConfiguration.

Categories

Resources