0

I am using cli-commons 1.4 library under which option class is present. I am creating an object of option class under my class that is CLIReader.java. Here is my code:

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.log4j.Logger;

public class CLIReader {

private String user = "";
private String password = "";
private String serverUrl = "";
private String streamName = "";
private static String compList;
private static String completeLogger;

public boolean readCommandLineParameters(String[] args) {
Logger log = Logger.getLogger(CLIReader.class);
Options options = new Options();

Option helpOpt = Option.builder("h").longOpt("help").desc("Usage Help").build();
options.addOption(helpOpt);

Option serverurl = Option.builder("url").longOpt("server url").desc("Server url").required().hasArg().argName("url").build();
options.addOption(serverurl);

Option userOpt = Option.builder("u").longOpt("user").desc("User Name").hasArg().argName("user").required().build();
options.addOption(userOpt);

Option pwdOpt = Option.builder("p").longOpt("password").desc("user password").hasArg().argName("password").required().build();
options.addOption(pwdOpt);
Option streamOpt = Option.builder("s").longOpt("streamName").desc("Stream Name").hasArg().argName("streamName").required().build();
options.addOption(streamOpt);

Option configOpt =   Option.builder("c").longOpt("componentList").desc("ComponentListPath").hasArg().argName("compList").required().build();
options.addOption(configOpt);

Option completeLoggerOpt = Option.builder("v").longOpt("completeLogger").desc("Complete Logger Info + Errors").hasArg().argName("yes/no").required().build();
options.addOption(completeLoggerOpt);

try {
  CommandLineParser parser = new DefaultParser();
  CommandLine cmd = parser.parse(options, args, true);

  if (cmd.hasOption("h")) {
    System.out.println("p");
    return false;
  }

  serverUrl = cmd.getOptionValue("url");
  user = cmd.getOptionValue("u");
  password = cmd.getOptionValue("p");
  streamName = cmd.getOptionValue("s");
  compList = cmd.getOptionValue("c");
  completeLogger = cmd.getOptionValue("v").toLowerCase();
}
  catch (Exception e) {
  log.info(e.getMessage());

  HelpFormatter formatter = new HelpFormatter();
  formatter.printHelp("User", options, true);

  return false;
}

return true;
}

public String getUser() {
return user;
}

public String getPassword() {
return password;
}

public String getServerUrl() {
return serverUrl;
}

public String getStreamName() {
return streamName;
}

public String getcompList() {
return compList;
}

public String getcompleteLogger() {
return completeLogger;
}

}

I have two scenarios, that is

Scenario 1

When I pass this command in command line prompt: java -jar abc.jar -u stack -p stackoverflow91 -url https://www.google.com -s streamA -c D:\abc.txt -v

I get output:

INFO - Missing required options: v
usage: abc  -c <compList> [-h] -p <password> -s <streamName>
   -u <user> -url <url> -v <yes/no>
-c,--componentList <compList>   ComponentListPath
-h,--help                       Usage Help
-p,--password <password>        user password
-s,--streamName <streamName>    Stream Name
-u,--user <user>                User Name
-url,--server url <url>         Server url
-v,--completeLogger <yes/no>    Complete Logger Info + Errors

which is correct as the value of v is missing

Scenario 2

When I pass this command in command line prompt: java -jar abc.jar -h or java -jar abc.jar -help

I get output:

INFO - Missing required options:url,s,u,p,c v
usage: abc  -c <compList> [-h] -p <password> -s <streamName>
   -u <user> -url <url> -v <yes/no>
-c,--componentList <compList>   ComponentListPath
-h,--help                       Usage Help
-p,--password <password>        user password
-s,--streamName <streamName>    Stream Name
-u,--user <user>                User Name
-url,--server url <url>         Server url
-v,--completeLogger <yes/no>    Complete Logger Info + Errors

But what I want here is when I pass this command, java -jar abc.jar -h or java -jar abc.jar -help

I want my output as "p" which is the message inside if condition.

Can anyone help me out to fine what in the above code I am doing wrong?

Tryout-1

