spring-native
spring-native copied to clipboard
Properties from @PropertySource are not available in the environment
Dear team,
I tried to run an app using @PropertySource
.
It works fine with Spring boot standard but not once converted to Native.
I'm using Spring native 0.11.0-RC1 / Spring boot 2.6.0
Example:
com/example/demo/DemoApplication.java
package com.example.demo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Component
public class CLR implements CommandLineRunner {
private static final Log logger = LogFactory.getLog(CLR.class);
@Value("${custom.property}")
private String customProperty;
@Override
public void run(String... args) throws Exception {
logger.info("Custom property: " + customProperty);
logger.info("---");
logger.trace("WARNING log message");
logger.debug("DEBUG log message");
logger.info("INFO log message");
logger.warn("WARNING log message");
logger.error("ERROR log message");
}
}
@Configuration
@PropertySource("classpath:test.properties")
public class SomeConfiguration {
}
}
test.properties:
custom.property=hello
build.gradle:
plugins {
id 'java'
id 'org.springframework.boot' version '2.6.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.springframework.experimental.aot' version '0.11.0-RC1'
id 'io.freefair.lombok' version '6.3.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
maven { url 'https://repo.spring.io/milestone' }
mavenCentral()
}
ext {
set('springCloudVersion', "2021.0.0-RC1")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
bootBuildImage {
builder = 'paketobuildpacks/builder:tiny'
environment = ['BP_NATIVE_IMAGE': 'true']
}
Result with Spring boot:
2021-12-02 21:12:50.764 INFO 28959 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-12-02 21:12:51.236 INFO 28959 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.806 seconds (JVM running for 1.088)
2021-12-02 21:12:51.239 INFO 28959 --- [ main] com.example.demo.DemoApplication$CLR : Custom property: hello
2021-12-02 21:12:51.239 INFO 28959 --- [ main] com.example.demo.DemoApplication$CLR : ---
2021-12-02 21:12:51.239 INFO 28959 --- [ main] com.example.demo.DemoApplication$CLR : INFO log message
2021-12-02 21:12:51.239 WARN 28959 --- [ main] com.example.demo.DemoApplication$CLR : WARNING log message
2021-12-02 21:12:51.239 ERROR 28959 --- [ main] com.example.demo.DemoApplication$CLR : ERROR log message
Result with Spring native:
2021-12-02 21:04:01.071 INFO 28318 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-12-02 21:04:01.072 WARN 28318 --- [ main] o.s.c.support.GenericApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.example.demo.DemoApplication$CLR': Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'custom.property' in value "${custom.property}"
2021-12-02 21:04:01.077 ERROR 28318 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.example.demo.DemoApplication$CLR': Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'custom.property' in value "${custom.property}"
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:555) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[na:na]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[na:na]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[demo:2.6.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) ~[demo:2.6.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[demo:2.6.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[demo:2.6.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) ~[demo:2.6.0]
at com.example.demo.DemoApplication.main(DemoApplication.java:17) ~[demo:na]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'custom.property' in value "${custom.property}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[na:na]
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[na:na]
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[na:na]
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[na:na]
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:936) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1321) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[na:na]
at org.springframework.aot.beans.factory.InjectedFieldResolver.resolve(InjectedFieldResolver.java:45) ~[na:na]
at org.springframework.aot.beans.factory.InjectedElementResolver.resolve(InjectedElementResolver.java:19) ~[na:na]
at org.springframework.aot.beans.factory.InjectedElementResolver.invoke(InjectedElementResolver.java:37) ~[na:na]
at com.example.demo.ContextBootstrapInitializer.lambda$registerDemoApplication_CLR$1(ContextBootstrapInitializer.java:15) ~[na:na]
at org.springframework.aot.beans.factory.ThrowableFunction.apply(ThrowableFunction.java:18) ~[na:na]
at org.springframework.aot.beans.factory.BeanDefinitionRegistrar.lambda$instanceSupplier$0(BeanDefinitionRegistrar.java:82) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[na:na]
... 13 common frames omitted
I have the same issue when I also use @ConfigurationProperties
.
Values coming from property source files are not injected into the Configuration properties bean.
Any clue on what I may do wrong?
Thanks for your help.
@snicoll Issue confirmed with AOT + JVM, could you please give it a look?
Good catch, the environment is prepared at build time but this is lost at runtime as there is no bean that translates this change. Probably something relatively easy to fix.
The code that processes those is internal of ConfigurationClassParser
. Yet another case of something that should have a way to output what it has discovered so that it can be written in generated code.
@julb in general we don't recommend using @PropertySource
at all. Spring Boot has a fairly superior configuration model. I understand that you might have got used to the flexibility that the annotation brings, but using profiles and spring.config.import
has the advantage of having the config in one place and it being processed before the application context is parsed.
We've moved this issue to backlog as we can't justify spending the time on this project to support it. This will be reconsidered during the move to Spring Framework proper though. Thank you.
Thanks a lot @snicoll for your feedback.
Spring Native is now superseded by Spring Boot 3 official native support, see the related reference documentation for more details.
As a consequence, I am closing this issue, and recommend trying your use case with latest Spring Boot 3 version. If you still experience the issue reported here, please open an issue directly on the related Spring project (Spring Framework, Data, Security, Boot, Cloud, etc.) with a reproducer.
Thanks for your contribution on the experimental Spring Native project, we hope you will enjoy the official native support introduced by Spring Boot 3.