How do you determine 32 or 64 bit architecture of Windows using Java?

58,495

Solution 1

Please note, the os.arch property will only give you the architecture of the JRE, not of the underlying os.

If you install a 32 bit jre on a 64 bit system, System.getProperty("os.arch") will return x86

In order to actually determine the underlying architecture, you will need to write some native code. See this post for more info (and a link to sample native code)

Solution 2

I don't exactly trust reading the os.arch system variable. While it works if a user is running a 64bit JVM on a 64bit system. It doesn't work if the user is running a 32bit JVM on a 64 bit system.

The following code works for properly detecting Windows 64-bit operating systems. On a Windows 64 bit system the environment variable "Programfiles(x86)" will be set. It will NOT be set on a 32-bit system and java will read it as null.

boolean is64bit = false;
if (System.getProperty("os.name").contains("Windows")) {
    is64bit = (System.getenv("ProgramFiles(x86)") != null);
} else {
    is64bit = (System.getProperty("os.arch").indexOf("64") != -1);
}

For other operating systems like Linux or Solaris or Mac we may see this problem as well. So this isn't a complete solution. For mac you are probably safe because apple locks down the JVM to match the OS. But Linux and Solaris, etc.. they may still use a 32-bit JVM on their 64-bit system. So use this with caution.

Solution 3

I used the command prompt (command --> wmic OS get OSArchitecture) to get the OS architecture. The following program helps get all the required parameters:

import java.io.*;

public class User {
    public static void main(String[] args) throws Exception {

        System.out.println("OS --> "+System.getProperty("os.name"));   //OS Name such as Windows/Linux

        System.out.println("JRE Architecture --> "+System.getProperty("sun.arch.data.model")+" bit.");       // JRE architecture i.e 64 bit or 32 bit JRE

        ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c","wmic OS get OSArchitecture");
        builder.redirectErrorStream(true);
        Process p = builder.start();
        String result = getStringFromInputStream(p.getInputStream());

        if(result.contains("64"))
            System.out.println("OS Architecture --> is 64 bit");  //The OS Architecture
        else
            System.out.println("OS Architecture --> is 32 bit");

        }


    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }

}

Solution 4

I wanted to share my Java code solution to this (the one alike is a native code).

I would like to add up to Mr James Van Huis's answer; since the property os.arch System.getProperty("os.arch") returns the bitness of JRE, this can actually be very useful. From the article:

In your code, you first need to check the size of IntPtr, if it returns 8 then you are running on a 64-bit OS. If it returns 4, you are running a 32 bit application, so now you need to know whether you are running natively or under WOW64.

Therefore, the IntPtr size check is the same check you perform by looking at the "os.arch". After this you can proceed with figuring out whether the process is running natively or under WOW64.

This can be done using the jna library(e.g. NativeLibrary) which offers use of the native functions you need.

//test the JRE here by checking the os.arch property
//go into the try block if JRE is 32bit
try {
    NativeLibrary kernel32Library = NativeLibrary.getInstance("kernel32");
    Function isWow64Function = kernel32Library.getFunction("IsWow64Process");

    WinNT.HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess();
    IntByReference isWow64 = new IntByReference(0);
    Boolean returnType = false;
    Object[] inArgs = {
        hProcess,
        isWow64
    };
    if ((Boolean) isWow64Function.invoke(returnType.getClass(), inArgs))    {
        if (isWow64.getValue() == 1)    {
                //32bit JRE on x64OS
        }
    }
} catch (UnsatisfiedLinkError e) {  //thrown by getFunction

}

Something like this might also work, but I would recommend the first version, since it's the one I tested on x64 and 32bit JRE on x64 OS. Also it should be the safer way, because in the following you don't actually check whether or not the "IsWow64Process" function exists.

Here I am adding an example of the JRE check, just so it is complete, even though it's not hard to find.

Map<String, Integer> archMap = new HashMap<String, Integer>();
archMap.put("x86", 32);
archMap.put("i386", 32);
archMap.put("i486", 32);
archMap.put("i586", 32);
archMap.put("i686", 32);
archMap.put("x86_64", 64);
archMap.put("amd64", 64);
//archMap.put("powerpc", 3);
this.arch = archMap.get(SystemUtils.OS_ARCH);
if (this.arch == null)  {
    throw new IllegalArgumentException("Unknown architecture " + SystemUtils.OS_ARCH);
}

Solution 5

You can try this code, I thinks it's better to detect the model of JVM

boolean is64bit = System.getProperty("sun.arch.data.model").contains("64");
Share:
58,495
Matt
Author by

Matt

Updated on August 18, 2021

Comments

  • Matt
    Matt over 2 years

    How do you determine 32 or 64 bit architecture of Windows using Java?