Simple CDI Magic: Command Line Apps with Weld and Static Producers

This technical guide demonstrates how to effectively bootstrap a CDI container in a Java SE command-line environment using Weld. It presents a practical solution for passing command-line arguments to managed beans through static producer methods, providing a clean and maintainable approach to dependency injection in standalone Java applications. The implementation showcases a singleton main class that manages the container lifecycle while maintaining proper separation of concerns.

2 Minutes reading time

Behold the masterpiece that AI hallucinated while reading this post:

"How Little Weld Learned to Share His Command Line Toys"

(after I fed it way too many marketing blogs and memes)

Created using DALL-E 3

AI-Generated: How Little Weld Learned to Share His Command Line Toys

It is possible to use CDI and Weld in a Java command line program. There are several options to bootstrap the CDI container. Weld offers a special Main class that does the job for us. But sometimes we just want to shield the CDI dependencies and provide our own main method. Now comes the tricky part: how do we pass command line arguments to the container, or even boot managed beans by injecting command line argument?

The answer is simple: use a static producer method! Here is an example:

@Singleton
public final class Main {
    private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);


    private static Configuration CONFIGURATION;
    @Produces
    public static Configuration configuration() {
        return CONFIGURATION;
    }


    @Inject
    ProjectSpecificBean instance;
    public void run() throws IOException {
        // Use injected instace
    }
    public static void main(String[] args) throws IOException {
        // Initialize the Configurtation instance by command line arguments
        // and store it in a static field. Now it is available by the producer method
        CONFIGURATION = new Configuration(args);


        // Initialize Weld
        Weld theWeld = new Weld();
        WeldContainer theContainer = theWeld.initialize();


        // Execute the run method
        theContainer.instance().select(Main.class).get().run();


        // Shutting down Weld again
        theWeld.shutdown();
    }
}

Note that ProjectSpecificBean requires a container managed Configuration instance. This is acquired by the configuration() static producer method.

Quite simple. I really love CDI, even in a Java SE environment.

Git revision: 2e692ad