Skip to content

SpringApplication.setEnvironmentPrefix is ignored when reading MANAGEMENT_SERVER_PORT #45857

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
emouty opened this issue Jun 9, 2025 · 11 comments
Assignees
Labels
type: regression A regression from a previous release
Milestone

Comments

@emouty
Copy link

emouty commented Jun 9, 2025

In spring boot 3.4.5 I could setup my management server port as an env var with a prefix since 3.5.0 this is no longer the case. This might be due to changes from #45549

I could have

@SpringBootApplication
public class SpringBootIssuesApplication {

    public static void main(String[] args) {
        SpringApplicationBuilder myApp = new SpringApplicationBuilder(SpringBootIssuesApplication.class);
        myApp.environmentPrefix("myapp");
        myApp.run(args);
    }

}

and launching my app with env var : MYAPP_MANAGEMENT_SERVER_PORT=9090 would start management server on 9090. since 3.5.0 I need to put MANAGEMENT_SERVER_PORT=9090 to have the same behavior

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 9, 2025
@wilkinsona
Copy link
Member

Thanks for the report. This is a regression caused, at least in part, by a performance optimisation that means that the prefix isn't considered. One option is to disable the optimization when an environment prefix has been configured but I'd like to discuss this with @philwebb as there may be a better approach. A secondary problem appears to be that the prefix isn't transferred to the child context's environment. I have yet to identify the cause.

@wilkinsona wilkinsona added type: regression A regression from a previous release and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 9, 2025
@wilkinsona wilkinsona added this to the 3.5.x milestone Jun 9, 2025
@wilkinsona
Copy link
Member

wilkinsona commented Jun 9, 2025

A secondary problem appears to be that the prefix isn't transferred to the child context's environment. I have yet to identify the cause.

Rather than the prefix no longer being transferred, I believe the cause is the ManagementServerProperties now being bound in the child context due to this change. A possible fix here is to rely on the properties in the parent context where they should already exist.

@philwebb
Copy link
Member

philwebb commented Jun 9, 2025

#45741 might also be related to this area.

@philwebb philwebb self-assigned this Jun 9, 2025
@wilkinsona
Copy link
Member

wilkinsona commented Jun 9, 2025

I've opened #45858 as 3.4.x also suffers from the second part of the problem. It's gone unnoticed as nothing binds @EnableConfigurationProperties(ManagementServerProperties.class) in the child management context in 3.4.x. If something does, it binds those properties ignoring the environment prefix.

@philwebb
Copy link
Member

philwebb commented Jun 9, 2025

I think the fix I pushed for #45741 may also solve this one. @wilkinsona If you have a sample or test could you please try it again?

@wilkinsona
Copy link
Member

I'm struggling to reproduce it now, even with 3.5.0. Either I was/am doing something daft, or there's a subtle ordering aspect to the problem which makes me wonder if the cache is involved too somehow?

I can still reproduce a failure where the property can't be bound in the child context which results in an NPE:

Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties.getPort()" is null
	at org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer.customize(ManagementWebServerFactoryCustomizer.java:112) ~[spring-boot-actuator-autoconfigure-3.5.0.jar:3.5.0]
	at org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration$ServletManagementWebServerFactoryCustomizer.customize(ServletManagementChildContextConfiguration.java:127) ~[spring-boot-actuator-autoconfigure-3.5.0.jar:3.5.0]
	at org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration$ServletManagementWebServerFactoryCustomizer.customize(ServletManagementChildContextConfiguration.java:117) ~[spring-boot-actuator-autoconfigure-3.5.0.jar:3.5.0]
	at org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer.customize(ManagementWebServerFactoryCustomizer.java:88) ~[spring-boot-actuator-autoconfigure-3.5.0.jar:3.5.0]
	at org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer.customize(ManagementWebServerFactoryCustomizer.java:42) ~[spring-boot-actuator-autoconfigure-3.5.0.jar:3.5.0]
	at org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor.lambda$postProcessBeforeInitialization$0(WebServerFactoryCustomizerBeanPostProcessor.java:71) ~[spring-boot-3.5.0.jar:3.5.0]
	at org.springframework.boot.util.LambdaSafe$Callbacks.lambda$invoke$0(LambdaSafe.java:287) ~[spring-boot-3.5.0.jar:3.5.0]
	at org.springframework.boot.util.LambdaSafe$LambdaSafeCallback.invoke(LambdaSafe.java:159) ~[spring-boot-3.5.0.jar:3.5.0]
	at org.springframework.boot.util.LambdaSafe$Callbacks.lambda$invoke$1(LambdaSafe.java:286) ~[spring-boot-3.5.0.jar:3.5.0]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[na:na]
	at java.base/java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1116) ~[na:na]
	at org.springframework.boot.util.LambdaSafe$Callbacks.invoke(LambdaSafe.java:286) ~[spring-boot-3.5.0.jar:3.5.0]
	at org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor.postProcessBeforeInitialization(WebServerFactoryCustomizerBeanPostProcessor.java:71) ~[spring-boot-3.5.0.jar:3.5.0]
	at org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor.postProcessBeforeInitialization(WebServerFactoryCustomizerBeanPostProcessor.java:57) ~[spring-boot-3.5.0.jar:3.5.0]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:429) ~[spring-beans-6.2.7.jar:6.2.7]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1818) ~[spring-beans-6.2.7.jar:6.2.7]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.2.7.jar:6.2.7]
	... 25 common frames omitted

