With the following configuration:
spring:
kafka:
producer:
client-id: some-id
ssl:
key-password: secret
key-store-location: classpath:keystore.jks # line 18
key-store-password: secret
trust-store-location: classpath:truststore.jks
trust-store-password: secret
I get the following message:
[WARN] org.springframework.boot.context.properties.migrator.PropertiesMigrationListener -
The use of configuration keys that have been renamed was found in the environment:
Property source 'migrate-Config resource 'class path resource [application-integration.yml]' via location 'optional:classpath:/'':
Key: spring.kafka.producer.ssl.keystore-location
Line: 18
Replacement: spring.kafka.producer.ssl.key-store-location
Key: spring.kafka.producer.ssl.keystore-password
Line: 19
Replacement: spring.kafka.producer.ssl.key-store-password
Key: spring.kafka.producer.ssl.truststore-location
Line: 20
Replacement: spring.kafka.producer.ssl.trust-store-location
Key: spring.kafka.producer.ssl.truststore-password
Line: 21
Replacement: spring.kafka.producer.ssl.trust-store-password
Property source 'Config resource 'class path resource [application-integration.yml]' via location 'optional:classpath:/'':
Key: spring.kafka.producer.ssl.keystore-location
Line: 18
Replacement: spring.kafka.producer.ssl.key-store-location
Key: spring.kafka.producer.ssl.keystore-password
Line: 19
Replacement: spring.kafka.producer.ssl.key-store-password
Key: spring.kafka.producer.ssl.truststore-location
Line: 20
Replacement: spring.kafka.producer.ssl.trust-store-location
Key: spring.kafka.producer.ssl.truststore-password
Line: 21
Replacement: spring.kafka.producer.ssl.trust-store-password
Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.
But I already changed them to the new one. It's just a warning, but it seems to be incorrect. Also interesting it shows it twice with different property source names.
Comment From: mhalbritter
This indeed looks like a bug. The org.springframework.boot.context.properties.migrator.PropertiesMigrationReporter#getMatchingProperties returns it as deprecated properties, because this line:
ConfigurationProperty match = propertySource.getConfigurationProperty(metadataName);
returns a non-null match when invoked with e.g. "spring.kafka.producer.ssl.keystore-location". I assume this is because of the relaxed mapping support in SpringIterableConfigurationPropertySource and "keystore" and "key-store" map to the same relaxed value.
However, I can't reproduce that you get those messages two times. Could you maybe provide a small sample which reproduces this double printing issue?
Comment From: martinvisser
I see you added 2.7.x milestone, but forgot to mention this (also) happened using Spring Boot 3.1.0
Comment From: mhalbritter
I suspect the underlying cause is in Boot 2.7.x too. When we fix that bug there, we forward merge to 3.0.x and 3.1.x.
Comment From: p-palanisami
I am a new contributor. Shall I take this bug?
Comment From: mhalbritter
Hey, thanks for the offer. If you want to help, keep an eye out on first timer issues and ideal for contribution issues.
I think this issue could get quite complicated and is not suitable for getting started.
Comment From: Wzy19930507
Hi, may i pick it up
i'll chang code at https://github.com/spring-projects/spring-boot/blob/0ef87f51020939fef8c06d922dce87eab0f15190/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/SpringIterableConfigurationPropertySource.java#L96-L112
after change
class SpringIterableConfigurationPropertySource extends SpringConfigurationPropertySource
implements IterableConfigurationPropertySource, CachingConfigurationPropertySource {
@Override
public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
for (String candidate : getMappings().getMapped(name)) {
if(!isFieldDashNameMatch(candidate, name)) {
return null;
}
Object value = getPropertySource().getProperty(candidate);
if (value != null) {
Origin origin = PropertySourceOrigin.get(getPropertySource(), candidate);
return ConfigurationProperty.of(this, name, value, origin);
}
}
}
private static class Mappings {
public static boolean isFieldDashNameMatch(String propertyName, ConfigurationPropertyName fieldName) {
ConfigurationPropertyName name = this.reverseMappings.get(propertyName);
if (name == null || fieldName == null) {
return false;
}
if (name.getNumberOfElements() != fieldName.getNumberOfElements()) {
return false;
}
for (int i = 0; i < name.getNumberOfElements(); i++) {
String element = name.getElement(i, Form.Dash);
String fieldElement = fieldName.getElement(i, Form.Dash);
if (!ObjectUtils.nullSafeEquals(element, fieldElement)) {
return false;
}
}
return true;
}
}
}
Comment From: philwebb
@Wzy19930507 You're welcome to submit a PR but I'm afraid with our 3.2 release so imminent we won't be able to provide a lot of guidance at this time. In the future, it's better to start a draft PR rather than describing the code changes you intend to make as a comment in the issue. It's very hard for us to discuss changes when they are issue comments and it adds a lot of noise for folks watching the issue.
Comment From: arkinmodi
Hi. I am running Spring Boot 3.3.3 and encountering this issue (with same configurations as in the original report). Could this issue be reopen?
Here is a Dockerfile to reproduce this warning log.
FROM eclipse-temurin:21
WORKDIR /tmp/demo
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
unzip
RUN curl \
-G https://start.spring.io/starter.zip \
-d type=gradle-project \
-d javaVersion=21 \
-d bootVersion=3.3.3 \
-o /tmp/demo.zip
RUN unzip /tmp/demo.zip -d /tmp/demo
RUN ./gradlew dependencies
RUN sed -i '/dependencies {/a runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")' build.gradle
RUN echo 'spring.kafka.ssl.trust-store-password=secret' >> ./src/main/resources/application.properties
CMD ["./gradlew", "bootRun"]
Output:
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
> Task :bootRun
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.3)
2024-08-30T20:34:39.745Z INFO 142 --- [demo] [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 21.0.4 with PID 142 (/tmp/demo/build/classes/java/main started by root in /tmp/demo)
2024-08-30T20:34:39.746Z INFO 142 --- [demo] [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2024-08-30T20:34:39.982Z INFO 142 --- [demo] [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.368 seconds (process running for 0.484)
2024-08-30T20:34:39.986Z WARN 142 --- [demo] [ main] o.s.b.c.p.m.PropertiesMigrationListener :
The use of configuration keys that have been renamed was found in the environment:
Property source 'Config resource 'class path resource [application.properties]' via location 'optional:classpath:/'':
Key: spring.kafka.ssl.truststore-password
Line: 2
Replacement: spring.kafka.ssl.trust-store-password
Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.
BUILD SUCCESSFUL in 9s
4 actionable tasks: 4 executed
Comment From: philwebb
@arkinmodi Thanks for the reproducer. I've opened #42068 to investigate.