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

JavaWindowsX8664 Bit

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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 2 - Java

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 3 - Java

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 - Java

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 - Java

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");

Solution 6 - Java

(Only for Windows) Check if C:\Windows\SysWOW64 exists. if the directory exist, it is a 64 bit process. Else, it is a 32 bit process.

Solution 7 - Java

Maybe it 's not the best way, but it works.

All I do is get the "Enviroment Variable" which windows has configured for Program Files x86 folder. I mean Windows x64 have the folder (Program Files x86) and the x86 does not. Because a user can change the Program Files path in Enviroment Variables, or he/she may make a directory "Program Files (x86)" in C:, I will not use the detection of the folder but the "Enviroment Path" of "Program Files (x86)" with the variable in windows registry.

public class getSystemInfo {

	static void suckOsInfo(){
		
	// Get OS Name (Like: Windows 7, Windows 8, Windows XP, etc.)
	String osVersion = System.getProperty("os.name");
	System.out.print(osVersion);
	
	String pFilesX86 = System.getenv("ProgramFiles(X86)");
	if (pFilesX86 !=(null)){
		// Put here the code to execute when Windows x64 are Detected
	System.out.println(" 64bit");
	}
	else{
		// Put here the code to execute when Windows x32 are Detected
	System.out.println(" 32bit");
	}
	
	System.out.println("Now getSystemInfo class will EXIT");
	System.exit(0);
		
	}
	
}

Solution 8 - Java

You can get the "real" os arch from command line. You can use "wmic cpu get AddressWidth".

enter image description here

If do you want the processor arch, you can use "wmic cpu get DataWidth"

I write a simple java static code to try this.

(Disclaimer: You need use ProcessBuilder if you want reuse this code)

public static String getOsArch() {
    String arch = null;
    try {
        arch = HotUtils.executeCmd("wmic cpu get AddressWidth");
        arch = arch.trim();
        arch = arch.replace("\n\n", "\n");
        arch = arch.replace(" ", "");
        arch = arch.trim();
        return arch.endsWith("64")? "64": "32";
    } catch (IOException ex) {
        Logger.getLogger(HotUtils.class.getName()).log(Level.SEVERE, null, ex);
    }
    return arch;
}

public static void main(String[] args) {
    System.out.println(HotUtils.getOsArch());
}

public static String executeCmd(String cmd) throws IOException {
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(cmd);

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

    StringBuilder out = new StringBuilder();
    String s;
    while ((s = stdInput.readLine()) != null) {
        out.append(s);
    }

    while ((s = stdError.readLine()) != null) {
        out.append(s);
    }
    return out.toString();
}

Solution 9 - Java

System.getProperty("os.arch");

Solution 10 - Java

You can use the os.arch property in system properties to find out.

Properties pr = System.getProperties();
System.out.println(pr.getProperty("os.arch"));

If you are on 32 bit, it should show i386 or something

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatthewView Question on Stackoverflow
Solution 1 - JavaBooleanView Answer on Stackoverflow
Solution 2 - JavaJames Van HuisView Answer on Stackoverflow
Solution 3 - JavaCrusaderpyroView Answer on Stackoverflow
Solution 4 - JavastrudelPiView Answer on Stackoverflow
Solution 5 - Javauser2181778View Answer on Stackoverflow
Solution 6 - JavaOlligaming1107View Answer on Stackoverflow
Solution 7 - JavaBlackgeo32View Answer on Stackoverflow
Solution 8 - JavaCarlos Jesus Arancibia TaborgaView Answer on Stackoverflow
Solution 9 - JavaBozhoView Answer on Stackoverflow
Solution 10 - JavaprasannaView Answer on Stackoverflow