Writing main() method

args-inject is designed to process a commandline, therefore it logically has direct impact on public static main() method serving as the Java's entry point to the application.

While developer is given complete freedom on how to implement it, there is rarely a reason for any creativity. See below which implementation prototypes are recommended.

Straightforward approach

This code does exactly the needed minimum to have a functional main - imagine your set of commands and other settings there:

    public static void main(String[] args) throws Exception {
        final AnnottationAwareSetup setup = new AnnottationAwareSetup("myapp");
        setup.setDefaultSubCommand(DemoFileLister.class);
        final int exitCode = BasicArgsParser.process(setup, args);
        if (exitCode != 0) {
            System.exit(exitCode); // indicate failure to shell
        }
    }

Unit testing aware approach

The above main method is simple enough, but it still makes sense to split it into two parts if you wish to use utilize most of production code in your unit tests.

Look how it is done in the MiniCalc sample:

  • the part that constructs java mapping (setup)
    /**
     * Highest-possible level of invocation usable both from {@link #main} and from unit tests.
     *
     * @param args commandline arguments
     * @return true if successful
     * @throws Exception -
     */
    static int run(String... args) throws Exception {
        final AnnottationAwareSetup setup = new AnnottationAwareSetup("minicalc");
        setup.addSubCommand(DefaultHelpCommand.class);
        setup.addSubCommand(Plus.class);
        setup.addSubCommand(Minus.class);
        setup.addSubCommand(Logarithm.class);
        return BasicArgsParser.process(setup, args);
    }
  • the part that can call System.exit() which is illegal in JUnit
    public static void main(String[] args) throws Exception {
        final int exitCode = run(args);
        if (exitCode != 0) {
            System.exit(exitCode);
        }
    }

Then your junit test can use it like this:

            Assert.assertEquals(0, MiniCalc.run(args));

You can also be interrested in trapping stdout/stderr for testing; it's fairly simple; for inspiration, look into MiniCalcTest.java how it can be accomplished.