ARTICLE AD BOX
I'm currently using Javamelody with Spring boot 4.0.3
I wanted to add a refresh feature of my configuration properties (loaded from file and database).
Using PropertySourceLocator, I'm fine but when calling actuator/refresh endpoint the datasource is refreshed causing an exception.
Javamelody wraps/decorates the Datasource with a Proxy and Spring calls Bindable and now detect that the Proxy class is not an instance of the HikariDatasource
There are some old issues on Javamelody tracker (2027/2018/2019) about proxy.
One suggested solution is to use spring.aop.proxy-target-class but Spring doc raises some issues and if I'm reading the doc correctly the default value is already true
What configuration is required to make /actuator/refresh work with a Javamelody-proxied DataSource in Spring Boot 4?
Here a sample build.gradle generated by spring initialzr. When POST to /actuator/refresh
java.lang.IllegalArgumentException: 'existingValue' must be an instance of com.zaxxer.hikari.HikariDataSource at org.springframework.util.Assert.isTrue(Assert.java:136) ~[spring-core-7.0.7.jar:7.0.7] at org.springframework.boot.context.properties.bind.Bindable.withExistingValue(Bindable.java:195) ~[spring-boot-4.0.6.jar:4.0.6] at org.springframework.boot.context.properties.ConfigurationPropertiesBean.get(ConfigurationPropertiesBean.java:210) ~[spring-boot-4.0.6.jar:4.0.6]Debugging it it comes from boxedTypeIsInstanceOf metod that check instanceOf
Assert.isTrue(existingValue == null || this.type.isArray() || boxedTypeIsInstanceOf(existingValue), () -> "'existingValue' must be an instance of " + this.type);Build.gradle:
plugins { id 'java' id 'org.springframework.boot' version '4.0.6' id 'io.spring.dependency-management' version '1.1.7' } group = 'com.example' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } repositories { mavenCentral() } ext { set('springCloudVersion', "2025.1.1") } dependencies { implementation 'org.springframework.cloud:spring-cloud- starter' implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter- actuator' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-webmvc' implementation 'net.bull.javamelody:javamelody-spring-boot4-starter:2.6.0' testImplementation 'org.springframework.boot:spring-boot-starter-test' runtimeOnly 'com.oracle.database.jdbc:ojdbc11' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud- dependencies:${springCloudVersion}" } } tasks.named('test') { useJUnitPlatform() }In my application.yml, I hve defined my datasource and open the refresh endpoints.
management.endpoints.web.exposure.include: info, health, refresh