Skip to content

Improve setEnvironmentPrefix(...) reference documentation #45370

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
GrahamHannington opened this issue May 6, 2025 · 8 comments
Closed

Improve setEnvironmentPrefix(...) reference documentation #45370

GrahamHannington opened this issue May 6, 2025 · 8 comments
Assignees
Labels
type: documentation A documentation update
Milestone

Comments

@GrahamHannington
Copy link

GrahamHannington commented May 6, 2025

With no environment prefix set, the following environment variables work:

SPRING_CONFIG_ADDITIONALLOCATION=file:../shared/
SPRING_PROFILES_ACTIVE=server-public

That is, my Spring Boot app loads the corresponding profile-specific file ../shared/nexus-server-public.yaml, and the app uses the property values set in that file, such as the server.port value.

Note:

  • The Java command line for the app sets --spring.config.name=nexus.
  • The app uses Spring Boot 3.1.12 (yes, old).

If I set the environment prefix "nco" (here's the corresponding snippet from the app main() function):

SpringApplication application = new SpringApplication(DataStreamerApplication.class);
application.setEnvironmentPrefix("nco");
context = application.run(args);

then, as expected, those (unprefixed) environment variables no longer "work".

Interestingly, though, the app log reports that profile as being active, but the log also shows that the app does not use the server port value set by that profile-specific file.

The problem: This tells me that, with an environment prefix set, my app is using SPRING_PROFILES_ACTIVE, but not SPRING_CONFIG_ADDITIONALLOCATION.

Sure enough, if I add the prefix NCO_ to the variable name SPRING_CONFIG_ADDITIONALLOCATION, then it works: the app uses the server.port set in the profile-specific file in that additional location.

However, if I also add the prefix NCO_ to SPRING_PROFILES_ACTIVE, then the application log reports "No active profile set".

That is, my app recognizes NCO_SPRING_CONFIG_ADDITIONALLOCATION as a configuration property, but not NCO_SPRING_PROFILES_ACTIVE.

If this is a bug in Spring Boot, then: please fix it.

If this is working as designed, then: please enhance the docs to describe, if an environment prefix is set, which configuration properties should be specfied with that prefix, and which (e.g. SPRING_PROFILES_ACTIVE) should not.

Another possibility is that my app is causing this behavior. I've already considered that, but I can't see any reason for it, hence this issue. I acknowledge that I haven't taken the time to create a minimal app using the latest release of Spring Boot and attempt to reproduce this behavior. If Spring Boot developers respond to this issue that it's not a bug and it's not working as designed, then that will be useful to me: with apologies, I'll slink away and attempt again to figure out how the app is causing this behavior.

In any case, I suggest that the Spring Boot docs about the environment prefix could be enhanced.

In the related GitHub issue, "Add prefix support for environment variables", #3450, @philwebb wrote:

a prefix ... Which would then bind MYAPP_SERVER_PORT rather than SERVER_PORT

That concise design intent seems clear to me.

However, from the Spring Boot docs heading "Configuring System Environment Properties":

if you set the prefix to input, a property such as remote.timeout will also be resolved as input.remote.timeout in the system environment.

While I acknowledge that you "can't fix stupid" 🙂, and so this might just be my problem: those docs confuse me. Are those docs even describing the same feature as GitHub issue #3450? If so, the docs seem to me to be describing the feature "backwards". My understanding is that, if you set the prefix to input, then the environment variable INPUT_REMOTE_TIMEOUT will be resolved as the property remote.timeout. What does "also" mean in the phrase "will also be resolved as", and how does that relate to the phrase "rather than" in issue #3450?

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

snicoll commented May 6, 2025

Spring Boot 3.1.12 is out of OSS support. Please upgrade and, if you can still reproduce the issue you've described, share a small app that we can run ourselves that demonstrates what you've explained. This is a lot of text and our time would be best used looking at the actual problem to see if the documentation should be updated. Thank you.

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label May 6, 2025
@mdeinum
Copy link
Contributor

mdeinum commented May 6, 2025

context = SpringApplication.run(DataStreamerApplication.class, args);
SpringApplication application = new SpringApplication(DataStreamerApplication.class);
application.setEnvironmentPrefix("nco");
context = application.run(args);

This code starts the application twice. First without a prefix, second with a prefix. You should remove the context = SpringApplication.run(DataStreamerApplication.class, args); line and check again.

@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 May 6, 2025
@bclozel bclozel added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels May 6, 2025
@philwebb philwebb changed the title Environment prefix: not all prefixed environment variables are recognized as configuration properties Improve setEnvironmentPrefix(...) reference documentation May 6, 2025
@philwebb philwebb self-assigned this May 6, 2025
@philwebb philwebb added type: documentation A documentation update and removed status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged labels May 6, 2025
@philwebb philwebb modified the milestones: 3.3.x, 3.3.12 May 6, 2025
@philwebb
Copy link
Member

philwebb commented May 6, 2025

I've tried to improve the documentation. I think the first issue you describe is due to the description @mdeinum provided. If you can recreate the issue without the first static SpringApplication.run call then please provide a sample and we can investigate.

@GrahamHannington
Copy link
Author

@mdeinum wrote:

This code starts the application twice. First without a prefix, second with a prefix. You should remove the context = SpringApplication.run(DataStreamerApplication.class, args); line and check again.

Thanks for spotting that. That's not in the actual code. That was my stupid copy'n'paste mistake: I copied code from a pull request diff, including that original (deleted) first line. I've edited my original post and removed that line. Sorry about that.

@GrahamHannington
Copy link
Author

@snicoll wrote:

Spring Boot 3.1.12 is out of OSS support.

Yes, I'm aware of this. I'm not the owner of this app, nor the primary developer.

Please upgrade and, if you can still reproduce the issue you've described, share a small app that we can run ourselves that demonstrates what you've explained. This is a lot of text

Yes, I agree with everything you've written. All of that has occurred to me, including "This is a lot of text". I'm sorry for being verbose. It's partly me overcompensating for not having that demo app to offer.

I'm feeling a little like an imposter here. I'm learning Java, and Spring Boot, by examining and making small tweaks to an existing app. It would do me good to start with a new, minimal app, and work from there. I really want to do that. It's just a matter of getting the time to do it.

@GrahamHannington
Copy link
Author

@philwebb wrote:

I think the first issue you describe is due to

No, it's not.

If you can recreate the issue without the first static SpringApplication.run call

Yes, I can.

As I've mentioned in a recent comment, that first call is not in my actual working code.

I'm so sorry for wasting people's time with that careless copy'n'paste mistake.

please provide a sample and we can investigate

Understood.

@GrahamHannington
Copy link
Author

@philwebb wrote:

Please provide a sample and we can investigate

Done. Here's the source of a sample Spring Boot 3.4.5 app, with detailed test cases. Could you please investigate?

The sample and test cases demonstrate the issue that I reported: with an environment prefix set (in this example, to nco), the app continues to recognize the unprefixed environment variable SPRING_PROFILES_ACTIVE as the corresponding property spring.profiles.active, not the prefixed variable (NCO_SPRING_PROFILES_ACTIVE).

Is this a bug, or working as designed?

Are other configuration properties also "insensitive" to the environment prefix?

Sample Java source

Here is my newbie attempt at a minimal demo app, created after some trial and error.

I'd gratefully accept tips on how to make this more concise.

I deliberately chose to use CommandLineRunner to keep the app running "forever" because I wanted to browse to Actuator endpoints.

Issue45370Application.java:

package io.github.grahamhannington.issue45370;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Issue45370Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Issue45370Application.class);
        application.setEnvironmentPrefix("nco");
        application.run(args);
    }

    @Override
    public void run(String... args) throws Exception {
        while (true) {
            Thread.sleep(1000);
        }
    }

}

