Spring boot + spring boot security start error - java

I'm doing a MVC project with spring boot and spring security and jsp. I'm just training my spring and I have the same project running without spring boot. Currently I moved to springboot and when I try to start I get :
2020-05-09 17:28:38.521 INFO 21308 --- [ restartedMain]
o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring
embedded WebApplicationContext 2020-05-09 17:28:38.527 INFO 21308 ---
[ restartedMain] o.s.web.context.ContextLoader : Root
WebApplicationContext: initialization completed in 6813 ms 2020-05-09
17:28:38.753 WARN 21308 --- [ restartedMain]
ConfigServletWebServerApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'inMemoryDatabaseShutdownExecutor'
defined in class path resource
[org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.class]:
Unsatisfied dependency expressed through method
'inMemoryDatabaseShutdownExecutor' parameter 0; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource' defined in class path resource
[org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method
'dataSource' threw exception; nested exception is
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException:
Failed to determine a suitable driver class 2020-05-09 17:28:38.769
INFO 21308 --- [ restartedMain]
o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2020-05-09 17:28:38.826 INFO 21308 --- [ restartedMain]
ConditionEvaluationReportLoggingListener :
*************************** APPLICATION FAILED TO START
Description:
Failed to configure a DataSource: 'url' attribute is not specified and
no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
I have no idea what is happening.
application.properties
# JDBC properties
#
app.datasource.url=jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimezone=UTC
app.datasource.username=springstudent
app.datasource.password=springstudent
# Spring Data JPA properties
spring.data.jpa.repository.packages=com.crm.dao
spring.data.jpa.entity.packages-to-scan=com.crm.beans
#
# SECURITY JDBC properties
#
security.datasource.jdbc-url=jdbc:mysql://localhost:3306/spring_security_demo_bcrypt?useSSL=false&serverTimezone=UTC
security.datasource.username=springstudent
security.datasource.password=springstudent
security.datasource.driver-class-name= com.mysql.jdbc.Driver
Configuration:
#Configuration
#EnableWebSecurity
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter {
// add a reference to our security data source
#Autowired
#Qualifier("securityDataSource")
private DataSource securityDataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(securityDataSource);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("aplicando configuracion");
http.authorizeRequests()
.antMatchers("/employees/showForm*").hasAnyRole("MANAGER", "ADMIN")
.antMatchers("/employees/save*").hasAnyRole("MANAGER", "ADMIN")
.antMatchers("/employees/delete").hasRole("ADMIN")
.antMatchers("/employees/**").hasRole("EMPLOYEE")
.antMatchers("/resources/**").permitAll()
.antMatchers("/showMyLoginPage").permitAll()
.and()
.formLogin()
.loginPage("/showMyLoginPage")
.loginProcessingUrl("/authenticateTheUser")
.permitAll()
.and()
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
}
Configuration:
#Configuration
#EnableJpaRepositories(basePackages={"${spring.data.jpa.repository.packages}"})
public class DemoDataSourceConfig {
#Primary
#Bean
#ConfigurationProperties(prefix="app.datasource")
public DataSource appDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="spring.data.jpa.entity")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, DataSource appDataSource) {
return builder
.dataSource(appDataSource)
.build();
}
#Bean
#ConfigurationProperties(prefix="security.datasource")
public DataSource securityDataSource() {
return DataSourceBuilder.create().build();
}
}
Thanks for your help in advance.

In your properties file...
Change app.datasource.* to spring.datasource.* like below..
# JDBC properties
#
spring.datasource.url=jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimezone=UTC
spring.datasource.username=springstudent
spring.datasource.password=springstudent
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
This error message gives hint that when Soring looks for database URL property.. (they have a fixed property name for it.. like spring.datasource.*) Or Else.. if you are using any embedded database like DB2 then it does not require any url/username/password only the dependency is enough.
In your case, it's not embedded database.. so the property name spring looks for, must be provided correctly.

Related

datadog.apiKey was 'null' but it is required

