Spring Boot 1.5 #JdbcTest failing when using Eureka Discovery - spring-boot

I'm trying to use the new #JdbcTest annotation in Spring boot 1.5.0.RC1.
My app uses Eureka discovery ie I have
compile('org.springframework.cloud:spring-cloud-starter-eureka')
in my build.gradle and
#EnableDiscoveryClient
on my main Spring Boot class
When I try to use #JdbcTest to test a JdbcTemplate based DAO I get this error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method eurekaHealthIndicator in org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration$EurekaHealthIndicatorConfiguration required a bean of type 'com.netflix.discovery.EurekaClient' that could not be found.
Action:
Consider defining a bean of type 'com.netflix.discovery.EurekaClient' in your configuration.
It looks like the auto configuration is loading part of the Eureka configuration when it should only load JDBC related beans.
If I add
#TestPropertySource(properties={"eureka.client.enabled=false"})
to the test the problem goes away, but I think #JdbcTest should be making sure already that only relevant beans are loaded.
Am I missing something or is this a problem with the new #JdbcTest, or maybe Spring Cloud Eureka?

Your #SpringBootApplication has # EnableDiscoveryClient on it. When you use a slice annotation (such as #JdbcTest), Spring Boot finds the context to use by looking at the package of your test for a #SpringBootConfiguration. If it does not find one, it looks in the parent package, etc. With a sensible package structure and no further customization, your tests use your #SpringBootApplication as the root context.
So, that configuration class (and only that one) is processed an #EnableDiscoveryClient is also obviously processed. In your case, this has an additional side effect: every single test now requires the Eureka Client.
TL;DR never put such annotation on your application. And only put it if you actually need it. You could define a #Configuration class next to your Spring Boot app for those.

#David
I had similar issue and fixed by adding the following to my application.yml file
eureka:
client:
enabled: false

Related

Is an explicit CacheManager bean definition mandatory when using Spring Boot + Spring Cache?

