2

how can I Print adittional information to Command line Console?

Output now is:

C:\Users\admin\Desktop\java>java -jar pdf.jar
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
        at readDataIn.main(readDataIn.java:31)

Code:

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        try {
            String arg = args[0];
            fileNameSource = "import/" + arg + ".xml";
            fileNameTarget = "export/" + arg + ".pdf";
        } catch (Exception e) {
            // TODO: handle exception
            **System.out.println("Personal-Number is missing");**
            e.printStackTrace();
            
        }

How can i give the information out, that the Personal Number ist Missing?

Eminen
  • 21
  • 4
  • A better way might be to ask whats wrong with your code. Setting topic to the exception you are getting. IndexOutOfBound in your case, it helps others to search easily. – devilpreet Mar 09 '22 at 10:48

2 Answers2

1

First of all, as a general rule you should check for possible exceptions before they actually occur if that is possible, which in your case it definitely is. So instead of catching the ArrayIndexOutOfBounds insert an if statement that checks the length of the args array before accessing it.

if(args.length == 0){
   // no argument has been provided
   // handle error here
}

In terms of how to handle the error, there are many options available and depending of what you want to do either could be a good fit.

IllegalArgumentException

It is a common idiom in Java that whenever a function receives an invalid/ illegal argument to throw an IllegalArgumentException.

if (args.length == 0){
    throw new IllegalArgumentException("Personal number is missing");
}

This will print the message that you have provided and the stack trace. However if your application should be a Command Line Interface (CLI) you should not use this kind of error handling.

Print message & exit program

if (args.length == 0){
    // notice: "err" instead of "out": print to stderr instead of stdout
    System.err.println("Personal number is missing");
    // exit program with non-zero exit code as exit code == 0 means everything is fine
    System.exit(1);
}

For more information on stdout and stderr see this StackOverflow question. This is what many CLI applications and e.g. java itself does. When you type java fdsdfsdfs or some similar nonsense as an argument Java will give you an error message and exit with some non-zero return code ("1" in this case). It is also common that CLI applications print an error message and following some usage information on how to correctly use the application or provide a help command so a user can get more information. This happens for example if you just enter java without any parameters. So it is really up to you what you want to do.

If you are thinking of implementing a full featured CLI application with more (complex) commands with multiple options etc. you should consider using a CLI library like JCommander or Apache Commons CLI as parsing command line arguments can quickly get ugly. All these common things are already handled there.

Logging

In case your application is some script that will be executed in a non-interactive way logging the error to a file and exiting with a non-zero exit code might also be an option.

PS

Your code looks to me like it should not compile at all as you are not declaring a type for your variables fileNameSource and fileNameTarget. Use String or var here (assuming you're running > Java 11).

String fileNameSource = "import/" + arg + ".xml";
var fileNameTarget = "export/" + arg + ".pdf";

You might also need to consider that your program name is part of the args array, so you might have more than 0 values in the array and therefore might need to adjust the if statements above.

Mushroomator
  • 6,516
  • 1
  • 10
  • 27
0

You may be interested in picocli, which is a modern CLI library for Java and other JVM languages.

Picocli does some basic validation automatically, and results in very compact code that produces user-friendly applications. For example:

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "myapp", mixinStandardHelpOptions = true, version = "1.0",
        description = "This command does something useful.")
class MyApp implements Runnable {

    @Parameters(description = "File name (without extension) of the file to import and export.")
    private String personalNumber;

    @Override
    public void run() {
        String fileNameSource = "import/" + personalNumber + ".xml";
        String fileNameTarget = "export/" + personalNumber + ".pdf";

        // remaining business logic
    }

    public static void main(String[] args) {
        System.exit(new CommandLine(new MyApp()).execute(args));
    }
}

If I run this class without any parameters, the following message is printed to the standard error stream, and the process finished with exit code 2. (Exit codes are customizable.)

Missing required parameter: '<personalNumber>'
Usage: myapp [-hV] <personalNumber>
This command does something useful.
      <personalNumber>   File name (without extension) of the file to import
                           and export.
  -h, --help             Show this help message and exit.
  -V, --version          Print version information and exit.

The usage help message is created automatically from the descriptions of the command, and the descriptions of its options and positional parameters, but can be further customized.

Note how the mixinStandardHelpOptions = true annotation adds --help and --version options to the command. These options are handled by the library without requiring any further logic in the application.

Picocli comes with an annotation processor that makes it very easy to turn your application into a native image with GraalVM. Native images have faster startup time and lower runtime memory overhead compared to a Java VM.

Remko Popma
  • 35,130
  • 11
  • 92
  • 114