I am currently using spring boot 2.7.0-M1 and following is my dependencies in build.gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.boot:spring-boot-starter-cache'
compileOnly 'org.projectlombok:lombok'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'io.micrometer:micrometer-registry-datadog:latest.release'
datadogagent("com.datadoghq:dd-java-agent:$datadoghq_dd_version")
implementation("com.datadoghq:dd-trace-api:${datadoghq_dd_version}")
However, when i try to set micrometer bean:
#Configuration
public class MeterRegistryConfig {
#Bean
MeterRegistry meterRegistry(ApplicationContext context) {
DatadogConfig config = new DatadogConfig() {
#Override
public Duration step() {
return Duration.ofSeconds(10);
}
#Override
public String get(String k) {
return null; // accept the rest of the defaults
}
};
return new DatadogMeterRegistry(config, Clock.SYSTEM);
}
}
I am getting a startup error:
2022-02-05 05:07:56.457 ERROR 7897 --- [ restartedMain] o.s.b.web.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webMvcMetricsFilter' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfiguration.class]: Unsatisfied dependency expressed through method 'webMvcMetricsFilter' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'compositeMeterRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryConfiguration.class]: Unsatisfied dependency expressed through method 'compositeMeterRegistry' parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'meterRegistry' defined in class path resource [com/hbomax/ml/mlsvc/config/MeterRegistryConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.micrometer.core.instrument.MeterRegistry]: Factory method 'meterRegistry' threw exception; nested exception is io.micrometer.core.instrument.config.validate.ValidationException: datadog.apiKey was 'null' but it is required
2022-02-05 05:07:56.504 INFO 7897 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2022-02-05 05:07:56.520 WARN 7897 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
2022-02-05 05:07:56.541 INFO 7897 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Here's my application.yaml:
management:
info:
git:
mode: full
metrics:
distribution:
percentiles:
http:
server:
requests: 0.5, 0.95, 0.99
percentiles-histogram:
http:
server:
requests: true
sla:
http:
server:
requests: 200ms, 400ms, 600ms
export:
datadog:
step: 30s
enabled: true
api-key: xxxxxxx
tags:
application: ${spring.application.name}
env: ${spring.profiles}
Can someone help me understand what is the issue? I tried searching around but din't get any solution. I tried replacing api-key with apiKey(I know it's silly) but no success.
Any help folks?
You are using Spring Boot's configuration properties in application.yml but you are also making your own DatadogMeterRegistry that doesn't use those configuration properties, and therefore it will not have the required API key configuration.
You can delete the MeterRegistryConfig class entirely and instead use the DatadogMeterRegistry that Spring Boot will auto-configure from configuration properties because you have the micrometer-registry-datadog dependency on your classpath. See this section of the Spring Boot documentation.
For me, it was just the hierarchy is changed when updated from Spring boot 2 -> 3.
Update the below:
management:
.....
metrics: // Changed to datadog
.....
export: // Changed to metrics
datadog: // Changed to export
step: 30s
enabled: true
api-key: xxxxxxx
.....
To :
management:
.....
datadog:
.....
metrics:
export:
step: 30s
enabled: true
api-key: xxxxxxx
.....

How to configure spring to use External LDAP Server

I am learning about Spring Security to LDAP server, right now i am trying to make spring authenticate to ldap server. However, spring always uses the embedded server ldap://127.0.0.1:33389/dc=springframework,dc=org instead of my ldap://localhost:389/dc=localdomain,dc=local. I'm trying to configure it using application.properties See below my spring configuration.
WebSecurityConfig.java
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
logger.info("Loading Global Auth Configuration");
auth
.ldapAuthentication();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("Configuring HTTP Security.");
// Configure Web Security
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
// disable page caching
http.headers().cacheControl();
}
#Override
public void configure(WebSecurity web) throws Exception {
logger.info("Configuring Web Security HTTP Security.");
// AuthenticationTokenFilter will ignore the below paths
web
.ignoring()
.antMatchers(
HttpMethod.POST,
"/auth"
);
}
}
application.properties
#Ldap Info
spring.ldap.urls=ldap://localhost:389
spring.ldap.anonymous-read-only=true
spring.ldap.username=ldapadm
spring.ldap.password=root123
spring.ldap.base=ou=People,dc=localdomain,dc=local
Tried using above application.properties, still does not work.
application.properties
#Ldap Info
ldap.urls=ldap://localhost:389
ldap.base.dn=dc=localdomain,dc=local
ldap.username=cn=ldapadm,dc=localdomain,dc=local
ldap.password=root123
ldap.user.dn.pattern =uid={0}
I also tried above properties, still does not work.
2018-09-04 00:05:31.515 INFO 9948 --- [ main] s.s.l.DefaultSpringSecurityContextSource : URL 'ldap://127.0.0.1:33389/dc=springframework,dc=org', root DN is 'dc=springframework,dc=org'
2018-09-04 00:05:31.516 INFO 9948 --- [ main] o.s.l.c.support.AbstractContextSource : Property 'userDn' not set - anonymous context will be used for read-write operations
2018-09-04 00:05:31.523 WARN 9948 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.RuntimeException: Could not postProcess org.springframework.security.ldap.authentication.BindAuthenticator#3bc735b3 of type class org.springframework.security.ldap.authentication.BindAuthenticator
2018-09-04 00:05:31.526 INFO 9948 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
for both settings in application.properties, i always get this on my server log
Can anyone make sense of these? i am trying to make it read the application.properties but it always uses the embedded ldap in spring
You can follow a similar approach as in LDAP Authentication with Spring Boot
In application.properties.
ldap.urls=ldap://localhost:389/dc=localdomain,dc=local
In your WebSecurityConfig
#Value("${ldap.urls:ldap://127.0.0.1:33389/dc=springframework,dc=org}")
private String ldapUrls;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource()
.url(ldapUrls)
.and()
.passwordCompare()
.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("adminpassword");
}
Please note that actual parameters(userDnPatterns etc...) that may be changed according to your LDAP config, i just pointed out how you can configure your LDAP config to connect to an external LDAP
For me this is works
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userSearchFilter("sAMAccountName={0}")
.userDnPatterns("ou=people")
.contextSource()
.url("ldap://127.0.0.1:33389/dc=springframework,dc=org")
.managerDn("ldapadm")
.managerPassword("root123");
}
change "sAMAccountName={0}" to "uid={0}" or whatever your configuration