From documentation Spring Boot uses ConcurrentMapCacheManager as CacheManager implementation by default if we don't define own CacheManager bean definition. But I keep getting 'No qualifying bean of type 'org.springframework.cache.CacheManager' available' error eventhough spring-boot-starter-cache and #EnableCaching is there.
Any help would be greatly appreciated.
Best regards,
SetNug
Short answer... NO.
I suspect you are having problems while (integration) testing? If so, then you probably need to declare the appropriate "test slice annotation", that is #AutoConfigureCache; see Javadoc.
To demonstrate, I created a simple example with a test class contained in this module of my SO repository. You must declare the #AutoConfigureCache annotation in configuration (see here) even if your test is a #SpringBootTest.
As Spring Boot's documentation describes, all of Spring Boot's auto-configuration (which is quite extensive) can be a bit much for testing. As such, none of Spring Boot's auto-configuration is enabled by default. Therefore, you must explicitly enable what you want, or, alternatively, you can declare that you want Spring Boot's entire auto-configuration enabled, by replacing the #AutoConfigureCache annotation declaration with Spring Boot's #EnableAutoConfiguration annotation instead.
You are correct that Spring Boot will auto-configure a "Simple" caching provider (i.e. the ConcurrentMapCacheManager, or in other words, a Spring CacheManager implementation backed by a java.util.concurent.ConcurrentHashMap; see here) when no other cache provider implementation (e.g Redis) is present or explicitly declared.
However, Spring Boot auto-configuration is only in effect when your Spring Boot application is an "application", which I have shown here.
Of course, it is also true that if your #SpringBootApplication annotated class is found (in the classpath component-scan) by your test as described, then it will also enable caching without any explicit annotations, such as, no need to explicitly declare the #AutoConfigureCache test slice annotation, even.
NOTE: In my example, I deliberately did not package the source according to the suggested structure. So, if I were to replace the #AutoConfigureCache annotation declaration in my test configuration with #Import(SpringBootDefaultCachingApplication.class) and comment out this assertion from the application class, then the test would also pass. Using the #Import annotation in this way works similarly as if the test class and application class were in the same package, or the application class were in a parent package relative to the test class.
1 last tip... you can always enable Spring Boot debugging (see Baeldung's blog) to see what auto-configuration is applied while running your application, or even while running tests.

Implementation provided for BatchConfigurer is not connsidered when using #EnableBatchProcessing(modular=true)

I am developing a sample application that Spring Batch with Spring Boot. My requirement is:
Have my own implementation of BasicBatchConfigurer so that I can configure AsyncTaskExecutor and my own dataSource as I am using SAP HANA as DB for which databaseType is not supported.
I want to use #EnableBatchProcessing(modular=true) so that I can register multiple jobs and launch them with separate Child Context
I have added all the required configurations. Without setting modular=true the Job is Launched and works as expected. It initializes the beans defined from my implementation of BasicBatchConfigurer.
However, once modular=true is set, the beans from my implementation are not initialized.
The code is hosted here: https://github.com/VKJEY/spring-framework-evaluation
I debugged further into the issue:
Looks like, When we set modular=true, BatchConfigurationSelector uses ModularBatchConfiguration
In ModularBatchConfiguration, there's a field Collection<BatchConfigurer> configurers. This has been annotated as #autowired.
I assume that this field is auto initialized if I provided a implementation
of BatchConfigurer as it has been mentioned in the comments of ModularBatchConfiguration class as well
However, While debugging I realized that the above field is still null beacuse of which, It loads DefaultBatchConfigurer and follows the default flow.
My question is why is that field configurers not being initialized in ModularBatchConfiguration? Am I missing something?
I am using Spring boot 2.1.2.
My question is why is that field configurers not being initialized in ModularBatchConfiguration? Am I missing something?
You are hitting a lifecycle issue between Spring Boot custom auto-configuration that you defined in the META-INF/spring.factories file and Spring Batch configuration.
I debugged your code and here is how to fix the issue:
remove org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.job.data.persistence.config.AsyncBatchConfigurer
from META-INF/spring.factories file. This is not needed as Spring Batch
will detect the AsyncBatchConfigurer when it is declared as a bean.
You can even remove this spring.factories file
remove #ConditionalOnMissingBean(BatchConfigurer.class) from AsyncBatchConfigurer:
Since you declared this class as a #Configuration class, it will also be defined as a bean of type BatchConfigurer and will be detected by ModularBatchConfiguration
With these two changes, the field configurers in ModularBatchConfiguration is correctly autowired with your AsyncBatchConfigurer.
As a side note, you don't need the AsyncBatchConfigurer#configurers method as Spring will do the work of injecting all BatchConfigurer beans in ModularBatchConfiguration.
Hope this helps.

Can I start with a spring boot application without the annotations componentscan,autoconfiguration,configuration,springbootapplication?

I have written some code in order test integration with mongoDB. Please find the link to the main method for running this spring boot application below,
https://github.com/siva54/simpleusercontrol/blob/master/src/main/java/com/siva/UserManagementApplication.java
From what I have read, An application should contain any of the configurations from the following URL to declare how the applications manages the context,
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/using-boot-using-springbootapplication-annotation.html
I haven't used any of those contexts, However my application works fine and I'm able to run it without any issues. Am I missing something here? Can you please help with the info of how my application is able to start and manage the context/dependencies automatically?
Thanks in advance
#SpringBootApplication is equivalent of #Configuration, #EnableAutoConfiguration and #ComponentScan. Let's consider why your application works without of any of this three annotations.
Why it works without #Configuration:
When Spring will scan packages, it will find all classes marked by #Configuration and will use them as part of configuration. But in next line you manually passed UserManagementApplication as configuration source:
SpringApplication.run(UserManagementApplication.class, args);
So spring doesn't need to find this class by scan. Therefor it is not necessary to mark it by #Configuration.
Why it works without #ComponentScan:
Class UserManagementApplication has #ImportResource("classpath:spring/application-context.xml") annotation. That means file spring/application-context.xml will be included into configuration. And this file contains next line:
<context:component-scan base-package="com.siva.*" />
So, you don't need use annotation for scan packages, because you already declared it in the xml file.
Why it works without #EnableAutoConfiguration:
This annotation allows to Spring to try guess and configure the components automatically. For example, if you include the following dependency in your build.gradle:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
Spring configures all the components required to work with MongoDB automatically. And all you need just specify host and user/pass in the aplication.proprties file.
But you preferred to declare all needed beans manually in the spring/application-context.xml file. So, you simply don't need #EnableAutoConfiguration annotation at all.

Using #ConfigurationProperties in Spring Boot Application doesn't work

I am using Spring Boot V 1.4.1 for a new application.
My app requires two JDBC data sources and I was following the example at http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources how to set it up.
My Spring beans configuration class is annotated with #EnableConfigurationProperties and my first bean is defined as
#Primary
#Bean
#ConfigurationProperties(prefix = "first.database")
DataSource qivsDB() {
return DataSourceBuilder.create().build();
}
, the second one accordingly. My application.properties file has properties defined like
first.database.url=jdbc:[redacted]
first.database.username=[redacted]
first.database.password=[redacted]
For reasons I not transparent to me during debugging this is failing to initialize: Cannot determine embedded database driver class for database type NONE - debug showed me that the builder does not have any properties set when calling build().
What did I miss here?
Before you do all the debugging part, you should have a look to the auto-configuration report. If you define your own DataSource there's no reason for Spring Boot to start looking at what it can do for your app. So, for some reasons, that definition of yours is not applied in your app and the default in Spring Boot still applies, doesn't find any JDBC url in the default namespace and attempt to start an embedded database. You should see in the auto-config report that the DataSourceAutoConfiguration still matches.
I am not sure the public keyword has anything to do with it, though you won't get custom meta-data for that key since we only scan for public methods.

spring-boot without #SpringBootApplication

I am attempting to migrate a spring, non-boot, app to a boot app. The current one builds a war file. Following these instructions, I am walking through the steps to migrate.
I am finding that the #SpringBootApplication annotation forces a lot of things to fail. For instance, it tries to auto config security when I really need the existing xml security config to remain as is. I found that I can override #EnableAutoConfiguration and exclude configuration classes (.i.e. SecurityAutoConfiguration.class). But I am finding it is doing this a great deal for the items I already have on my classpath. I decided it would be better to remove #SpringBootApplication and replace it with just #Configuration, #ComponentScan and #ImportResource to load my original context xml. The class extends SpringBootServletInitializer so that I can register my custom servlets and filters.
What I have found, it now no longer knows to load the application.yml or bootstrap.yml. What triggers auto configuration of these files? Do I fall back to loading with the traditional properties placeholder configurers? I want to avoid this as the next step is to hook it up to spring cloud config to centralize the management of the application configuration.
#SpringBootApplication is a alternative for #Configuration, #EnableAutoConfiguration and #ComponentScan.
Probably you want use #Configuration + #ComponentScan. If you want load xml configuration you can use: #ImportResource annotation.
If you want use autoconfiguration, but you can disable a few auto configurations, eg:
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
Details:
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-configuration-classes.html
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html

Resources