如何使用 64 位浏览器和 64 位 java 插件在 64 位 Linux 上获取 32 位 JRE 路径

Posted

技术标签:

【中文标题】如何使用 64 位浏览器和 64 位 java 插件在 64 位 Linux 上获取 32 位 JRE 路径【英文标题】:How to get 32 bit JRE path on 64 bit Linux with 64 bit browser and 64 bit java plugin 【发布时间】:2012-05-19 19:29:30 【问题描述】:

我的应用程序由三个组件组成:

    小程序 Java 程序 (myapp.jar) JNI 库 (myjni.so)

请注意,JNI 库是为 32 位构建的。在 32 位操作系统上,小程序使用 java.home 属性来获取 JRE 路径。一旦小程序获得 JRE 路径,它就会像这样启动 JAR

JRE-path myapp.jar

现在我需要在 64 位 Linux 上运行这个应用程序。这里我有两个选择:

    为 64 位构建 JNI 库。 这是不可能的,因为所有依赖的库都需要为 64 位构建。 (这是我最后的一个约束) 要求用户安装 32 位 JVM 现在的问题是如何获取 32 位 JRE 路径,因为 java.home 属性给出了 64 位 JRE 路径。 (因为浏览器和插件都是 64 位的)。一种选择是使用update-alternatives –list java 命令获取所有JRE 安装路径。然后对每个安装路径运行JRE-path -d32 –version命令查看是否支持32位JVM 如果它支持 32 位 JVM,请使用该 JRE 路径来启动 JAR 文件 如果没有安装的 java 支持 32 位 JVM,则显示安装 32 位 JVM 的消息

问题:

    上述解决方案有问题吗? (我需要在 Ubuntu、Redhat 和 OpenSuse 上使用这个解决方案) 在 64 位 Linux 上获取 32 个 JRE 路径是否有更好的解决方案?

【问题讨论】:

如何将原生库推送给客户端?我想你的小程序是用受信任的证书签名的,对吗? 是的,小程序是用受信任的证书签名的。 Native lib 使用 java 传递机制推送到客户端 【参考方案1】:

使用选项 1。构建 32 位和 64 位 JNI 库并加载相关的 .so(基于 32 位或 64 位 VM)。

您可以为 Sun JDK 使用 sun.arch.data.model 系统属性

您可以将com.ibm.vm.bitmode 用于 IBM websphere VM

或在os.arch 系统属性中查找子字符串64(在基于64 位intel 的VM 上是x86_64/amd64)

由于您无法构建 .so 的 64 位变体以及它所依赖的 .a.so 文件(这实际上是很好的软件配置管理实践),那么下面的 shell 脚本应该是一个很好的努力。如果在调用它结束时脚本以66 退出,则没有有效的 32 位 java

#!/bin/bash -p

# attempt to find a 32bit VM
# uses a dummy class file (it's just an empty file)

trap 'rm -f /tmp/testclass$$.class /tmp/jlocations.$$' EXIT HUP

touch /tmp/testclass$$.class

tryj() 
    while read java; do
        errout=$($java -cp /tmp -d32 testclass$$ 2>&1)
        if grep -q 'java.lang.ClassFormatError' <<<$errout; then
            # good VM - run with this
            rm -f /tmp/testclass$$.class /tmp/jlocations.$$
            # echo $java "$@"
            exec $java "$@"
        fi
    done </tmp/jlocations.$$
    return 1


# try update-alternatives - debian/ubuntu
update-alternatives --list java > /tmp/jlocations.$$ 2>/dev/null

tryj "$@"

# Try alternatives - redhat
alternatives --list java > /tmp/jlocations.$$ 2>/dev/null

tryj "$@"

# then try locate - generic linux/unix
locate java | grep 'bin/java$' > /tmp/jlocations.$$

tryj "$@"

# if we had no luck, then use find - this will be sloooooooooow
find / -wholename '*/bin/java' >/tmp/jlocations.$$ 2>/dev/null
tryj "$@"

exit 66

【讨论】:

无法使用选项 1。这是因为 myjni.so 依赖于其他一些静态和共享库。所以我需要为64位编译so模块。这些模块又是另一组库等。简而言之,我需要为 64 位构建整个堆栈。 那么选项 1 并不是一个真正的选项。在我的 ubuntu 系统上,我什至没有安装 jre 的 32 位变体的选项 - 我必须手动安装它,这意味着它不会出现在 update-alternatives 输出中。我将在答案中添加一个选项,该选项使用 shell 脚本,利用 locate 尝试查找 java 的副本,如果失败则回退到使用 find

以上是关于如何使用 64 位浏览器和 64 位 java 插件在 64 位 Linux 上获取 32 位 JRE 路径的主要内容,如果未能解决你的问题,请参考以下文章

如何强制安装mt65xx preloader win7 64位

如何知道Java虚拟机JVM是64位JVM还是32位? - Break易站

如何查找 java.exe 是 32 位还是 64 位?

求教,WIN7 64位系统下MT65XX preloader驱动安装失败,无法线刷

如何将 Open Office(32 位)与 64 位 Java 运行时环境集成?

如何从 32 位进程启动 64 位进程