I would like to determine the operating system of the host that my Java program is running programmatically (for example: I would like to be able to load different properties based on whether I am on a Windows or Unix platform). What is the safest way to do this with 100% reliability?
22 Answers
You can use:
System.getProperty("os.name")
P.S. You may find this code useful:
class ShowProperties {
public static void main(String[] args) {
System.getProperties().list(System.out);
}
}
All it does is print out all the properties provided by your Java implementations. It'll give you an idea of what you can find out about your Java environment via properties. :-)

- 219,335
- 46
- 382
- 435
-
8I'm using `Windows 10` and yet `os.name` gives me `Windows 8.1`. Why is that? Where is this coming from? – Brian Feb 07 '16 at 19:59
-
11nvm found https://stackoverflow.com/questions/31909107/javas-os-name-for-windows-10 – Brian Feb 07 '16 at 20:00
As indicated in other answers, System.getProperty provides the raw data. However, the Apache Commons Lang component provides a wrapper for java.lang.System with handy properties like SystemUtils.IS_OS_WINDOWS
, much like the aforementioned Swingx OS util.

- 27,789
- 26
- 218
- 353

- 3,787
- 3
- 17
- 10
Oct. 2008:
I would recommend to cache it in a static variable:
public static final class OsUtils
{
private static String OS = null;
public static String getOsName()
{
if(OS == null) { OS = System.getProperty("os.name"); }
return OS;
}
public static boolean isWindows()
{
return getOsName().startsWith("Windows");
}
public static boolean isUnix() // and so on
}
That way, every time you ask for the Os, you do not fetch the property more than once in the lifetime of your application.
February 2016: 7+ years later:
There is a bug with Windows 10 (which did not exist at the time of the original answer).
See "Java's “os.name” for Windows 10?"
-
6I agree with the getOSName function, on the basis of OAOO (once and only once); however, the caching is totally redundant given the speed of hash lookups. – C. K. Young Oct 23 '08 at 04:02
-
7Totally redundant might be a bit harsh, hash lookups are more expensive than accessing a reference. It all depends on the context. – Craig Day Oct 23 '08 at 04:04
-
2Good points... Feel free to down-vote if you think it is a bad practice ;) – VonC Oct 23 '08 at 04:10
-
6I reread this answer. If you are going to cache, cache the values of `isWindows`, `isUnix`, etc. That way you save on the string comparison time also. – C. K. Young Mar 19 '15 at 14:48
-
@ChrisJester-Young I agree (I didn't remember this 6.5+ years old answer). Could you edit it accordingly? – VonC Mar 19 '15 at 14:49
-
2@Brian True. I have edited this very old answer accordingly, to refer to the more recent one. – VonC Feb 07 '16 at 20:18
-
1In the days of Windows 10 you can imagine why this was a bad practice. Please do not `if(getOsName().startsWith("Windows 9")) { /* 95 and 98 */ } else { }` – Doomjunky Aug 29 '17 at 01:41
some of the links in the answers above seem to be broken. I have added pointers to current source code in the code below and offer an approach for handling the check with an enum as an answer so that a switch statement can be used when evaluating the result:
OsCheck.OSType ostype=OsCheck.getOperatingSystemType();
switch (ostype) {
case Windows: break;
case MacOS: break;
case Linux: break;
case Other: break;
}
The helper class is:
/**
* helper class to check the operating system this Java VM runs in
*
* please keep the notes below as a pseudo-license
*
* http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java
* compare to http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/Os.java
* http://www.docjar.com/html/api/org/apache/commons/lang/SystemUtils.java.html
*/
import java.util.Locale;
public static final class OsCheck {
/**
* types of Operating Systems
*/
public enum OSType {
Windows, MacOS, Linux, Other
};
// cached result of OS detection
protected static OSType detectedOS;
/**
* detect the operating system from the os.name System property and cache
* the result
*
* @returns - the operating system detected
*/
public static OSType getOperatingSystemType() {
if (detectedOS == null) {
String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
if ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)) {
detectedOS = OSType.MacOS;
} else if (OS.indexOf("win") >= 0) {
detectedOS = OSType.Windows;
} else if (OS.indexOf("nux") >= 0) {
detectedOS = OSType.Linux;
} else {
detectedOS = OSType.Other;
}
}
return detectedOS;
}
}