HikariPool-1 - jdbcUrl is required with driverClassName

I went back to programming my old program https://github.com/JonkiPro/REST-Web-Services. I've updated Spring Boot from version 15.6 to version 2.0.0. I have encountered many problems with compilation, but I can not deal with one. Well, during compilation, he throws me in the console
2018-03-18 21:54:53.339 ERROR 3220 --- [ost-startStop-1] com.zaxxer.hikari.HikariConfig : HikariPool-1 - jdbcUrl is required with driverClassName.
2018-03-18 21:54:55.392 INFO 3220 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'unit'
2018-03-18 21:54:56.698 INFO 3220 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'unit'
2018-03-18 21:54:56.778 ERROR 3220 --- [ost-startStop-1] com.zaxxer.hikari.HikariConfig : HikariPool-1 - jdbcUrl is required with driverClassName.
2018-03-18 21:54:56.782 ERROR 3220 --- [ost-startStop-1] o.s.b.web.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userDetailsService' defined in file [C:\Users\Jonatan\Documents\GitHub\REST-Web-Services\web\out\production\classes\com\web\web\security\service\impl\UserDetailsServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Cannot create inner bean '(inner bean)#65d6e77b' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#65d6e77b': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Post-processing of FactoryBean's singleton object failed; nested exception is java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
2018-03-18 21:54:56.821 WARN 3220 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
I've never had such a mistake. I do not know what it means completely. My properties for the base look like this
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql:database
username: root
password: root
schema: classpath:/db/init/schema.sql
I do not know how to deal with this error. I've been programming quite a long time, but for the first time I'm meeting the concept of hikari. I'm using a Tomcat(in Spring Boot) server and a PostgreSQL database.
I had the same issue in another context.
From the 79. Data Access - Configure a Custom DataSource
if you happen to have Hikari on the classpath, this basic setup does not work, because Hikari has no url property (but does have a jdbcUrl property)
Hikari is the default pool in spring boot 2.
so you can replace the config
url: jdbc:postgresql:database -> jdbc-url: jdbc:postgresql:database
or you can keep the config but you need to define another Bean to handle the mapping (aliases)
#Bean
#Primary
#ConfigurationProperties("app.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#ConfigurationProperties("app.datasource")
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().
.build();
}
Either remove spring.datasource.driver-class-name property or rename the spring.datasource.url property to spring.datasource.jdbc-url.
This is reported in your error:
java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName
First option looks cleaner and Spring Boot will figure out the default driver class name based on the spring.datasource.url property value (see org.springframework.boot.jdbc.DatabaseDriver class if you want to debug this).

Spring Boot Not Able to Resolve Static Content