That's what #45858 is tracking.

@emouty, given "ignored" in the issue's title, I assume that this isn't the behavior that you're seeing. Can you please share a minimal example that ignores MYAPP_MANAGEMENT_SERVER_PORT when the environment prefix is set to myapp?

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Jun 9, 2025
emouty added a commit to emouty/spring-boot-issues that referenced this issue Jun 10, 2025
@emouty
Copy link
Author

emouty commented Jun 10, 2025

you will an example on this repo https://github.com/emouty/spring-boot-issues

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jun 10, 2025
@wilkinsona
Copy link
Member

Thank you, @emouty. The key piece that was missing from your original description is that you're also setting management.server.port in application.properties. This means that the app will always create the child management context. The port that it listens on will vary depending on whether or not the environment variable is picked up.

@emouty
Copy link
Author

emouty commented Jun 10, 2025

Indeed, I'm so used to having it here all the time that I forgot that its not the default value 😅

@wilkinsona
Copy link
Member

I'm struggling to reproduce it now, even with 3.5.0

This remains the case this morning. Sorry, @philwebb.

Yesterday, I was certain that I was seeing SpringConfigurationPropertySource wrapping a prefixed system environment property source. When it then went straight to the underlying Map<String, Object> source, the prefixing was lost so it looked for MANAGEMENT_SERVER_PORT instead of MYAPP_MANAGEMENT_SERVER_PORT.

What I see now is that the wrapping is the other way around so the prefix has already been applied before SpringConfigurationPropertySource gets involved.

We can fix the problem reported here by removing @EnableConfigurationProperties(ManagementServerProperties.class) from ServletManagementChildContextConfiguration. This will ensure that it reuses the ManagementServerProperties from the parent context. It also brings ServletManagementChildContextConfiguration and ReactiveManagementChildContextConfiguration into alignment.

We can consider #45858 separately as the prefix not being applied to the child context's environment will still affect any configuration property binding that's performed in the child context.

@wilkinsona wilkinsona removed the status: feedback-provided Feedback has been provided label Jun 10, 2025
@wilkinsona wilkinsona assigned wilkinsona and unassigned philwebb Jun 10, 2025
wilkinsona added a commit that referenced this issue Jun 10, 2025
Binding in the child context does not work correctly when an
environment prefix has been configured. The prefix is not applied
to the child context's Environment and, therefore, prefixed
environment variables are ignored during binding.

We can fix the problem by reusing the parent context's
ManagementServerProperties rather than binding them again in the
child context. Doing so will fix the problem reported in gh-45857
that was introduced in 020fd7b and will also avoid an unnecessary
second binding of the properties.

gh-45858 may fix the problem more generally by applying the prefix
to the child context's environment. This would benefit situations
where the properties need to be bound in the child context because
they haven't already been bound in the parent.

Closes gh-45847
@wilkinsona
Copy link
Member

Closed by 9a1ca2f.

@wilkinsona wilkinsona modified the milestones: 3.5.x, 3.5.1 Jun 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

4 participants