After upgrading from 2.7.11 to 3.0.7 system environment isn't applied to Property
I have a property 'home' in Globals class https://github.com/sergmain/metaheuristic/blob/5f660e45baf44720996cf5f385e26ad99a1a9eb5/apps/metaheuristic/src/main/java/ai/metaheuristic/ai/Globals.java#L528
In 2.7.11 initializing OS environment MH_HOME was enough to set Globals.home to a new value.
after upgrading to 3.0.7 Globals.home isn't initialized
Caused by: java.lang.IllegalArgumentException: mh.home isn't specified
at ai.metaheuristic.ai.Globals.getHome(Globals.java:532) ~[classes/:na]
at ai.metaheuristic.ai.Globals.postConstruct(Globals.java:549) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:425) ~[spring-beans-6.0.9.jar:6.0.9]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:369) ~[spring-beans-6.0.9.jar:6.0.9]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:193) ~[spring-beans-6.0.9.jar:6.0.9]
... 123 common frames omitted
Comment From: sergmain
Addition. I don't know, do I need to create a new bug or don't, so I post here
Order of @PostConstruct is completely broken I have a service MetadataService which has an autowired bean EnvService
PostConstruct of MetadataService is being called before PostConstruct of EnvService
https://github.com/sergmain/metaheuristic/blob/5f660e45baf44720996cf5f385e26ad99a1a9eb5/apps/metaheuristic/src/main/java/ai/metaheuristic/ai/processor/MetadataService.java#L72
Comment From: mhalbritter
Hey, I can't reproduce that issue. My test application works fine. When setting MH_HOME=test it prints test.
If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
For your second comment: If you think there's a bug, please create a separate issue.
Comment From: wilkinsona
For your second comment: If you think there's a bug, please create a separate issue.
If you open an issue, it should be a Spring Framework issue as it handles @PostConstruct. It should also be accompanied by a minimal sample.
Comment From: sergmain
Hey, I can't reproduce that issue. My test application works fine. When setting
MH_HOME=testit prints test.If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
For your second comment: If you think there's a bug, please create a separate issue.
I managed to reproduce a bug with your code - adding
private final Environment env;
to TestAppProperties is enough reproduce
https://github.com/sergmain/sb-35718/blob/98d460ac2a987c097da22f6fbe94b674224caa4b/src/main/java/com/example/sb35718/TestAppProperties.java#L15
After adding this line method org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod#get(java.lang.Class<?>) return VALUE_OBJECT instead of JAVA_BEAN
Comment From: mhalbritter
Yes, because the binder is now using constructor based binding. If you do this, it works again:
private final Path home;
private final Environment environment;
public TestAppProperties(Path home, Environment environment) {
this.home = home;
this.environment = environment;
}
public Path getHome() {
return this.home;
}
But injecting Environment into @ConfigurationProperties doesn't work.
Comment From: sergmain
That would be nice to have ISE or at least message in log that @ConfigurationProperties is being used in wrong way.
Comment From: wilkinsona
Unfortunately, I don't think we can tell with absolute certainty that a particular arrangement is wrong.
FWIW, the documentation does provide some advice with which your Globals class is not aligned:
We recommend that
@ConfigurationPropertiesonly deal with the environment and, in particular, does not inject other beans from the context. For corner cases, setter injection can be used or any of the*Awareinterfaces provided by the framework (such asEnvironmentAwareif you need access to theEnvironment). If you still want to inject other beans using the constructor, the configuration properties bean must be annotated with@Componentand use JavaBean-based property binding.
You can also avoid the problem by annotating the constructor with @Autowired to ensure that JavaBean-based binding is still used:
For most users, this updated logic will allow for simpler
@ConfigurationPropertiesclasses. If, however, you have a@ConfigurationPropertiesand you want to inject beans into the constructor rather than binding it, you’ll now need to add an@Autowiredannotation.
Comment From: sergmain
Thanks for additional info