args4j with secret parameters

Args4j ( is a decent and compact library that makes it easy to parse command line parameters.

If you ever come across a case where you want to pass your app arguments like:

./myapp -dbUser foo -dbPassword s3cr3t

Then you’d be exposing the password to any other users on the system using ps (process show).

Instead, rather call the application using a wrapper script, and save the password in an environment variable as such:

export DBPASSWORD=s3cr3t
./myapp -dbUser foo

In order to achieve this, a decorator is needed so that we can treat environment variables as valid alternatives to options passed via the CLI:

public class DecoratedCmdLineParser extends CmdLineParser {

public DecoratedCmdLineParser(Object bean) {

public void parseArgument(String... args)
throws CmdLineException {

final List<String> allArgs = new ArrayList<>();

// Allow environment variables to override
getOptions().forEach(optionHandler -> {
final OptionDef option = optionHandler.option;
final String envVar = System.getenv(option.metaVar());
if (envVar != null) {

// Add regular command line args

allArgs.toArray(new String[allArgs.size()]));

Now you can go ahead using args4j in the conventional manner, but remember to use the decorated implementation of CmdLineParser:

private void runMain(String[] args) throws IOException {

final CmdLineParser parser = new DecoratedCmdLineParser(this);

try {
// Parse arguments

No doubts the decorator can be improved, so feedback/improvements is welcome.