So after adding Spring Security (not sure if it is the cause) it appears not only are the default Static Content resolution path null and void, but also any subsequent attempts to map URLs to static content
For example, a vanilla Spring Boot Application without a WebSecurityConfigurerAdapter would map /GET localhost:8080/index.html to ResourceHttpRequestHandler with default configured static content locations such as classpath:META-INF/resources and classpath:static/
Thus index.html located in one of these classpath locations are automatically served.
With a WebSecurityConfigurerAdapter however, I get 405s ... and no matter what I do ... it appears the handler registry will not contain a mapping to the aforementioned ResourceHttpRequestHandler locations
For example
Attempt to Add mapping explicitly
Use ResourceHandlerRegistry
#Configuration
public class ServletConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/index.html").addResourceLocations("classpath:statc/index.html");
super.addResourceHandlers(registry);
}
}
Here are the TRACE logs
2017-07-17 12:12:21.742 DEBUG 23566 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/]
2017-07-17 12:12:21.755 DEBUG 23566 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /
2017-07-17 12:12:21.760 DEBUG 23566 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
2017-07-17 12:12:21.768 DEBUG 23566 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Invoking #ExceptionHandler method: public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)
Is this a known and frequently encountered issue when dealing with Spring Security?
Or maybe this is not expected and unrelated to Spring Security? I've gotten the entire setup to work many times before, the only thing new is Spring Security
Here is the SecurityConfiguration
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
final DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(new StandardPasswordEncoder());
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
/*
it is important to set the default userDetailsService on AuthenticationManagerBuilder
*/
auth.authenticationProvider(daoAuthenticationProvider).userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
org.springframework.security.web.authentication.AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler();
http
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
.and()
.authorizeRequests()
.antMatchers("/index.html").permitAll()
.antMatchers("/api/security/**")
.hasAuthority("ADMIN")
.antMatchers("/api/portfolios/**", "/api/trades/**", "/api/user/**", "/api/init")
.authenticated()
.and()
.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.rememberMe()
.and()
.logout()
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK));
}
}
Note that the start-up logs show both the default static content handler mapping and my explicit mapping to be both present and configured ... they are just not there when the actual request is made:
2017-07-17 12:25:57.088 DEBUG 23702 --- [ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#23707d5d]
2017-07-17 12:25:57.089 DEBUG 23702 --- [ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/index.html", locations=[class path resource [statc/index.html]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#5fa49615]
2017-07-17 12:25:57.089 DEBUG 23702 --- [ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/webjars/**", locations=[class path resource [META-INF/resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#7921eb37]
2017-07-17 12:25:57.089 DEBUG 23702 --- [ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**", locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#3fdb9c55]
EDIT
Digging Deeper
It appears there is a PartialMatchHelper in RequestMappingInfoHandlerMapping.java:195 on URL:[], method: PUT which will match every single request!
Kind of small mistake on my part - but has huge implications (after learning how Spring MVC framework works internally)
I had accidentally added a controller like this
#RestController("registration")
public class RegistrationController { ... }
When I meant
#RestController
#RequestMapping("registration")
public class RegistrationController {...}
so my registration REST end point would not have worked ... clearly BUT ... the former configuration also unwitting affected static content resolution by placing an empty URL:[], METHOD: PUT/POST or whatever into RequestMappingHandlerMapping which is one of the handler mappings that can take precedence over static Resource mappings
So the moral of the story is:
debug DispatcherServlet.java to see which handler mapping is truly being used

Multiple liquibase configurations in spring boot

I have spring boot application which use 2 databases. I defined 2 configurations providing specified datasources. I want to have that datasources managed separately by liquibase. I defined 2 separated changelog files.
The problem is that I can't define 2 separate beans for liquibase.
Here are my config classes:
...
public class CCSConfiguration {
...
#Bean
#ConfigurationProperties("ccs.liquibase")
public LiquibaseProperties ccsLiquibaseProperties() {
return new LiquibaseProperties();
}
#Bean
public SpringLiquibase ccsLiquibase(LiquibaseProperties liquibaseProperties) {
...
}
...
}
...
public class CCAConfiguration {
...
#ConfigurationProperties("cca.liquibase")
public LiquibaseProperties ccaLiquibaseProperties() {
return new LiquibaseProperties();
}
#Bean
public SpringLiquibase ccaLiquibase(LiquibaseProperties liquibaseProperties) {
...
}
...
}
And properties:
cca:
liquibase:
change-log: classpath:config/liquibase/cca/master.xml
ccs:
liquibase:
change-log: classpath:config/liquibase/ccs/master.xml
With this config i get following error while running appliction:
2017-04-11 14:26:55.664 WARN 34292 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'liquibase' available
2017-04-11 14:26:55.711 WARN 34292 --- [ restartedMain] o.s.boot.SpringApplication : Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.config.internalCacheAdvisor' defined in class path resource [org/springframework/cache/annotation/ProxyCachingConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor]: Factory method 'cacheAdvisor' threw exception; nested exception is java.lang.NullPointerException)
2017-04-11 14:26:55.939 ERROR 34292 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named 'liquibase' that could not be found.
Action:
Consider defining a bean named 'liquibase' in your configuration.
So, is it possible to define multiple liquibase beans for different datasources?
there are two options:
you define a bean named liquibase to let spring-boot integrated process to update your schema on you first DS. You have to handle the second one by hand
you disable liquibase automatic update at startup with
enabled: false
and define your way DS and liquibase beans to update your two databases

Categories