- 15,016
- 11
- 93
- 186
-
4(OS.indexOf("darwin") >= 0) can never be true because it comes after (OS.indexOf("win") >= 0) – William Dec 09 '13 at 11:32
-
22The code above *may* have locale issues, since it uses toLowerCase(), which is locale sensitive. Where this matters is particularly when converting i's to lower/upper case, since in Turkey, I becomes lower case undotted i (ı), and i becomes upper case dotted i (İ). So "WINDOWS".toLowerCase().indexOf("win") will return -1 in Turkey. Always pass a locale when doing a lower case of a particular language, ie "WINDOWS".toLowerCase(Locale.ENGLISH).indexOf("win") will work in Turkey. – James Roper Jul 14 '14 at 00:40
The following JavaFX classes have static methods to determine current OS (isWindows(),isLinux()...):
- com.sun.javafx.PlatformUtil
- com.sun.media.jfxmediaimpl.HostUtils
- com.sun.javafx.util.Utils
Example:
if (PlatformUtil.isWindows()){
...
}

- 3,091
- 2
- 25
- 32
-
5Please note that the access to "com/sun/javafx/*" is discouraged now (checked it with JDK 1.8.0_121). – Michael Marton Jan 14 '18 at 12:27
-
1
-
@HummelingEngineeringBV: I guess it was a mistake from my side. I am working with eclipse Neon 4.6.3 and the "Java Build Path" shows several "Discouraged: com/sun/javafx/**" warnings. However, as I found out, this happens to be an eclipse-bug and/or -feature (see [link](https://stackoverflow.com/questions/24743027/eclipse-gives-warning-on-access-restriction-for-jfxrt-jar-classes)). – Michael Marton Jul 11 '18 at 11:01
-
2I have to correct myself one more time. Beginning with Java 9/10+, several "com.sun.*" packages/APIs are about to be removed. Check out [this link](https://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-F7696E02-A1FB-4D5A-B1F2-89E7007D4096) for more info. I actually stumbled over this because we use some of these packages. Migrating to eclipse 4.8/JDK 10, we now have to fix these and several other compiler errors due to missing references. – Michael Marton Aug 16 '18 at 20:00
TL;DR
For accessing OS use: System.getProperty("os.name")
.
But WAIT!!!
Why not create a utility class, make it reusable! And probably much faster on multiple calls. Clean, clear, faster!
Create a Util class for such utility functions. Then create public enums for each operating system type.
public class Util {
public enum OS {
WINDOWS, LINUX, MAC, SOLARIS
};// Operating systems.
private static OS os = null;
public static OS getOS() {
if (os == null) {
String operSys = System.getProperty("os.name").toLowerCase();
if (operSys.contains("win")) {
os = OS.WINDOWS;
} else if (operSys.contains("nix") || operSys.contains("nux")
|| operSys.contains("aix")) {
os = OS.LINUX;
} else if (operSys.contains("mac")) {
os = OS.MAC;
} else if (operSys.contains("sunos")) {
os = OS.SOLARIS;
}
}
return os;
}
}
Now, you can easily invoke class from any class as follows,(P.S. Since we declared os variable as static, it will consume time only once to identify the system type, then it can be used until your application halts. )
switch (Util.getOS()) {
case WINDOWS:
//do windows stuff
break;
case LINUX:
and That is it!

- 3,788
- 30
- 31
-
5I want to use this piece of code in an open-source project (https://github.com/openhab/openhab-addons), is this okay with you? – Consti P Jan 11 '20 at 20:29
-
4
-
Why? It's not cleaner or clearer, and I doubt it's really much faster, either. – pabrams Mar 12 '23 at 07:55
-
Go ahead and put rationale for why you said so. I am happy to change the code if you have any reasonable evidence... Be reasonable and clarify your comment please, so that I can improve my 7-8 years old answer... – Memin Mar 13 '23 at 01:51
A small example of what you're trying to achieve would probably be a class
similar to what's underneath:
import java.util.Locale;
public class OperatingSystem
{
private static String OS = System.getProperty("os.name", "unknown").toLowerCase(Locale.ROOT);
public static boolean isWindows()
{
return OS.contains("win");
}
public static boolean isMac()
{
return OS.contains("mac");
}
public static boolean isUnix()
{
return OS.contains("nux");
}
}
This particular implementation is quite reliable and should be universally applicable. Just copy and paste it into your class
of choice.

- 164
- 1
- 11

- 245
- 2
- 8
-
Why make it so complicated? System.getProperty("os.name") is sufficient. Don't bother with the unnecessary fluff. – pabrams Mar 12 '23 at 07:57
Try this,simple and easy
System.getProperty("os.name");
System.getProperty("os.version");
System.getProperty("os.arch");

- 1,241
- 10
- 18
If you're interested in how an open source project does stuff like this, you can check out the Terracotta class (Os.java) that handles this junk here:
http://svn.terracotta.org/svn/tc/dso/trunk/code/base/common/src/com/tc/util/runtime/- http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/
And you can see a similar class to handle JVM versions (Vm.java and VmVersion.java) here:

- 1
- 1

- 69,183
- 25
- 122
- 167
-
2
-
also suffers from the same issue identified by James Roper in [Wolfgang Fahl's answer](http://stackoverflow.com/a/18417382/814422) -- use of `toLowerCase` without specifying a locale – kbolino Mar 12 '16 at 14:52
I think following can give broader coverage in fewer lines
import org.apache.commons.exec.OS;
if (OS.isFamilyWindows()){
//load some property
}
else if (OS.isFamilyUnix()){
//load some other property
}
More details here: https://commons.apache.org/proper/commons-exec/apidocs/org/apache/commons/exec/OS.html

- 5,380
- 2
- 27
- 34
If you're working in a security sensitive environment, then please read this through.
Please refrain from ever trusting a property obtained via the System#getProperty(String)
subroutine! Actually, almost every property including os.arch
, os.name
, and os.version
isn't readonly as you'd might expect — instead, they're actually quite the opposite.
First of all, any code with sufficient permission of invoking the System#setProperty(String, String)
subroutine can modify the returned literal at will. However, that's not necessarily the primary issue here, as it can be resolved through the use of a so called SecurityManager
, as described in greater detail over here.
The actual issue is that any user is able to edit these properties when running the JAR
in question (through -Dos.name=
, -Dos.arch=
, etc.). A possible way to avoid tampering with the application parameters is by querying the RuntimeMXBean
as shown here. The following code snippet should provide some insight into how this may be achieved.
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
for (String argument : arguments) {
if (argument.startsWith("-Dos.name") {
// System.getProperty("os.name") altered
} else if (argument.startsWith("-Dos.arch") {
// System.getProperty("os.arch") altered
}
}

- 164
- 1
- 11
-
File.separator does not look like a serious solution. Is there any other way to do it? – Čamo Feb 25 '21 at 10:27
-
Yes! There actually is quite an elegant way of detecting tampering with the system properties. I'll update the answer accordingly. But please be aware that a check can only do so much - if a person has physical access to your application, it **will be possible** to break it - no matter how sophisticated the check. – Theikon Feb 26 '21 at 14:39
Below code shows the values that you can get from System API, these all things you can get through this API.
public class App {
public static void main( String[] args ) {
//Operating system name
System.out.println(System.getProperty("os.name"));
//Operating system version
System.out.println(System.getProperty("os.version"));
//Path separator character used in java.class.path
System.out.println(System.getProperty("path.separator"));
//User working directory
System.out.println(System.getProperty("user.dir"));
//User home directory
System.out.println(System.getProperty("user.home"));
//User account name
System.out.println(System.getProperty("user.name"));
//Operating system architecture
System.out.println(System.getProperty("os.arch"));
//Sequence used by operating system to separate lines in text files
System.out.println(System.getProperty("line.separator"));
System.out.println(System.getProperty("java.version")); //JRE version number
System.out.println(System.getProperty("java.vendor.url")); //JRE vendor URL
System.out.println(System.getProperty("java.vendor")); //JRE vendor name
System.out.println(System.getProperty("java.home")); //Installation directory for Java Runtime Environment (JRE)
System.out.println(System.getProperty("java.class.path"));
System.out.println(System.getProperty("file.separator"));
}
}
Answers:-
Windows 7
6.1
;
C:\Users\user\Documents\workspace-eclipse\JavaExample
C:\Users\user
user
amd64
1.7.0_71
http://java.oracle.com/
Oracle Corporation
C:\Program Files\Java\jre7
C:\Users\user\Documents\workspace-Eclipse\JavaExample\target\classes
\

- 1
- 46
- 174
- 282
A bit shorter, cleaner (and eagerly computed) version of the top answers:
switch(OSType.DETECTED){
...
}
The helper enum:
public enum OSType {
Windows, MacOS, Linux, Other;
public static final OSType DETECTED;
static{
String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
if ((OS.contains("mac")) || (OS.contains("darwin"))) {
DETECTED = OSType.MacOS;
} else if (OS.contains("win")) {
DETECTED = OSType.Windows;
} else if (OS.contains("nux")) {
DETECTED = OSType.Linux;
} else {
DETECTED = OSType.Other;
}
}
}

- 1,508
- 3
- 15
- 24
-
The answer is just System.getProperty("os.name"). Nobody wants to do all this extra work. Why bother? – pabrams Mar 12 '23 at 07:56
I find that the OS Utils from Swingx does the job.

- 19,247
- 4
- 40
- 67
-
2The above link seems to be broken, probably due to SwingX introducing branches; the 1.6 release is here: https://swingx.dev.java.net/source/browse/swingx/tags/SwingX-1-6/src/java/org/jdesktop/swingx/util/OS.java?view=markup – David Moles Mar 03 '10 at 14:38
-
1@David Moles, thanks. the link was ok when I answered- I've now updated it with your one. – Richard Harrison Mar 03 '10 at 17:41
-
2Latest version is here: http://java.net/projects/swingx/sources/svn/content/trunk/swingx-core/src/main/java/org/jdesktop/swingx/util/Utilities.java – Vladislav Rastrusny Jun 15 '11 at 13:29
-
Oracle shut down the java.net site, so Someone who cares should edit this answer to fix the link. – MarkHu Oct 24 '21 at 06:19
-
I found a version here https://github.com/tmyroadctfig/swingx/blob/master/swingx-common/src/main/java/org/jdesktop/swingx/util/OS.java - thanks @MarkHu for notifying the broken link – Richard Harrison Nov 05 '21 at 12:59
String osName = System.getProperty("os.name");
System.out.println("Operating system " + osName);

- 55,989
- 15
- 126
- 162

- 403
- 1
- 6
- 13
I liked Wolfgang's answer, just because I believe things like that should be consts...
so I've rephrased it a bit for myself, and thought to share it :)
/**
* types of Operating Systems
*
* please keep the note below as a pseudo-license
*
* helper class to check the operating system this Java VM runs in
* http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java
* compare to http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/Os.java
* http://www.docjar.com/html/api/org/apache/commons/lang/SystemUtils.java.html
*/
public enum OSType {
MacOS("mac", "darwin"),
Windows("win"),
Linux("nux"),
Other("generic");
private static OSType detectedOS;
private final String[] keys;
private OSType(String... keys) {
this.keys = keys;
}
private boolean match(String osKey) {
for (int i = 0; i < keys.length; i++) {
if (osKey.indexOf(keys[i]) != -1)
return true;
}
return false;
}
public static OSType getOS_Type() {
if (detectedOS == null)
detectedOS = getOperatingSystemType(System.getProperty("os.name", Other.keys[0]).toLowerCase());
return detectedOS;
}
private static OSType getOperatingSystemType(String osKey) {
for (OSType osType : values()) {
if (osType.match(osKey))
return osType;
}
return Other;
}
}

- 10,106
- 12
- 75
- 118
-
It seems like "darwin" can never be matched because checking "win" would already cause Windows to be returned. – tvkanters Mar 29 '14 at 11:54
-
-
3Congratulations, you've reimplemented sun.awt.OSInfo#getOSType :) – Kirill Gamazkov Jan 22 '16 at 15:44
-
1HHHHH... good one... @Kirill Gamazkov I didn't find it back then.. thanks for pointing it out – TacB0sS Apr 27 '18 at 20:13
You can just use sun.awt.OSInfo#getOSType() method

- 3,277
- 1
- 18
- 22
-
This should be the best answer! I was just checking if someone already has mentioned this over here. – Martin Krajčírovič Aug 23 '18 at 17:14
-
Any workaround for this being 'restricted API'? I'd like to try using this but it gives me that warning in Eclipse. I can use an older jre (e.g. jre1.8.0_171), but the latest 1.8 jres have it marked as restricted. – Brian_Entei May 07 '20 at 16:50
-
Whole 'sun' package is deprecated, I can't imagine how one could workaround this. Seems that it's just `System.getProperty("os.name")` and then checks if the property contains 'Windows', 'Linux', 'Solaris' or 'OS X', so it's basically the same as Vishal Chaudhari's answer – Kirill Gamazkov Jul 23 '20 at 11:26
This code for displaying all information about the system os type,name , java information and so on.
public static void main(String[] args) {
// TODO Auto-generated method stub
Properties pro = System.getProperties();
for(Object obj : pro.keySet()){
System.out.println(" System "+(String)obj+" : "+System.getProperty((String)obj));
}
}

- 156
- 5
In com.sun.jna.Platform class you can find useful static methods like
Platform.isWindows();
Platform.is64Bit();
Platform.isIntel();
Platform.isARM();
and much more.
If you use Maven just add dependency
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.2.0</version>
</dependency>
Otherwise just find jna library jar file (ex. jna-5.2.0.jar) and add it to classpath.

- 508
- 3
- 19
Just use com.sun.javafx.util.Utils
as below.
if ( Utils.isWindows()){
// LOGIC HERE
}
OR USE
boolean isWindows = OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS);
if (isWindows){
// YOUR LOGIC HERE
}

- 7,006
- 27
- 78
- 121
Since google points "kotlin os name" to this page, here's the Kotlin version of @Memin 's answer:
private var _osType: OsTypes? = null
val osType: OsTypes
get() {
if (_osType == null) {
_osType = with(System.getProperty("os.name").lowercase(Locale.getDefault())) {
if (contains("win"))
OsTypes.WINDOWS
else if (listOf("nix", "nux", "aix").any { contains(it) })
OsTypes.LINUX
else if (contains("mac"))
OsTypes.MAC
else if (contains("sunos"))
OsTypes.SOLARIS
else
OsTypes.OTHER
}
}
return _osType!!
}
enum class OsTypes {
WINDOWS, LINUX, MAC, SOLARIS, OTHER
}

- 6,566
- 4
- 45
- 57
For getting OS name, simply use:
Platform.getOS()
Lets say you want to see if platform is linux:
if (Platform.getOS().equals(Platform.OS_LINUX)) {
}
Similarly Platform class have defined constants for others operating system names. Platform class is part of org.eclipse.core.runtime
package.

- 515
- 2
- 11