I'm using spring boot 2.6.7 and hikari pool.
I'm trying to use autoconfigure ans setting :
spring:
datasource:
url: "jdbc:postgresql://localhost:5432/bdd"
username: username
password: pass
type: app.CustomHikariDatasource
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 3
minimum-idle: 3
register-mbeans: true
But when application is launch pool is always 10 (default hikari value)
I try to disable autoconfiguration (DataSourceAutoConfiguration.class) and create my datasource manually like this:
@Bean
@Primary
public DataSource dataSource(HikariConfig hikariConfig) {
return new CustomHikariDatasource(hikariConfig);
}
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
but whe application start i got :
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [HikariDataSource (HikariPool-1)] with key 'dataSource'; nested exception is javax.management.InstanceAlreadyExistsException: MXBean already registered with name com.zaxxer.hikari:type=PoolConfig (HikariPool-1)
If i put a breakpoint in HikariConfig constructor, i effectivly pass 2 times in it! If i disable register-mbeans: false it work, but i need to have mbeans activated!
2 ways to find a solution:
- first, can someone explain to me why my autoconfigure not taking hikariconfig properties and perhaps fix the problem?
- secondly, if first point is not working, why spring boot instantiate 2 times hikariconfig when i disable autoconfiguration? does i need to disable something else?
thanks for helping me.
#EDIT1
To disable default mbean exporter i follow this issue :
https://github.com/brettwooldridge/HikariCP/issues/342
And with doing this:
@Bean
public MBeanExporter exporter() {
MBeanExporter exporter = new MBeanExporter();
exporter.setAutodetect(true);
exporter.setExcludedBeans("dataSource");
return exporter;
}
I don't have exception anymore and my mbean is correctly exposed!
#EDIT2
For the first point i think it's because i'm using CustomHikariDatasource and in the code of DatasourceConfiguration i can see :
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
matchIfMissing = true)
static class Hikari {
so because my spring.datasource.type isn't com.zaxxer.hikari.HikariDataSource, spring don't instanciate it in the right way, so i decided to disable autoconfiguration and instantiate my CustomHikariDatasource manually and with the solution found in the Edit1, all seems to be working.
CodePudding user response:
As mentioned in this issue this is due to a change in Hikari which now leads to Spring detecting it as an MBean and tries to export it as such. However as you enabled jmx export on Hikari as well there is already a bean.
The initial thought might be to disable the JMX export in Hikari by specifying this in your config.
spring.datasource.hikari.register-mbeans=false
However according to the earlier mentioned issue this will only register the datasource in JMX. While Hikari itself exports two in JMX.
I suggest to add the @EnableMBeanExport
annotation to an configuration class and override the behavior when it detects an existing bean. The default is to throw an exception, but you could configure it to ignore the exception and keep the original bean.
@EnableMBeanExport(registration=IGNORE_EXISTING)
This will enable JMX exporting (as it was already enabled) and keep the Hikari registered ones.
Another option would be to register both and ignore the exception and generate a new name. You can do this by specifying this in your application.properties
.
spring.jmx.unique-names=true
Which should generate a new name for the Spring registered one. Drawback is that you now have the same bean twice in JMX. Advantage you don't have to override any Spring configuration.