Java system properties are key-value pairs of strings that the JVM keeps for the running program, such as java.version or user.home, and we can add our own with -D on the command line or with System.setProperty() in code. All properties live in one Properties object per JVM, so every class in the app reads the same values.
We use system properties for two jobs. We read the standard ones to learn about the environment, such as the Java version, the operating system or the user’s home folder, and we pass our own to configure an app or a library at startup without changing its code.
The following example reads a standard property, reads an app property with a default value, and sets a property in code. The app was started with java -Dapp.region=eu-west MealPlanner.java on Java 25.
String version = System.getProperty("java.version"); // "25.0.4.1"
String region = System.getProperty("app.region", "us-east"); // "eu-west" with -Dapp.region=eu-west, else "us-east"
String previous = System.setProperty("app.theme", "dark"); // null, there was no value before
String theme = System.getProperty("app.theme"); // "dark"
Notice that getProperty() returns a String or null, and the second argument replaces null with a default. We list the standard properties of Java 25, read and set them in code and on the command line, compare them with environment variables and point out the properties we should never change at runtime.
1. Standard System Properties in Java 25
The JVM fills in a set of standard properties at startup, before our main() method runs. Every Java runtime must provide the keys listed for System.getProperties(), and the values depend on the machine, the JDK build and the way we start the app.

