32位JRE和64位JRE中os.arch的所有可能值

37

我需要获取JRE 1.6在Linux、Solaris和Windows系统中,os.arch属性的所有可能值的最新汇编。如果可能的话,请引用您发现的来源。 我需要这些值来选择我的JNLP文件中的资源。基本上,我需要根据JRE是32位还是64位来分配不同的JVM内存。 等待您的回答。 谢谢

3个回答

22

你可以在自己的JDK中寻找这个最佳位置。

查看 java.lang.System,你会看到属性是在initializeSystemClass方法中初始化的,该方法使用initProperties方法,该方法依赖于使用JNI的本机代码:

private static native Properties initProperties(Properties props);

/**
 * Initialize the system class.  Called after thread initialization.
 */
private static void initializeSystemClass() {

    // VM might invoke JNU_NewStringPlatform() to set those encoding
    // sensitive properties (user.home, user.name, boot.class.path, etc.)
    // during "props" initialization, in which it may need access, via
    // System.getProperty(), to the related system encoding property that
    // have been initialized (put into "props") at early stage of the
    // initialization. So make sure the "props" is available at the
    // very beginning of the initialization and all system properties to
    // be put into it directly.
    props = new Properties();
    initProperties(props);  // initialized by the VM
    ...
    ...
}

如果您检查从initProperties调用的此本地代码在不同平台上的源代码,您可以看到os.arch系统属性的可能值。因此,请逐步执行以下操作:

首先查看System.c,以查看从java.lang.System.initProperties调用的JNI方法。从System.c

JNIEXPORT jobject JNICALL
Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
{
    char buf[128];
    java_props_t *sprops = GetJavaProperties(env);
    jmethodID putID = (*env)->GetMethodID(env,
                                          (*env)->GetObjectClass(env, props),
                                          "put",
            "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");

    if (sprops == NULL || putID == NULL ) return NULL;

    PUTPROP(props, "java.specification.version",
            JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
    PUTPROP(props, "java.specification.name",
            "Java Platform API Specification");
    PUTPROP(props, "java.specification.vendor", "Sun Microsystems Inc.");

    PUTPROP(props, "java.version", RELEASE);
    PUTPROP(props, "java.vendor", VENDOR);
    PUTPROP(props, "java.vendor.url", VENDOR_URL);
    PUTPROP(props, "java.vendor.url.bug", VENDOR_URL_BUG);

    ...

    /* os properties */
    PUTPROP(props, "os.name", sprops->os_name);
    PUTPROP(props, "os.version", sprops->os_version);

    // HERE IS THE `os.arch` PROPERTY :)

    PUTPROP(props, "os.arch", sprops->os_arch);

正如您所看到的os.arch来自于PUTPROP(props, "os.arch", sprops->os_arch);,而sprops则是通过java_props_t *sprops = GetJavaProperties(env);实现的。那么让我们看看GetJavaProperties(env),这个方法在java_props.h中定义:

java_props_t *GetJavaProperties(JNIEnv *env);

而实现似乎取决于操作系统。

因此最后看一下GetJavaProperties的具体实现,在Windows中该属性可能的取值为ia64amd64x86unknown。您可以从java_props_md.c文件中看到:

#if _M_IA64
        sprops.os_arch = "ia64";
#elif _M_AMD64
        sprops.os_arch = "amd64";
#elif _X86_
        sprops.os_arch = "x86";
#else
        sprops.os_arch = "unknown";
#endif

对于Solaris而言,似乎更加复杂,因为本地代码中的属性值来自于特定于Solaris的java_props_md.c宏定义,如下所示:

sprops.os_arch = ARCHPROPNAME;

这个宏是在以下Makefile中定义的:

OTHER_CPPFLAGS += -DARCHPROPNAME = '"$(ARCHPROP)"'

因此,看起来这个宏是从编译环境中获取的(抱歉我不是C语言专家,只是猜测,但也许我可以给你一些指导)。

src/linux/native/文件夹中没有java_props_md.c,所以我想在这种情况下应该使用与Solaris相同的源代码(我再次猜测...)。

注意:我使用1.6版本来获取这些值,但是新的Java版本可能会添加新的值,因此请检查您所需的版本。

希望能有所帮助,


1
尽管这不是一个完整的解决方案,但我给了悬赏,因为你努力寻找规范值。注意:由于历史原因,在jdk9之前的Java中,Solaris文件夹包含大部分通用Unix内容,所以是的,该代码适用于Linux。如果该值来自环境,那就不幸了,因为这意味着它的值是开放式的。我希望有一个整洁、规范的可能值表,而无需迷信地包含大量架构同义词,但也许这是不可能的。 - Boann
@Boann 感谢您确认关于Solaris和Linux的问题。起初我查看文档以查看os.arch可能的值,但似乎没有官方信息...然后我直接查看代码;不幸的是,这也没有提供我们正在寻找的信息。无论如何,感谢您的慷慨奖励 :) - albciff

10

2019年我也遇到了同样的问题,尤其是与ARM处理器相关的问题。

在尝试后,树莓派2 (ARMv7) 看起来只是返回字符串 arm

树莓派3 (ARMv8) 返回 aarch64

x86 64位台式机和服务器返回 amd64

希望这能帮助到某些人。


7
你也可以像下面这样编写代码来查找操作系统及其架构。
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.SystemUtils;


public class PlatformDetection {
    private String os;
    private String arch;
    public static String OS_WINDOWS = "windows";
    public static String OS_OSX = "osx";
    public static String OS_SOLARIS = "solaris";
    public static String OS_LINUX = "linux";
    public static String ARCH_PPC = "ppc";
    public static String ARCH_X86_32 = "x86_32";
    public static String ARCH_X86_64 = "x86_64";

    public PlatformDetection() {
        // resolve OS
        if (SystemUtils.IS_OS_WINDOWS) {
            this.os = OS_WINDOWS;
        } else if (SystemUtils.IS_OS_MAC_OSX) {
            this.os = OS_OSX;
        } else if (SystemUtils.IS_OS_SOLARIS) {
            this.os = OS_SOLARIS;
        } else if (SystemUtils.IS_OS_LINUX) {
            this.os = OS_LINUX;
        } else {
            throw new IllegalArgumentException("Unknown operating system " + SystemUtils.OS_NAME);
        }

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

    public String getOs() {
        return os;
    }

    public String getArch() {
        return arch;
    }

    public void setArch(String arch) {
        this.arch = arch;
    }

    public void setOs(String os) {
        this.os = os;
    }

    public String toString() {

        return os + "_" + arch;
    }
}

请参考以下链接。
  1. https://github.com/trustin/os-maven-plugin/blob/master/src/main/java/kr/motd/maven/os/Detector.java

  2. https://github.com/rachelxqy/EligibilityCriteriaModeling/blob/57001f6d86084f074f4ca6aaff157e93ef6abf95/src/main/java/edu/mayo/bmi/medtagger/ml/util/PlatformDetection.java


1
我没有给这个答案设置赏金,因为链接的可靠性不够清晰。它们对于一些相同的架构(例如powerpcppc)检测到不同的os.arch值,而且不清楚它们是否知道这些值可能出现或者这是迷信式的编码。此外,你在这里复制粘贴了其中一个链接,我不知道它的版权状态是什么。 - Boann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接