'Custom HealthIndicator not invoked during startup

I implemented a custom HealthIndicator for our application, which is working fine.

I noticed that when I run the application through my IDE (tested with both IntelliJ and Eclipse), the HealthIndicator.health() method is invoked during startup.

However, when I run the application by using the JAR file itself, the HealthIndicator.health() method is not invoked during startup of the application.

Why is the HealthIndicator.health() method not invoked during startup when I run it as a JAR file, and shouldn't it behave similarly as when running it through the IDE?



Solution 1:[1]

This is actually not really a bug, but a side effect caused by your IDE. You should be aware that Actuator endpoints are not only exposed over HTTP, but also over JMX. If you take a look at the documentation, you'll also see that the health endpoint is enabled by default on both HTTP and JMX.

Additionally, most IDEs, including IntelliJ and Eclipse, will enable a JMX agent when running the application through the IDE itself. This means that when the application is started, a JMX connection is made, which will in turn trigger the custom health indicator.

You can verify this quite easily, for example let's assume the following health indicator:

@Bean
public HealthIndicator alwaysUpHealthIndicator() {
    return () -> {
        log.info("Indicator invoked");
        return Health.up().withDetail("Foo", "Bar").build();
    };
}

If you change your IntelliJ run configuration and disable Enable JMX agent, you'll notice that the message no longer appears in the log.

Screenshot of IntelliJ configuration

Likewise, if you disable the health JMX endpoint, you'll also notice that you won't get the additional message within the logs:

management.endpoints.jmx.exposure.exclude=health

This means that you shouldn't rely on the HealthIndicator being executed during the startup of your application. If you have code that should be executed when your application is starting up, consider using an ApplicationRunner or CommandLineRunner bean. For example:

@Bean
public ApplicationRunner applicationRunner() {
    return args -> log.info("This will be invoked on startup");
}

Solution 2:[2]

I can't answer directly the question, but it looks like there is no real question here, if its a bug - submit a bug to spring boot team. Otherwise its just a statement that I fully agree with.

Either HelathIndicator health() method should be executed in both ways or none at all.

What you're describing sounds more like a weird bug, here is a dirty way to check what happens (remove it or course in production):

Inside the health method of the health indicator obtain a stack trace and print it on console. Analyze the stack trace and check that its not a result of some /health invocation through the HTTP (for example, maybe your IDE is configured to automatically call actuator's health upon start, who knows)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Mark Bramnik