Does Java have any class to work with command line arguments?

13

I need to create a Java desktop app, and with this pass several parameters of the type:

  

java myapp.jar -DB c: \ base.db -user admin -pass admin

Is there an easy way to get these parameters? Something like this:

    public static void main(String args[]) {
         TipoMap<String> argum = TipoMap(args);
         usuario = agum.get("user");  
         senha = argum.get("senha");
         ...
    } 
    
asked by anonymous 13.11.2015 / 18:32

3 answers

12

One of the best-known libraries that does this is Commons.CLI . With it you can treat arguments as AP wants. With it it establishes the possible options, the format and then it processes what came by the command line, determining what to execute. It is very intuitive and has good abstraction to stick to the final result and not the mechanism of reading the arguments.

Documentation example:

// create the command line parser
CommandLineParser parser = new DefaultParser();

// create the Options
Options options = new Options();
options.addOption( "a", "all", false, "do not hide entries starting with ." );
options.addOption( "A", "almost-all", false, "do not list implied . and .." );
options.addOption( "b", "escape", false, "print octal escapes for nongraphic "
                                         + "characters" );
options.addOption( OptionBuilder.withLongOpt( "block-size" )
                                .withDescription( "use SIZE-byte blocks" )
                                .hasArg()
                                .withArgName("SIZE")
                                .create() );
options.addOption( "B", "ignore-backups", false, "do not list implied entried "
                                                 + "ending with ~");
options.addOption( "c", false, "with -lt: sort by, and show, ctime (time of last " 
                               + "modification of file status information) with "
                               + "-l:show ctime and sort by name otherwise: sort "
                               + "by ctime" );
options.addOption( "C", false, "list entries by columns" );

String[] args = new String[]{ "--block-size=10" };

try {
    // parse the command line arguments
    CommandLine line = parser.parse( options, args );

    // validate that block-size has been set
    if( line.hasOption( "block-size" ) ) {
        // print the value of block-size
        System.out.println( line.getOptionValue( "block-size" ) );
    }
}
catch( ParseException exp ) {
    System.out.println( "Unexpected exception:" + exp.getMessage() );
}
    
13.11.2015 / 19:27
5

Yes, there is.

Do you know that class main(String[] args) which is the entry point of your application? It is in this variable args that the parameters entered when calling the application are stored.

When you do

  

java myapp.jar param1 param2 param3

All these parameters will be in array args

I find it interesting to read this

See an example of how to use them:

public class Program {
    public static void main (String[] args) {
        for (String s: args) {
            System.out.println(s);
        }
    }
} 
    
13.11.2015 / 18:41
3

If you use the Spring framework to do dependency injection and manage your beans, you can decouple your code from doing searches on command lines and simply inject values read from the environment.

Example:

@Component
public class MeuComponente {

    @Value("${usuario}")
    private String usuario;

}

See documentation and you'll see that injected values are read from a variety of sources, the first being command-line arguments, but also including Java's system properties, environment variables, and the Spring configuration file.

This approach is flexible and makes it easy to test components individually, as well as allowing multiple system configuration mechanisms. For example, the user can set the database as an environment variable while the password is passed via the command line argument and other default settings are defined in the application.properties file that goes along with the system.

And if at any point you need to access the arguments more directly, just inject ApplicationArguments . Example:

@Component
public class MeuComponente {

    @Autowired
    public MeuComponente(ApplicationArguments args) {
        List<String> dbs = arg.getOptionValues("DB");
        if (!dbs.isEmpty()) {
            carregaDB(dbs.get(0));
        }
    }

}

Of course, if you want to accept arguments more elaborately than in native operating system programs, it's better to use another library (like the one cited in the @bigown response), although my general recommendation would be simply do not use Java.

    
17.11.2015 / 07:57