The runtime properties describe the Java installation that runs the code. The sample values come from Eclipse Temurin 25.0.4.1.
| Key | Meaning | Example value |
|---|---|---|
| java.version | Java runtime version | 25.0.4.1 |
| java.version.date | Release date of that version | 2026-08-18 |
| java.vendor | Vendor of the runtime | Eclipse Adoptium |
| java.home | Installation folder of the runtime | C:\Program Files\Java\jdk-25 |
| java.vm.name | Name of the JVM | OpenJDK 64-Bit Server VM |
| java.class.version | Newest class file version the runtime can load | 69.0 |
| java.class.path | The classpath of the app | classes;lib\units.jar |
| java.library.path | Folders searched for native libraries | Depends on the OS |
| java.io.tmpdir | Default folder for temporary files | C:\Users\lokesh\AppData\Local\Temp\ |
The operating system and user properties describe the machine and the account that started the JVM.
| Key | Meaning | Windows | Linux |
|---|---|---|---|
| os.name | Operating system name | Windows 11 | Linux |
| os.arch | Architecture of the JVM build | amd64 | amd64 or aarch64 |
| os.version | Operating system version | 10.0 | Kernel version, such as 6.8.0 |
| file.separator | Separator inside a file path | \ | / |
| path.separator | Separator between entries in PATH or the classpath | ; | : |
| line.separator | End of a line in text files | \r\n | \n |
| user.name | Account name | lokesh | lokesh |
| user.home | Home folder of the account | C:\Users\lokesh | /home/lokesh |
| user.dir | Working directory when the JVM started | The folder of the command | The folder of the command |
The encoding properties changed in recent releases. Since Java 18 (JEP 400), file.encoding is UTF-8 on every platform, and native.encoding holds the encoding of the operating system, such as Cp1252 on many Windows machines. The properties stdout.encoding and stderr.encoding name the encoding of System.out and System.err.
Some properties from older tutorials are gone. The property java.ext.dirs belonged to the extension mechanism that Java 9 removed, so System.getProperty(“java.ext.dirs”) returns null on Java 25. To print every property of the current JVM, we start java with -XshowSettings:properties.
java -XshowSettings:properties -version
Property settings:
file.encoding = UTF-8
file.separator = /
java.class.version = 69.0
java.home = /opt/jdk-25.0.4.1+1
java.vendor = Eclipse Adoptium
java.version = 25.0.4.1
os.arch = amd64
os.name = Linux
path.separator = :
...
2. Reading System Properties in Code
The System class has two read methods for one property. The one-argument getProperty(key) either returns the value or null, and the two-argument version returns our default instead of null, so we use it whenever the property is optional.
String home = System.getProperty("user.home"); // the account's home folder
String missing = System.getProperty("app.unit"); // null
String unit = System.getProperty("app.unit", "metric"); // "metric"
String empty = System.getProperty(""); // IllegalArgumentException: key can't be empty
An empty key throws IllegalArgumentException and a null key throws NullPointerException, so keys from user input need a check first. Property values are always strings, and two helper methods parse them into other types.
String set = System.setProperty("app.retries", "5"); // null
Integer retries = Integer.getInteger("app.retries", 3); // 5
String bad = System.setProperty("app.timeout", "abc"); // null
Integer timeout = Integer.getInteger("app.timeout", 30); // 30, "abc" is not a number
boolean debug = Boolean.getBoolean("app.debug"); // false, the property is not set
The method Integer.getInteger() returns the default when the property is missing or not a valid number, so a typo in a start script never crashes the app. The same rule applies to Long.getLong(). The method Boolean.getBoolean() returns true only when the value is true in any letter case, so -Dapp.debug=yes reads as false.
To read all properties at once, we call System.getProperties(). It returns the live Properties object, and stringPropertyNames() gives the keys as a Set that we can filter and sort.
Properties all = System.getProperties();
Set<String> keys = all.stringPropertyNames();
List<String> osKeys = keys.stream().filter(key -> key.startsWith("os.")).sorted().toList(); // [os.arch, os.name, os.version]
3. Setting System Properties
We set our own properties either when the JVM starts or while it runs. Values from the command line are in place before any of our code runs, which is what libraries expect when they read a property once in a static initializer.
3.1. With -D on the Command Line
The java command takes any number of -Dkey=value options. The value runs until the next space, so a value with spaces goes in double quotes.
java -Dapp.region=eu-west -Dapp.retries=5 -Dapp.greeting="Good morning" -jar meal-planner.jar
The -D options must come before the main class, the source file or -jar file.jar, because everything after the main class goes to the program as arguments in args. For example, in java MealPlanner.java -Dapp.region=eu, the program gets -Dapp.region=eu as args[0], and System.getProperty(“app.region”) returns null. The article on the main method shows how to read such arguments.
When we cannot change the start command, for example in a container or a CI job, the environment variable JDK_JAVA_OPTIONS adds options to every java command. The older JAVA_TOOL_OPTIONS variable works for every tool that starts a JVM, and both print a Picked up line on System.err so the extra options stay visible in the logs.
set JDK_JAVA_OPTIONS=-Dapp.region=eu-west
java -jar meal-planner.jar
3.2. With System.setProperty() in Code
The method System.setProperty(key, value) sets a property for the whole JVM and returns the previous value, or null. The method System.clearProperty(key) removes a property and also returns the previous value.
String before = System.setProperty("app.season", "summer"); // null
String replaced = System.setProperty("app.season", "winter"); // "summer"
String removed = System.clearProperty("app.season"); // "winter"
String after = System.getProperty("app.season"); // null
A setting in code works for our own properties and for libraries that read a property on every call. It is too late for properties that the JDK or a library reads once at startup, which brings us to the properties we should leave alone.
3.3. Standard Properties We Should Not Change at Runtime
The JDK reads many standard properties once and caches the value, so changing them later has no effect or leaves the app in a mixed state. Changing a standard property at runtime may have unpredictable results. The following example changes user.dir, and File still resolves relative paths against the original working directory.
String start = new File("notes.txt").getAbsolutePath();
String oldDir = System.setProperty("user.dir", "/tmp");
String later = new File("notes.txt").getAbsolutePath();
boolean unchanged = start.equals(later); // true, File cached user.dir at startup
The same applies to file.encoding, java.home and line.separator. We set such properties with -D at startup, or we pass the value to the API as an argument, such as a Path for the folder or a Charset for the encoding.
4. Configuring an App With System Properties
Many libraries and frameworks read system properties, so -D is a common way to configure them without touching their files. Spring Boot treats system properties as a property source with a higher priority than application.properties, so -Dserver.port=9090 overrides the port in the file.
| Property | Read by | Effect |
|---|---|---|
| user.timezone | JDK | Sets the default time zone, as shown in setting the JVM time zone |
| javax.net.ssl.trustStore | JDK TLS | Uses another truststore for HTTPS connections |
| https.proxyHost, https.proxyPort | JDK HTTP clients | Routes HTTPS calls through a proxy |
| log4j2.configurationFile | Log4j2 | Loads another logging configuration |
| server.port, spring.profiles.active | Spring Boot | Overrides the port and the active profiles |
For example, a meal planner service runs the same JAR in staging and in production. The deployment script starts it with -Dapp.region=eu-west in Europe and -Dapp.region=us-east in the US, and the code reads System.getProperty(“app.region”, “us-east”) once at startup to pick the nearest recipe database.
We prefix our own keys with the app name, such as app. or mealplanner., so they never clash with the java., jdk. and sun. keys of the JDK or with library keys.
5. System Properties vs Environment Variables
Environment variables are name-value pairs of the operating system process, and we read them with System.getenv(). Both carry configuration into the app, but they differ in scope and in what the app can change.
| System properties | Environment variables | |
|---|---|---|
| Read with | System.getProperty() | System.getenv() |
| Set by | -D, System.setProperty(), the JVM | The shell, the OS, Docker, Kubernetes, CI |
| Visible to | This JVM only | This process and every child process |
| Changeable at runtime | Yes, with setProperty() | No, the map is unmodifiable |
| Key case | Case-sensitive | Case-insensitive on Windows |
Map<String, String> env = System.getenv();
String path = System.getenv("PATH"); // the PATH of the process, null when not set
String added = env.put("APP_REGION", "eu-west"); // UnsupportedOperationException
System properties are the recommended way to pass information to a Java process, because environment variables have a global effect and behave slightly differently on each OS. Containers are the exception, since Docker and Kubernetes pass configuration as environment variables, so cloud apps often read both and let one override the other.
6. Java System Properties FAQs
A few doubts about scope, the start command and the property file come up once teams pass their own settings through -D.
6.1. How do we list all system properties from the command line?
We run java -XshowSettings:properties -version. It prints every property of a fresh JVM, sorted by key, and exits. For a running app, jcmd <pid> VM.system_properties prints the current values, including those set in code.
6.2. Are system properties shared between threads?
Yes. All threads of one JVM share one Properties object, and Properties extends the synchronized Hashtable, so concurrent reads and writes are safe. A second JVM, even on the same machine, has its own properties.
6.3. Can we load system properties from a file?
Yes. We load the file into a Properties object and copy each entry with System.setProperty(), as in the following example with an in-memory file. The guide to reading and writing properties files covers real files.
Properties fromFile = new Properties();
fromFile.load(new StringReader("app.region=eu-west\napp.retries=4"));
fromFile.forEach((key, value) -> System.setProperty((String) key, (String) value));
Integer loaded = Integer.getInteger("app.retries", 3); // 4
6.4. Why does System.getProperty() return null for a -D value?
The -D option was placed after the main class or -jar file.jar, so the program got it as an argument, or the key has a typo, since keys are case-sensitive. Printing args or running jcmd <pid> VM.system_properties shows which one it is.
6.5. Does the Security Manager still restrict access to system properties?
No. Older code checked PropertyPermission through the Security Manager, but Java 24 disabled the Security Manager permanently (JEP 486), so every class can read and write every property.
7. Conclusion
Java system properties are one shared map of string keys and values per JVM. The JVM fills in the standard keys such as java.version, os.name and user.home, and we add our own with -D before the main class or with System.setProperty().
We read them with System.getProperty(key, default), or with Integer.getInteger() and Boolean.getBoolean() for typed values, and we leave the standard ones alone at runtime. For settings that must reach child processes or come from a container platform, environment variables are the better fit, and the Java tutorial links the other core topics.
8. References
- System.getProperties() (Java 25 API)
- The java Command (Java 25)
- JEP 400, UTF-8 by Default
- JEP 486, Permanently Disable the Security Manager
- Oracle Java Tutorials, System Properties
Happy Learning !!
Hey, good job, but!
You didn’t mentioned a real world example in which cases I can use these existed or custom defined properties?
HI , How to set the value to System.setProperty dynamic (from spring boot config server ) .
Informative and useful article. Java programmers are well known with java system properties and it is very important for the beginners to know about this. You have shared great post here, thanks for that.