Test environment

Operating system: Ubuntu 24.04.1 LTS (Noble Numbat)

Java version: 17 (OpenJDK Runtime Environment, build 17.0.14+7-Ubuntu-124.04)

Current working directory:

additionallocation/
  application-custom-server-port.yaml

Contents of application-custom-server-port.yaml:

server:
  port: 8081

Example Java command line (as described in the test cases below, I tried various combinations of environment variable names, with and without the NCO_ environment prefix):

NCO_SPRING_CONFIG_ADDITIONALLOCATION=file:./additionallocation/ SPRING_PROFILES_ACTIVE=custom-server-port java -jar /u/myid/path/to/issue45370.jar > /u/myid/path/to/spring-boot.log

Test cases

Test case 1: expected failure: both variable names deliberately without environment prefix

Environment variables:

SPRING_CONFIG_ADDITIONALLOCATION=file:./additionallocation/
SPRING_PROFILES_ACTIVE=custom-server-port

Log excerpt:

The following 1 profile is active: "custom-server-port"

Interesting: I expected the app to not recognize SPRING_PROFILES_ACTIVE without the NCO_ prefix.

App uses default port 8080. That is, the app does not use the server port 8081 set in ./additionallocation/application-custom-server-port.yaml. The log reported this. I also tested this by browsing to the health endpoint at http://localhost:8080/actuator/health. I expected this. That is, I expected the app to not recognize SPRING_CONFIG_ADDITIONALLOCATION, and so the app does not find the profile-specific file that sets the "custom" server port.

Test case 2: unexpected failure: both variable names with environment prefix

Environment variables:

NCO_SPRING_CONFIG_ADDITIONALLOCATION=file:./additionallocation/
NCO_SPRING_PROFILES_ACTIVE=custom-server-port

Log excerpt:

No active profile set, falling back to 1 default profile: "default"

Interesting: this tells me the app does not recognize NCO_SPRING_PROFILES_ACTIVE; that is, with the NCO_ prefix. Is this a bug, or working as designed?

App uses default port 8080.

Test case 3: unexpected success: only one variable name with environment prefix

Environment variables:

NCO_SPRING_CONFIG_ADDITIONALLOCATION=file:./additionallocation/
SPRING_PROFILES_ACTIVE=custom-server-port

Log excerpt:

The following 1 profile is active: "custom-server-port"

App uses custom server port 8081 set in ./additionallocation/application-custom-server-port.yaml

@philwebb
Copy link
Member

philwebb commented May 7, 2025

Thanks for the reproducer @GrahamHannington. Given that we used this issue for the documentation update, I've opened a new one to deal with the bug. #45387

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
Development

No branches or pull requests

6 participants