public boolean readCommandLineParameters(String[] args) {
Logger log = Logger.getLogger(CLIReader.class);
Options options = new Options();
boolean hasHelp= false;
Option helpOpt = Option.builder("h").longOpt("help").desc("Usage Help").build();
options.addOption(helpOpt);

Option serverurl = Option.builder("url").longOpt("server url").desc(" Server url").required().hasArg().argName("url").build();
options.addOption(serverurl);

Option userOpt = Option.builder("u").longOpt("user").desc("User Name").hasArg().argName("user").required().build();
options.addOption(userOpt);

Option pwdOpt = Option.builder("p").longOpt("password").desc(" user password").hasArg().argName("password").required().build();
options.addOption(pwdOpt);

//Stream Option added 
Option streamOpt = Option.builder("s").longOpt("streamName").desc("Stream Name").hasArg().argName("streamName").required().build();
options.addOption(streamOpt);

Option configOpt = Option.builder("c").longOpt("componentList").desc("ComponentListPath").hasArg().argName("compList").required().build();
options.addOption(configOpt);

Option completeLoggerOpt = Option.builder("v").longOpt("completeLogger").desc("Complete Logger Info + Errors").hasArg().argName("yes/no").required().build();
options.addOption(completeLoggerOpt);

  try {
  CommandLineParser parser = new DefaultParser();
  CommandLine cmd = parser.parse(options, args, true);
  } 
  if (cmd.hasOption(helpOpt.getOpt()) || cmd.hasOption(helpOpt.getLongOpt()))    {
    System.out.println("yes");
    hasHelp = true;
}

  serverUrl = cmd.getOptionValue("url");
  user = cmd.getOptionValue("u");
  password = cmd.getOptionValue("p");
  streamName = cmd.getOptionValue("s");
  compList = cmd.getOptionValue("c");
  completeLogger = cmd.getOptionValue("v").toLowerCase();
}
catch (Exception e) {
  log.info(e.getMessage());

  HelpFormatter formatter = new HelpFormatter();
 formatter.printHelp("Abc ", options, true);
}

return hasHelp;
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • See this question: [Required options contradicts with help option](https://stackoverflow.com/questions/36720946/apache-cli-required-options-contradicts-with-help-option). You are hitting the same problem. – andrewJames Mar 28 '20 at 16:06
  • @andrewjames thanks for the quick support but it did'nt worked for me – Rajat Krishnan Mar 28 '20 at 19:06
  • I tried the same code but now also same result – Rajat Krishnan Mar 28 '20 at 19:09
  • OK - understood, but I don't know what "the same code" is, or how you used it. Can you show your revised code? You can edit your question, or ask a new one. – andrewJames Mar 28 '20 at 19:13
  • @andrewjames i have posted the edited code,please have look the code under tryout-1 section,Thank you – Rajat Krishnan Mar 29 '20 at 07:49
  • Does this answer your question? [Apache CLI: Required options contradicts with help option.](https://stackoverflow.com/questions/36720946/apache-cli-required-options-contradicts-with-help-option) – Software Engineer Mar 29 '20 at 14:13

2 Answers2

0

Your "tryout-1" code is still hitting the original problem.

The original problem is this: You define your Options object, and then you add various mandatory options to it using required(). Now, it doesn't matter what you do - as soon as you try to use -h on its own, your Options object will complain about those missing mandatory options.

The link I provided suggested ways around this problem - but you have not yet implemented any of them.

As one of the answers states:

The way we have addressed this situation in the past... is to parse the command line twice.

Create a different Options object, and add -h to it - but nothing else. Use that object first to test your command line. If the command line contains -h then print the usage text. Otherwise, use the main Commands object to process the command line for all the remaining options.

Here is a very basic, stripped-down version of that approach - it needs cleaning up, but illustrates the point:

private String serverUrl = "";

public void readCommandLineParameters(String[] args) {
    // Just the "help" option:
    Options helpOpts = new Options();
    Option helpOpt = Option.builder("h").longOpt("help").desc("Usage Help").build();
    helpOpts.addOption(helpOpt);

    // Everything else:
    Options allOpts = new Options();
    Option serverurl = Option.builder("url").longOpt("server url").required().desc("Server url")
            .hasArg().argName("url").build();
    allOpts.addOption(serverurl);

    boolean hasHelpOption = false;

    CommandLineParser parser = new DefaultParser();
    CommandLine cmd = null;
    try {
        cmd = parser.parse(helpOpts, args, true);
    } catch (ParseException ex) {
        Logger.getLogger(CLIReader.class.getName()).log(Level.SEVERE, null, ex);
    }

    if (cmd.hasOption("h")) {
        System.out.println("p");
        hasHelpOption = true;
    }

    if (!hasHelpOption) {
        CommandLine cmd2 = null;
        try {
            cmd2 = parser.parse(allOpts, args, true);
        } catch (ParseException ex) {
            Logger.getLogger(CLIReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        serverUrl = cmd2.getOptionValue("url");
    }
}

If you don't like this approach (there may be good reasons to not like it) then you can look at the other answers in that question. Maybe one of those will be a better fit for your needs.

andrewJames
  • 19,570
  • 8
  • 19
  • 51
0
   String s="--help";
String s1="[--help]";
String s2="[-h]";
String s3="-h";
  if(s.equals(args[0]) || s1.equals(args[0]))
  {
    System.out.println("usage: AutoLockComponent  -c <compList> -p <password> -s <streamName>\r\n" + 
        "       -u <user> -url <url> -v <yes/no>\r\n" + 
        " -c,--componentList <compList>   ComponentListPath\r\n" + 
        " -h,--help                       Usage Help\r\n" + 
        " -p,--password <password>        user password\r\n" + 
        " -s,--streamName <streamName>    Stream Name\r\n"  
        );
    System.exit(1);
  }

this worked for me