1

I have a small application in Helidon start. It is mostly a REST interface, but I also want to start some background monitoring / logging on startup.

I would like that monitoring to be activated / deactivated by config. The issue I am facing is that the config is not being picked up if my class is instantiated manually.

Here is a very short code snippet :

Starting the application

public class Main {

    private Main() { }

    public static void main(final String[] args) throws IOException {
        Server server = startServer();

        CellarMonitoring monitoring = new CellarMonitoring();
        monitoring.start();
    }

    static Server startServer() {
        return Server.create().start();
    }
}

Starting monitoring or not based on Configuration :

package nl.lengrand.cellar;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

public class CellarMonitoring {

    @Inject
    @ConfigProperty(name = "monitoring.enabled", defaultValue = "true")
    private volatile boolean monitoringEnabled; <= Always false

    public void start(){
        if(monitoringEnabled) {
            System.out.println("Monitoring enabled by config. Starting up");
        }
        else System.out.println("Monitoring disabled by config");
    }
}

This code will always return "Monitoring disabled by config", whatever I do.

Accessing the config directly like described in the documentation is not really an option either since the onStartup method will never be fired.

What is the proper way to inject a class in my server so it can access the config as desired?

jlengrand
  • 12,152
  • 14
  • 57
  • 87

1 Answers1

3

Your question is actually about CDI.

In order for any kind of dependency injection to work with CDI, CDI must instantiate the thing to be injected. In this case, you instantiate the thing to be injected, so CDI never "sees" it, so it is never injected.

I am speculating here, but I'm guessing your use case is really just: "I'd like my CellarMonitoring component to be notified when CDI comes up. How do I do that?"

There are many answers to that question on this site and elsewhere. Essentially you take advantage of the fact that CDI will fire an event notifying any interested listeners in the initialization of the application scope. The application scope is effectively the lifespan of the application itself, so you can think of it as a startup event.

A full CDI tutorial is beyond the scope of this question and answer, but, to cut to the chase, here's a way to do it. I have had to make various assumptions, such as that you want CellarMonitoring to be singleton-like:

@ApplicationScoped
public class CellarMonitoring {

  @Inject
  @ConfigProperty(name = "monitoring.enabled", defaultValue = "true")
  private volatile boolean monitoringEnabled; // <= Always false

  public void start() {
    if (monitoringEnabled) {
      System.out.println("Monitoring enabled by config. Starting up");
    } else {
      System.out.println("Monitoring disabled by config");
    }
  }

  private void onStartup(@Observes @Initialized(ApplicationScoped.class) final Object event) {
    // The container has started.  You can now do what you want to do.
    this.start();
  }

}
Laird Nelson
  • 15,321
  • 19
  • 73
  • 127
  • 1
    I should mention if for some reason manual instantiation is something that you absolutely feel you must do for some reason not detailed here, you can make use of CDI's `Unmanaged` class: https://jakarta.ee/specifications/cdi/3.0/apidocs/jakarta/enterprise/inject/spi/Unmanaged.html – Laird Nelson Nov 13 '20 at 23:06
  • Hey there, many thanks! You are absolutely correct. I kept diving into the topic the past few days and things lead me to CDI. This is something I use in existing systems usually but should learn to know better. I had tried the onStartup method, but was missing the Observes annotation. Many thanks! – jlengrand Nov 14 '20 at 09:15
  • 1
    And super cool to see you're working on Helidon! Super nice project, I really like it since I it demoed a while back. – jlengrand Nov 14 '20 at 09:16