DuncG
DuncG

Reputation: 15096

How to determine that Java is running on Windows

I wish to determine whether Java is running on Windows, and have seen many different suggestions which include various permutations of the System property os.name with startsWith / indexOf / contains / toLowerCase(Locale.ENGLISH) / toLowerCase(), or just File.separatorChar.

I scanned JDK source code to see whether there was a definitive answer (see below) and a few other SO posts which suggest:

String os = System.getProperty("os.name" /**, "<Surely os.name is never null?>" */);
List<Boolean> isWindows = List.of(
    os.startsWith("Windows"),
    os.contains("Windows"),
    os.toLowerCase().startsWith("windows"),
    os.toLowerCase().contains("windows"),
    os.toLowerCase(Locale.ENGLISH).contains("windows"),
    os.toLowerCase(Locale.ENGLISH).startsWith("windows"),
    File.separatorChar == '\\'
);
System.out.println("os.name       ="+os);
System.out.println("os.name(UTF-8)="+Arrays.toString(os.getBytes(StandardCharsets.UTF_8)));
System.out.println("isWindows     ="+isWindows);

Is there any permutation of OS / language installation which incorrectly identifies isWindows using the above conditions, where true/false is inconsistent or wrong?

// For Windows I would expect all true, such as:
os.name       =Windows 10
os.name(UTF-8)=[87, 105, 110, 100, 111, 119, 115, 32, 49, 48]
isWindows     =[true, true, true, true, true, true, true]

// For non-Windows I would expect all false such as:
os.name       =Linux
os.name(UTF-8)=[76, 105, 110, 117, 120]
isWindows     =[false, false, false, false, false, false, false]

JDK source code examples

For reference, this is where isWindows is detected in Open JDK17 source code (from a recent git fetch NOT final release candidate):

src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java

    System.getProperty("os.name").toLowerCase().startsWith("win"));
        
src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java    
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java

    isWindows = System.getProperty("os.name").startsWith("Windows"))

src/java.desktop/share/classes/sun/font/FontUtilities.java

    isWindows = System.getProperty("os.name", "unknownOS").startsWith("Windows");
        
src/java.base/share/classes/java/util/zip/ZipFile.java
src/java.desktop/share/classes/sun/awt/OSInfo.java

    VM.getSavedProperty("os.name").contains("Windows")
    System.getProperty("os.name").contains("Windows")
    
src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java

    boolean isWindows = osName != null && osName.contains("Windows");
        
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java

    boolean isWin32 = (File.separatorChar == '\\')
    
src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java
Note that I've omitted this test in case of confusion with Darwin OS:

    String os = System.getProperty("os.name").toLowerCase();
    if (os.indexOf("win") >= 0) {
        platform = Platform.WINDOWS;
    }

Upvotes: 7

Views: 2914

Answers (1)

DuncG
DuncG

Reputation: 15096

After noting the various comments and other posts, I've not found a reason not to continue using the isWindows check I currently have in my code, which is simply the first test listed:

boolean isWindows = System.getProperty("os.name").startsWith("Windows");

The first six tests in my question appear to detect isWindows correctly, but not the last item File.separatorChar == '\\' (as that is also true on OS/2).

Note that in Turkish the lower case value of "I" is not equal to "i". Try:

"I".toLowerCase(Locale.forLanguageTag("TR")).equals("i") // char:305
"i".toUpperCase(Locale.forLanguageTag("TR")).equals("I") // char:304

Maybe this explains why some developers use .toLowerCase(Locale.ENGLISH) but nothing changes for any of the test results unless os.name property is uppercase in Turkish installation.

Thanks for all the suggestions.

Upvotes: 3

Related Questions