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

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

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

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

JRE-path myapp.jar

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

  1. 为 64 位构建 JNI 库。 这是不可能的,因为所有依赖的库都需要为 64 位构建。 (这是我最后的一个约束)
  2. 要求用户安装 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 的消息

问题:

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

【问题讨论】:

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

标签: java linux ubuntu applet 32bit-64bit


【解决方案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
猜你喜欢
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 2014-01-28
  • 2018-03-04
  • 2011-06-20
  • 2014-12-24
  • 2012-10-26
  • 2012-09-17
相关资源
最近更新 更多