The ReactorDebugAgent is enabled even if the property reactor.debug-agent.enabled in the application.yml is set to false. Debugging the DebugAgentEnvironmentPostProcessor has revealed that the processor gets called so early that the property is not yet set, so the value null is returned. This leads to the activation of the agent. Our application fails at that point as the agent only works in a JDK, but in a JRE.

This PR fixes it and also keeps the stacktrace of the error of the failed activation. A workaround for our application is the following environment post processor, which of course needs to be enabled via spring.factories:

public class DisableDebugAgentEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        MapPropertySource mapPropertySource = new MapPropertySource(
                "disableDebugAgentEnvironmentPostProcessorPropertySource",
                ImmutableMap.of(
                        "spring.reactor.debug-agent.enabled", false
                )
        );
        environment.getPropertySources().addLast(mapPropertySource);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

Comment From: wilkinsona

Thanks for the PR, but if this isn't working, I think it would be better to fix the underlying cause than switching from opt-out to opt-in for the debug agent. DebugAgentEnvironmentPostProcessor is ordered with lowest precedence so it should run after ConfigFileApplicationListener has added the properties read from application.yml to the environment so I do not yet understand why it is apparently running too early.

Can we please take a step back and consider the problem a bit more before we trying to implement a solution. To that end, can you please open an issue with a small sample that reproduces the behaviour you have described?

Comment From: wilkinsona

FWIW, I just tried to reproduce the problem described above and was unable to do so. I used the following src/main/resources/application.yml file:

spring:
  reactor:
    debug-agent:
      enabled: false

The debug agent was disabled as expected.

Comment From: ntausch

We investigated the issue again and have the following finding which you might want to consider/document:

The property spring.reactor.debug-agent.enabled is not considered for de-activating the debug agent when it is placed within application.yml and if you use a spring-cloud-context component in your project. In the latter case the property is processed from the file bootstrap.yml. If the file and the property in this file is missing, the debug-agent gets activated (as opt-out failed).

You can reproduce the behavior if you just add the spring-cloud-context component to your project.

In our project we discovered this behavior:

Due to the use of the component 'spring-cloud-context' the environment post processing that also includes the activation of the debug-agent is run twice. The first time it uses a bootstrap.yml to read properties, the second time it uses the application.yml for that. This is intended behaviour by the spring-cloud component: https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html

As the debug-agent gets activated using an opt-out strategy, the first run with the currently missing bootstrap.yml activates the debug-agent. The second run, where the property for disabling the debug-agent is in place (in application.yml) and active, it has no effect anymore as the debug-agent is already running.

The solution is to move the property for disabling the debug-agent to the file bootstrap.yml.

Comment From: wilkinsona

Thanks for sharing your findings. This is an unfortunate side-effect of Spring Cloud using the separate bootstrap context. I've opened https://github.com/spring-cloud/spring-cloud-commons/issues/656 to see what can be done.