Arguments, environment and exit codes
A program rarely lives on its own: it's started from a terminal, a script or a server, and it needs settings — a file name, a mode, a database address. There are three ways to get them: command-line arguments, environment variables and system properties. In return, the program reports whether it finished successfully with an exit code.
Command-line arguments
Everything written after the file name in the run command ends up in the args array — the parameter of the main method. In a compact file you can declare it: void main(String[] args). Arguments are separated by spaces, and a value with a space is put in quotes:
void main(String[] args) {
IO.println("Arguments: " + args.length);
for (String arg : args) {
IO.println(arg);
}
}Run:
java Main.java Anna "Oleg Petrov" 3Output:
Arguments: 3
Anna
Oleg Petrov
3All arguments are strings, even 3. A number is obtained with Integer.parseInt(args[2]). In IntelliJ IDEA arguments are set in the run settings: Run → Edit Configurations → Program arguments.
Environment variables
Environment variables are "name = value" pairs that the operating system passes to every program it starts. They usually hold what differs from computer to computer: the mode, service addresses, passwords. System.getenv("NAME") returns the value, or null if there is no such variable:
void main() {
String mode = System.getenv("APP_MODE");
if (mode == null) {
mode = "development";
}
IO.println("Mode: " + mode);
}Run in bash (in PowerShell the variable is set like this: $env:APP_MODE = "production"):
java Main.java
APP_MODE=production java Main.javaOutput:
Mode: development
Mode: productionSystem properties
System properties are settings of the JVM itself. Some are predefined: the Java version, the operating system name, the user's home folder. Your own properties are passed with the -Dname=value option — before the file name, otherwise it becomes an ordinary argument. The second argument of getProperty is a default value:
void main() {
IO.println("Java " + System.getProperty("java.version"));
IO.println("Language: " + System.getProperty("app.lang", "en"));
IO.println("Discount: " + Integer.getInteger("app.discount", 0) + "%");
}Run:
java -Dapp.lang=de -Dapp.discount=15 Main.javaOutput (your Java version may differ):
Java 25.0.4.1
Language: de
Discount: 15%Integer.getInteger reads a system property directly as a number. Other useful properties: user.home is the home folder, user.dir the current folder, os.name the operating system.
Exit code
When a program ends, it returns an integer to the operating system — the exit code. 0 means "success", any other number means "error". Scripts and build servers look at this code to decide whether to carry on. You set it with System.exit:
void main(String[] args) {
if (args.length == 0) {
System.err.println("Please specify a file name");
System.exit(1);
}
IO.println("Processing " + args[0]);
}Run without an argument and with one; echo $? in bash shows the exit code of the last command:
java Main.java
echo $?
java Main.java report.csv
echo $?Output:
Please specify a file name
1
Processing report.csv
0System.err is the stream for error messages: in a terminal it looks just like normal output, but it can be redirected separately. System.exit stops the JVM at once — even finally blocks don't run, so call it only at the very end, in main. If a program ends with an unhandled exception, the code is 1.
Common mistake
The program takes args[0] without checking that there are any arguments. Running it without them ends in an exception:
void main(String[] args) {
String name = args[0];
IO.println("Hello, " + name + "!");
}Output:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at Main.main(Main.java:2)Always check args.length and print a hint on how to run the program — as in the exit code example.